blob: b90c2df33ef0d36b5e2c016ba9527879c96b2560 [file] [log] [blame]
Jeremy Kerr42dc98c2016-02-25 10:23:14 +08001/******************************************************************************
2* Copyright 2016 Foxconn
3*
4* Licensed under the Apache License, Version 2.0 (the "License");
5* you may not use this file except in compliance with the License.
6* You may obtain a copy of the License at
7*
8* http://www.apache.org/licenses/LICENSE-2.0
9*
10* Unless required by applicable law or agreed to in writing, software
11* distributed under the License is distributed on an "AS IS" BASIS,
12* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13* See the License for the specific language governing permissions and
14* limitations under the License.
15******************************************************************************/
Jeremy Kerr982b7bc2016-02-25 10:54:39 +080016
17#include <stdio.h>
18#include <stdlib.h>
19#include <string.h>
20#include <errno.h>
21#include <time.h>
22#include <unistd.h>
23
24#include <sys/ioctl.h>
25#include <sys/socket.h>
26
27#include <netinet/in.h>
28
29#include <linux/if_packet.h>
30#include <linux/if_ether.h>
31#include <linux/if_arp.h>
32
Jeremy Kerr42dc98c2016-02-25 10:23:14 +080033#define MAX_SERVER_NODE 24
34#define SKU1_MAX_SERVER_NODES 24
35
36#define ETH_ARP_FRAME_LEN ( sizeof(struct ethhdr)+\
37 sizeof(struct arphdr)+\
38 ((ETH_ALEN+4)*2)\
39 )
40
41struct ARP_DATA {
Jeremy Kerrc10bedb2016-02-25 14:26:38 +080042 unsigned char src_mac[ETH_ALEN];
43 unsigned char src_ip[4];
44 unsigned char dest_mac[ETH_ALEN];
45 unsigned char dest_ip[4];
Jeremy Kerr42dc98c2016-02-25 10:23:14 +080046};
47struct ETH_ARP_PACKET {
48 struct ethhdr eh;
49 struct arphdr arp;
50 struct ARP_DATA arp_data;
51};
52
53struct ETH_ARP_PACKET *inarp_req;
54
Jeremy Kerr7b3bcf72016-02-25 14:29:55 +080055static int send_arp_packet(int fd,
Jeremy Kerr5514f7b2016-02-25 12:41:44 +080056 int ifindex,
57 struct ETH_ARP_PACKET *eth_arp,
58 __be16 ar_op,
59 unsigned char *src_mac,
60 unsigned char *src_ip,
61 unsigned char *dest_mac, unsigned char *dest_ip)
Jeremy Kerr42dc98c2016-02-25 10:23:14 +080062{
63 int send_result = 0;
64 struct ethhdr *eh = &eth_arp->eh;
65 struct arphdr *arp = &eth_arp->arp;
66 struct ARP_DATA *arp_data = &eth_arp->arp_data;
Jeremy Kerr42dc98c2016-02-25 10:23:14 +080067 struct sockaddr_ll socket_address;
Jeremy Kerrc10bedb2016-02-25 14:26:38 +080068
69 /* Prepare our link-layer address: raw packet interface,
70 * using the ifindex interface, receiving ARP packets
71 */
Jeremy Kerr5514f7b2016-02-25 12:41:44 +080072 socket_address.sll_family = PF_PACKET;
Jeremy Kerr42dc98c2016-02-25 10:23:14 +080073 socket_address.sll_protocol = htons(ETH_P_ARP);
Jeremy Kerr5514f7b2016-02-25 12:41:44 +080074 socket_address.sll_ifindex = ifindex;
Jeremy Kerr5514f7b2016-02-25 12:41:44 +080075 socket_address.sll_hatype = ARPHRD_ETHER;
Jeremy Kerr5514f7b2016-02-25 12:41:44 +080076 socket_address.sll_pkttype = PACKET_OTHERHOST;
Jeremy Kerr5514f7b2016-02-25 12:41:44 +080077 socket_address.sll_halen = ETH_ALEN;
Jeremy Kerr42dc98c2016-02-25 10:23:14 +080078 memcpy(socket_address.sll_addr, dest_mac, ETH_ALEN);
Jeremy Kerrc10bedb2016-02-25 14:26:38 +080079
80 /* set the frame header */
Jeremy Kerr5514f7b2016-02-25 12:41:44 +080081 memcpy((void *)eh->h_dest, (void *)dest_mac, ETH_ALEN);
82 memcpy((void *)eh->h_source, (void *)src_mac, ETH_ALEN);
Jeremy Kerr42dc98c2016-02-25 10:23:14 +080083 eh->h_proto = htons(ETH_P_ARP);
Jeremy Kerrc10bedb2016-02-25 14:26:38 +080084
85 /* Fill InARP request data for ethernet + ipv4 */
Jeremy Kerr42dc98c2016-02-25 10:23:14 +080086 arp->ar_hrd = htons(ARPHRD_ETHER);
87 arp->ar_pro = htons(ETH_P_ARP);
88 arp->ar_hln = ETH_ALEN;
89 arp->ar_pln = 4;
Jeremy Kerr5514f7b2016-02-25 12:41:44 +080090 arp->ar_op = htons(ar_op);
Jeremy Kerrc10bedb2016-02-25 14:26:38 +080091
92 /* fill arp ethernet mac & ipv4 info */
Jeremy Kerr5514f7b2016-02-25 12:41:44 +080093 arp_data = (void *)(arp + 1);
Jeremy Kerrc10bedb2016-02-25 14:26:38 +080094 memcpy(arp_data->src_mac, (void *)src_mac, ETH_ALEN);
95 memcpy(arp_data->src_ip, src_ip, 4);
96 memcpy(arp_data->dest_mac, (void *)dest_mac, ETH_ALEN);
97 memcpy(arp_data->dest_ip, dest_ip, 4);
98
99 /* send the packet */
Jeremy Kerr5514f7b2016-02-25 12:41:44 +0800100 send_result = sendto(fd, eth_arp, ETH_ARP_FRAME_LEN, 0,
101 (struct sockaddr *)&socket_address,
102 sizeof(socket_address));
Jeremy Kerr42dc98c2016-02-25 10:23:14 +0800103 if (send_result == -1) {
Jeremy Kerr5514f7b2016-02-25 12:41:44 +0800104 printf("sendto: [%s]\n", strerror(errno));
Jeremy Kerr42dc98c2016-02-25 10:23:14 +0800105 }
106 return send_result;
107}
Jeremy Kerr5514f7b2016-02-25 12:41:44 +0800108
Jeremy Kerr7b3bcf72016-02-25 14:29:55 +0800109static void show_mac_addr(const char *name, unsigned char *mac_addr)
Jeremy Kerr42dc98c2016-02-25 10:23:14 +0800110{
111 int i;
112 printf("%s MAC address: ", name);
Jeremy Kerr5514f7b2016-02-25 12:41:44 +0800113 for (i = 0; i < 6; i++) {
114 printf("%.2X%c", (unsigned char)mac_addr[i],
115 (i == 5) ? '\n' : ':');
116 }
Jeremy Kerr42dc98c2016-02-25 10:23:14 +0800117 return;
118}
Jeremy Kerr5514f7b2016-02-25 12:41:44 +0800119
Jeremy Kerr115522d2016-02-25 10:24:14 +0800120static void usage(const char *progname)
121{
122 fprintf(stderr, "Usage: %s <interface>\n", progname);
123}
124
125int main(int argc, char **argv)
Jeremy Kerr42dc98c2016-02-25 10:23:14 +0800126{
127 int fd, ret;
Jeremy Kerr5514f7b2016-02-25 12:41:44 +0800128 /*buffer for ethernet frame */
Jeremy Kerrc10bedb2016-02-25 14:26:38 +0800129 static unsigned char buffer[ETH_FRAME_LEN];
Jeremy Kerr42dc98c2016-02-25 10:23:14 +0800130 int send_result = 0;
Jeremy Kerr5514f7b2016-02-25 12:41:44 +0800131 static struct ifreq ifreq_buffer;
Jeremy Kerr115522d2016-02-25 10:24:14 +0800132 const char *ifname;
133
134 if (argc < 2) {
135 usage(argv[0]);
136 return EXIT_FAILURE;
137 }
138
139 ifname = argv[1];
140
141 if (strlen(ifname) > IFNAMSIZ) {
142 fprintf(stderr, "Interface name '%s' is invalid\n", ifname);
143 return EXIT_FAILURE;
144 }
Jeremy Kerr5514f7b2016-02-25 12:41:44 +0800145
Jeremy Kerr42dc98c2016-02-25 10:23:14 +0800146 static unsigned char src_mac[6];
147 static unsigned char src_ip[4];
148 int ifindex;
Jeremy Kerr42dc98c2016-02-25 10:23:14 +0800149
Jeremy Kerr5514f7b2016-02-25 12:41:44 +0800150 if (((fd = socket(AF_PACKET, SOCK_PACKET, htons(ETH_P_ARP)))) == -1) {
Jeremy Kerr5514f7b2016-02-25 12:41:44 +0800151 printf("socket: [%s]\n", strerror(errno));
Jeremy Kerr42dc98c2016-02-25 10:23:14 +0800152 exit(-1);
153 }
Jeremy Kerrc10bedb2016-02-25 14:26:38 +0800154
155 /* Query local mac address */
Jeremy Kerr42dc98c2016-02-25 10:23:14 +0800156 memset(&ifreq_buffer, 0x00, sizeof(ifreq_buffer));
Jeremy Kerr115522d2016-02-25 10:24:14 +0800157 strcpy(ifreq_buffer.ifr_name, ifname);
Jeremy Kerr42dc98c2016-02-25 10:23:14 +0800158 ret = ioctl(fd, SIOCGIFHWADDR, &ifreq_buffer);
159 if (ret == -1) {
Jeremy Kerr5514f7b2016-02-25 12:41:44 +0800160 printf("ioctl2: [%s]\n", strerror(errno));
Jeremy Kerr42dc98c2016-02-25 10:23:14 +0800161 close(fd);
162 exit(-1);
163 }
164 memcpy(src_mac, ifreq_buffer.ifr_hwaddr.sa_data, ETH_ALEN);
Jeremy Kerr115522d2016-02-25 10:24:14 +0800165 show_mac_addr(ifname, src_mac);
Jeremy Kerrc10bedb2016-02-25 14:26:38 +0800166
167 /* find the ifindex of the interface we're using */
Jeremy Kerr42dc98c2016-02-25 10:23:14 +0800168 memset(&ifreq_buffer, 0x00, sizeof(ifreq_buffer));
Jeremy Kerr115522d2016-02-25 10:24:14 +0800169 strcpy(ifreq_buffer.ifr_name, ifname);
Jeremy Kerr42dc98c2016-02-25 10:23:14 +0800170 ret = ioctl(fd, SIOCGIFINDEX, &ifreq_buffer);
171 if (ret == -1) {
Jeremy Kerr5514f7b2016-02-25 12:41:44 +0800172 printf("ioctl4: [%s]\n", strerror(errno));
Jeremy Kerr42dc98c2016-02-25 10:23:14 +0800173 close(fd);
174 exit(-1);
175 }
176 ifindex = ifreq_buffer.ifr_ifindex;
177
Jeremy Kerrc10bedb2016-02-25 14:26:38 +0800178 /* length of the received frame */
179 int length = 0;
180 static struct ETH_ARP_PACKET *inarp_req =
181 (struct ETH_ARP_PACKET *)buffer;
182 static struct ETH_ARP_PACKET inarp_resp;
183
Jeremy Kerr42dc98c2016-02-25 10:23:14 +0800184 while (1) {
Jeremy Kerrc10bedb2016-02-25 14:26:38 +0800185 /* get local ip address */
Jeremy Kerr42dc98c2016-02-25 10:23:14 +0800186 memset(&ifreq_buffer, 0x00, sizeof(ifreq_buffer));
Jeremy Kerr115522d2016-02-25 10:24:14 +0800187 strcpy(ifreq_buffer.ifr_name, ifname);
Jeremy Kerr42dc98c2016-02-25 10:23:14 +0800188 ret = ioctl(fd, SIOCGIFADDR, &ifreq_buffer);
189 if (ret == -1) {
Jeremy Kerr5514f7b2016-02-25 12:41:44 +0800190 sleep(1);
191 continue;
Jeremy Kerr42dc98c2016-02-25 10:23:14 +0800192 }
193
Jeremy Kerr5514f7b2016-02-25 12:41:44 +0800194 if (AF_INET == ifreq_buffer.ifr_addr.sa_family) {
Jeremy Kerr42dc98c2016-02-25 10:23:14 +0800195 memcpy(src_ip, &ifreq_buffer.ifr_addr.sa_data[2], 4);
Jeremy Kerr42dc98c2016-02-25 10:23:14 +0800196 } else {
Jeremy Kerr5514f7b2016-02-25 12:41:44 +0800197 printf("unknown address family [%d]!\n",
198 ifreq_buffer.ifr_addr.sa_family);
199 sleep(1);
200 continue;
Jeremy Kerr42dc98c2016-02-25 10:23:14 +0800201 }
202
Jeremy Kerr5514f7b2016-02-25 12:41:44 +0800203 memset((void *)&inarp_resp, 0, sizeof inarp_resp);
Jeremy Kerr42dc98c2016-02-25 10:23:14 +0800204 length = recvfrom(fd, buffer, ETH_ARP_FRAME_LEN, 0, NULL, NULL);
205 if (length == -1) {
206 sleep(1);
207 }
Jeremy Kerr42dc98c2016-02-25 10:23:14 +0800208 if (0 == memcmp(src_mac, inarp_req->eh.h_dest, ETH_ALEN)) {
Jeremy Kerrc10bedb2016-02-25 14:26:38 +0800209 if (ntohs(inarp_req->arp.ar_op) == ARPOP_InREQUEST) {
Jeremy Kerr5514f7b2016-02-25 12:41:44 +0800210
211 printf
212 ("src mac =%02x:%02x:%02x:%02x:%02x:%02x\r\n",
213 inarp_req->arp_data.src_mac[0],
214 inarp_req->arp_data.src_mac[1],
215 inarp_req->arp_data.src_mac[2],
216 inarp_req->arp_data.src_mac[3],
217 inarp_req->arp_data.src_mac[4],
218 inarp_req->arp_data.src_mac[5]
219 );
Jeremy Kerr42dc98c2016-02-25 10:23:14 +0800220 printf("src ip =%d:%d:%d:%d\r\n",
Jeremy Kerr5514f7b2016-02-25 12:41:44 +0800221 inarp_req->arp_data.src_ip[0],
222 inarp_req->arp_data.src_ip[1],
223 inarp_req->arp_data.src_ip[2],
224 inarp_req->arp_data.src_ip[3]
225 );
Jeremy Kerr42dc98c2016-02-25 10:23:14 +0800226 int fd_1;
Jeremy Kerr5514f7b2016-02-25 12:41:44 +0800227 if (((fd_1 =
228 socket(AF_PACKET, SOCK_RAW, 0))) == -1) {
229 printf("socket: [%s]\n",
230 strerror(errno));
Jeremy Kerr42dc98c2016-02-25 10:23:14 +0800231 exit(-1);
232 }
Jeremy Kerr5514f7b2016-02-25 12:41:44 +0800233 send_result =
234 send_arp_packet(fd_1, ifindex, &inarp_resp,
235 ARPOP_InREPLY,
236 inarp_req->arp_data.
237 dest_mac, src_ip,
238 inarp_req->arp_data.src_mac,
239 inarp_req->arp_data.src_ip);
Jeremy Kerr42dc98c2016-02-25 10:23:14 +0800240 close(fd_1);
241 if (send_result == -1) {
Jeremy Kerr5514f7b2016-02-25 12:41:44 +0800242 printf("[Rsp] sendto: [%s]\n",
243 strerror(errno));
244 sleep(1);
245 continue;
Jeremy Kerr42dc98c2016-02-25 10:23:14 +0800246 }
247 }
Jeremy Kerr5514f7b2016-02-25 12:41:44 +0800248 memset(buffer, 0, sizeof(buffer));
Jeremy Kerr42dc98c2016-02-25 10:23:14 +0800249 }
250 }
251 close(fd);
252 return 0;
253}