3 char const *cvs_id_arp
= "$Id: arp.c,v 1.7 2005/07/31 10:04:09 bodea Exp $";
7 #include <net/ethernet.h>
8 #include <net/if_arp.h>
9 #include <linux/if_packet.h>
13 /* Most of this code is based on keepalived:vrrp_arp.c */
16 struct ether_header eth
;
19 /* Data bit - variably sized, so not present in |struct arphdr| */
20 unsigned char ar_sha
[ETH_ALEN
]; /* Sender hardware address */
21 in_addr_t ar_sip
; /* Sender IP address. */
22 unsigned char ar_tha
[ETH_ALEN
]; /* Target hardware address */
23 in_addr_t ar_tip
; /* Target ip */
24 } __attribute__((packed
));
26 void sendarp(int ifr_idx
, const unsigned char* mac
, in_addr_t ip
)
29 struct sockaddr_ll sll
;
36 memset(buf
.eth
.ether_dhost
, 0xFF, ETH_ALEN
);
37 memcpy(buf
.eth
.ether_shost
, mac
, ETH_ALEN
);
38 buf
.eth
.ether_type
= htons(ETHERTYPE_ARP
);
41 buf
.arp
.ar_hrd
= htons(ARPHRD_ETHER
);
42 buf
.arp
.ar_pro
= htons(ETHERTYPE_IP
);
43 buf
.arp
.ar_hln
= ETH_ALEN
;
44 buf
.arp
.ar_pln
= 4; //IPPROTO_ADDR_LEN;
45 buf
.arp
.ar_op
= htons(ARPOP_REQUEST
);
48 memcpy(buf
.ar_sha
, mac
, ETH_ALEN
);
49 memcpy(&buf
.ar_sip
, &ip
, sizeof(ip
));
50 memcpy(buf
.ar_tha
, mac
, ETH_ALEN
);
51 memcpy(&buf
.ar_tip
, &ip
, sizeof(ip
));
53 /* Now actually send the thing */
54 fd
= socket(PF_PACKET
, SOCK_RAW
, htons(ETH_P_RARP
));
56 memset(&sll
, 0, sizeof(sll
));
57 sll
.sll_family
= AF_PACKET
;
58 memcpy(sll
.sll_addr
, mac
, sizeof(sll
.sll_addr
) - 1);
59 sll
.sll_halen
= ETH_ALEN
;
60 sll
.sll_ifindex
= ifr_idx
;
62 sendto(fd
, &buf
, sizeof(buf
), 0, (struct sockaddr
*)&sll
, sizeof(sll
));