5 #include <net/ethernet.h>
6 #include <net/if_arp.h>
7 #include <linux/if_packet.h>
8 #include <linux/rtnetlink.h>
9 #include <netinet/ip6.h>
14 /* Most of this code is based on keepalived:vrrp_arp.c */
17 struct ether_header eth
;
20 /* Data bit - variably sized, so not present in |struct arphdr| */
21 unsigned char ar_sha
[ETH_ALEN
]; /* Sender hardware address */
22 in_addr_t ar_sip
; /* Sender IP address. */
23 unsigned char ar_tha
[ETH_ALEN
]; /* Target hardware address */
24 in_addr_t ar_tip
; /* Target ip */
25 } __attribute__((packed
));
27 void sendarp(int ifr_idx
, const unsigned char* mac
, in_addr_t ip
)
30 struct sockaddr_ll sll
;
37 memset(buf
.eth
.ether_dhost
, 0xFF, ETH_ALEN
);
38 memcpy(buf
.eth
.ether_shost
, mac
, ETH_ALEN
);
39 buf
.eth
.ether_type
= htons(ETHERTYPE_ARP
);
42 buf
.arp
.ar_hrd
= htons(ARPHRD_ETHER
);
43 buf
.arp
.ar_pro
= htons(ETHERTYPE_IP
);
44 buf
.arp
.ar_hln
= ETH_ALEN
;
45 buf
.arp
.ar_pln
= 4; //IPPROTO_ADDR_LEN;
46 buf
.arp
.ar_op
= htons(ARPOP_REQUEST
);
49 memcpy(buf
.ar_sha
, mac
, ETH_ALEN
);
50 memcpy(&buf
.ar_sip
, &ip
, sizeof(ip
));
51 memcpy(buf
.ar_tha
, mac
, ETH_ALEN
);
52 memcpy(&buf
.ar_tip
, &ip
, sizeof(ip
));
54 /* Now actually send the thing */
55 fd
= socket(PF_PACKET
, SOCK_RAW
, htons(ETH_P_RARP
));
57 memset(&sll
, 0, sizeof(sll
));
58 sll
.sll_family
= AF_PACKET
;
59 memcpy(sll
.sll_addr
, mac
, sizeof(sll
.sll_addr
) - 1);
60 sll
.sll_halen
= ETH_ALEN
;
61 sll
.sll_ifindex
= ifr_idx
;
63 sendto(fd
, &buf
, sizeof(buf
), 0, (struct sockaddr
*)&sll
, sizeof(sll
));