2 * Warning : this program need to be link against libsupport.a
4 * This program need also wireless extensions...
7 #include <sys/socket.h>
9 #include <linux/netdevice.h>
11 #include <linux/if_arp.h>
12 #include <linux/if_ether.h>
13 #include <linux/ipx.h>
14 #include <linux/wireless.h>
24 int skfd = -1; /* generic raw socket desc. */
25 int ipx_sock = -1; /* IPX socket */
26 int ax25_sock = -1; /* AX.25 socket */
27 int inet_sock = -1; /* INET socket */
28 int ddp_sock = -1; /* Appletalk DDP socket */
30 static int sockets_open()
32 inet_sock=socket(AF_INET, SOCK_DGRAM, 0);
33 ipx_sock=socket(AF_IPX, SOCK_DGRAM, 0);
34 ax25_sock=socket(AF_AX25, SOCK_DGRAM, 0);
35 ddp_sock=socket(AF_APPLETALK, SOCK_DGRAM, 0);
37 * Now pick any (exisiting) useful socket family for generic queries
46 * If this is -1 we have no known network layers and its time to jump.
60 char * ifname = argv[1];
65 /* Create a channel to the NET kernel. */
66 if((skfd = sockets_open()) < 0)
72 /* Get the type of interface address */
73 strcpy(ifr.ifr_name, ifname);
74 if((ioctl(inet_sock, SIOCGIFADDR, &ifr) < 0) ||
75 ((ap = get_afntype(ifr.ifr_addr.sa_family)) == NULL))
78 fprintf(stderr, "Interface %s unavailable\n", ifname);
83 printf("Interface : %d - %s - %s\n", ifr.ifr_addr.sa_family,
84 ap->name, ap->sprint(&ifr.ifr_addr, 1));
87 /* Get the type of hardware address */
88 strcpy(ifr.ifr_name, ifname);
89 if((ioctl(skfd, SIOCGIFHWADDR, &ifr) < 0) ||
90 ((hw = get_hwntype(ifr.ifr_hwaddr.sa_family)) == NULL))
93 fprintf(stderr, "Unable to get hardware address of the interface %s\n",
99 printf("Hardware : %d - %s - %s\n", ifr.ifr_hwaddr.sa_family,
100 hw->name, hw->print(ifr.ifr_hwaddr.sa_data));
103 /* Is there any arguments ? */
105 { /* Nope : read out from kernel */
106 char buffer[(sizeof(struct iw_quality) +
107 sizeof(struct sockaddr)) * IW_MAX_SPY];
108 struct sockaddr * hwa;
109 struct iw_quality *qual;
113 strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
114 wrq.u.data.pointer = (caddr_t) buffer;
115 wrq.u.data.length = 0;
116 wrq.u.data.flags = 0;
117 if(ioctl(skfd, SIOCGIWSPY, &wrq) < 0)
119 fprintf(stderr, "Interface doesn't accept reading addresses...\n");
120 fprintf(stderr, "SIOCGIWSPY: %s\n", strerror(errno));
124 n = wrq.u.data.length;
126 hwa = (struct sockaddr *) buffer;
127 qual = (struct iw_quality *) (buffer + (sizeof(struct sockaddr) * n));
129 for(i = 0; i < n; i++)
130 printf("%s : Quality %d ; Signal %d ; Noise %d %s\n",
131 hw->print(hwa[i].sa_data),
132 qual[i].qual, qual[i].level, qual[i].noise,
133 qual[i].updated & 0x7 ? "(updated)" : "");
136 { /* Send addresses to kernel */
138 int nbr; /* Number of valid addresses */
139 struct sockaddr hw_address[IW_MAX_SPY];
140 struct sockaddr if_address;
141 struct arpreq arp_query;
143 /* Read command line */
144 i = 2; /* first arg to read */
145 nbr = 0; /* Number of args readen so far */
147 /* "off" : disable functionality (set 0 addresses) */
148 if(!strcmp(argv[2], "off"))
151 /* "+" : add all addresses already in the driver */
152 if(!strcmp(argv[2], "+"))
154 char buffer[(sizeof(struct iw_quality) +
155 sizeof(struct sockaddr)) * IW_MAX_SPY];
157 strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
158 wrq.u.data.pointer = (caddr_t) buffer;
159 wrq.u.data.length = 0;
160 wrq.u.data.flags = 0;
161 if(ioctl(skfd, SIOCGIWSPY, &wrq) < 0)
163 fprintf(stderr, "Interface doesn't accept reading addresses...\n");
164 fprintf(stderr, "SIOCGIWSPY: %s\n", strerror(errno));
168 /* Copy old addresses */
169 nbr = wrq.u.data.length;
170 memcpy(hw_address, buffer, nbr * sizeof(struct sockaddr));
172 i = 3; /* skip the "+" */
175 /* Read other args on command line */
176 while((i < argc) && (nbr < IW_MAX_SPY))
178 /* If it is not a hardware address (prefixed by hw)... */
179 if(strcmp(argv[i], "hw"))
181 /* Read interface address */
182 if(ap->input(argv[i++], &if_address) < 0)
184 fprintf(stderr, "Invalid interface address %s\n", argv[i - 1]);
188 /* Translate IP addresses to MAC addresses */
189 memcpy((char *) &(arp_query.arp_pa),
190 (char *) &if_address,
191 sizeof(struct sockaddr));
192 arp_query.arp_ha.sa_family = 0;
193 arp_query.arp_flags = 0;
194 /* The following restrict the search to the interface only */
195 strcpy(arp_query.arp_dev, ifname);
196 if((ioctl(inet_sock, SIOCGARP, &arp_query) < 0) ||
197 !(arp_query.arp_flags & ATF_COM))
199 fprintf(stderr, "Arp failed for %s... (%d) Try to ping the address before.\n",
200 ap->sprint(&if_address, 1), errno);
204 /* Store new MAC address */
205 memcpy((char *) &(hw_address[nbr++]),
206 (char *) &(arp_query.arp_ha),
207 sizeof(struct sockaddr));
210 printf("IP Address %s => Hw Address = %s - %d\n",
211 ap->sprint(&if_address, 1),
212 hw->print(hw_address[nbr - 1].sa_data));
215 else /* If it's an hardware address */
219 fprintf(stderr, "hw must be followed by an address...\n");
223 /* Get the hardware address */
224 if(hw->input(argv[i++], &(hw_address[nbr])) < 0)
226 fprintf(stderr, "Invalid hardware address %s\n", argv[i - 1]);
232 printf("Hw Address = %s - %d\n",
233 hw->print(hw_address[nbr - 1].sa_data));
236 } /* Loop on all addresses */
239 /* Check the number of addresses */
240 if((nbr == 0) && strcmp(argv[2], "off"))
242 fprintf(stderr, "No valid addresses found : exiting...\n");
246 /* Check if there is some remaining arguments */
249 fprintf(stderr, "Got only the first %d addresses, remaining discarded\n", IW_MAX_SPY);
252 /* Time to do send addresses to the driver */
253 strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
254 wrq.u.data.pointer = (caddr_t) hw_address;
255 wrq.u.data.length = nbr;
256 wrq.u.data.flags = 0;
257 if(ioctl(skfd, SIOCSIWSPY, &wrq) < 0)
259 fprintf(stderr, "Interface doesn't accept addresses...\n");
260 fprintf(stderr, "SIOCSIWSPY: %s\n", strerror(errno));
265 /* Close the socket. */