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