arp.c (32671) | arp.c (32721) |
---|---|
1/* 2 * sys-bsd.c - System-dependent procedures for setting up 3 * PPP interfaces on bsd-4.4-ish systems (including 386BSD, NetBSD, etc.) 4 * 5 * Copyright (c) 1989 Carnegie Mellon University. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms are permitted 9 * provided that the above copyright notice and this paragraph are 10 * duplicated in all such forms and that any documentation, 11 * advertising materials, and other materials related to such 12 * distribution and use acknowledge that the software was developed 13 * by Carnegie Mellon University. The name of the 14 * University may not be used to endorse or promote products derived 15 * from this software without specific prior written permission. 16 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 17 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 18 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 19 * | 1/* 2 * sys-bsd.c - System-dependent procedures for setting up 3 * PPP interfaces on bsd-4.4-ish systems (including 386BSD, NetBSD, etc.) 4 * 5 * Copyright (c) 1989 Carnegie Mellon University. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms are permitted 9 * provided that the above copyright notice and this paragraph are 10 * duplicated in all such forms and that any documentation, 11 * advertising materials, and other materials related to such 12 * distribution and use acknowledge that the software was developed 13 * by Carnegie Mellon University. The name of the 14 * University may not be used to endorse or promote products derived 15 * from this software without specific prior written permission. 16 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 17 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 18 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 19 * |
20 * $Id: arp.c,v 1.23 1998/01/19 22:34:20 brian Exp $ | 20 * $Id: arp.c,v 1.24 1998/01/21 12:52:14 brian Exp $ |
21 * 22 */ 23 24/* 25 * TODO: 26 */ 27 28#include <sys/param.h> 29#include <sys/time.h> 30#include <sys/socket.h> 31#include <net/if.h> 32#include <net/route.h> 33#include <net/if_dl.h> 34#include <netinet/in.h> 35#include <net/if_types.h> 36#include <netinet/if_ether.h> | 21 * 22 */ 23 24/* 25 * TODO: 26 */ 27 28#include <sys/param.h> 29#include <sys/time.h> 30#include <sys/socket.h> 31#include <net/if.h> 32#include <net/route.h> 33#include <net/if_dl.h> 34#include <netinet/in.h> 35#include <net/if_types.h> 36#include <netinet/if_ether.h> |
37#include <arpa/inet.h> |
|
37 38#include <fcntl.h> 39#include <stdio.h> 40#include <stdlib.h> 41#include <string.h> 42#include <sys/errno.h> 43#include <sys/ioctl.h> 44#include <sys/sysctl.h> --- 15 unchanged lines hidden (view full) --- 60 * cp ${.CURDIR}/arp.c arp-test.c 61 * echo 'const char *' >>arp-test.c 62 * awk '/^Index2Nam/,/^}/' ${.CURDIR}/route.c >>arp-test.c 63 * cc -I${.CURDIR} -DDEBUG arp-test.c -o arp-test 64 * 65 * and type ``make arp-test''. 66 * 67 */ | 38 39#include <fcntl.h> 40#include <stdio.h> 41#include <stdlib.h> 42#include <string.h> 43#include <sys/errno.h> 44#include <sys/ioctl.h> 45#include <sys/sysctl.h> --- 15 unchanged lines hidden (view full) --- 61 * cp ${.CURDIR}/arp.c arp-test.c 62 * echo 'const char *' >>arp-test.c 63 * awk '/^Index2Nam/,/^}/' ${.CURDIR}/route.c >>arp-test.c 64 * cc -I${.CURDIR} -DDEBUG arp-test.c -o arp-test 65 * 66 * and type ``make arp-test''. 67 * 68 */ |
68#define LogIsKept(x) 0 | 69#define LogIsKept(x) 1 |
69#define LogPrintf fprintf 70#undef LogDEBUG 71#define LogDEBUG stderr 72#undef LogERROR 73#define LogERROR stderr 74#undef LogPHASE 75#define LogPHASE stdout 76#define ID0socket socket --- 158 unchanged lines hidden (view full) --- 235 236#endif /* RTM_VERSION */ 237 238 239/* 240 * get_ether_addr - get the hardware address of an interface on the 241 * the same subnet as ipaddr. 242 */ | 70#define LogPrintf fprintf 71#undef LogDEBUG 72#define LogDEBUG stderr 73#undef LogERROR 74#define LogERROR stderr 75#undef LogPHASE 76#define LogPHASE stdout 77#define ID0socket socket --- 158 unchanged lines hidden (view full) --- 236 237#endif /* RTM_VERSION */ 238 239 240/* 241 * get_ether_addr - get the hardware address of an interface on the 242 * the same subnet as ipaddr. 243 */ |
243#define MAX_IFS 32 | |
244 245static int 246get_ether_addr(int s, struct in_addr ipaddr, struct sockaddr_dl *hwaddr) 247{ | 244 245static int 246get_ether_addr(int s, struct in_addr ipaddr, struct sockaddr_dl *hwaddr) 247{ |
248 int idx; 249 const char *got; 250 char *sp, *ep, *cp, *wp; 251 struct ifreq ifrq; 252 struct in_addr addr, mask; 253 struct rt_msghdr *rtm; 254 struct sockaddr *sa_dst, *sa_gw; 255 struct sockaddr_dl *dl; | 248 int mib[6], sa_len, skip, b; |
256 size_t needed; | 249 size_t needed; |
257 int mib[6]; | 250 char *buf, *ptr, *end; 251 struct if_msghdr *ifm; 252 struct ifa_msghdr *ifam; 253 struct sockaddr *sa; 254 struct sockaddr_dl *dl; 255 struct sockaddr_in *ifa, *mask; |
258 | 256 |
259 idx = 1; 260 while (strcmp(got = Index2Nam(idx), "???")) { 261 strncpy(ifrq.ifr_name, got, sizeof ifrq.ifr_name - 1); 262 ifrq.ifr_name[sizeof ifrq.ifr_name - 1] = '\0'; 263 if (ID0ioctl(s, SIOCGIFADDR, &ifrq) == 0 && 264 ifrq.ifr_addr.sa_family == AF_INET) { 265 addr = ((struct sockaddr_in *)&ifrq.ifr_addr)->sin_addr; 266 if (ID0ioctl(s, SIOCGIFNETMASK, &ifrq) == 0) { 267 mask = ((struct sockaddr_in *)&ifrq.ifr_broadaddr)->sin_addr; 268 if ((ipaddr.s_addr & mask.s_addr) == (addr.s_addr & mask.s_addr)) 269 break; 270 } 271 } 272 idx++; 273 } 274 275 if (!strcmp(got, "???")) 276 return 0; 277 278 LogPrintf(LogPHASE, "Found interface %s for proxy arp\n", got); 279 | |
280 mib[0] = CTL_NET; 281 mib[1] = PF_ROUTE; 282 mib[2] = 0; 283 mib[3] = 0; | 257 mib[0] = CTL_NET; 258 mib[1] = PF_ROUTE; 259 mib[2] = 0; 260 mib[3] = 0; |
284 mib[4] = NET_RT_DUMP; | 261 mib[4] = NET_RT_IFLIST; |
285 mib[5] = 0; | 262 mib[5] = 0; |
263 |
|
286 if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0) { | 264 if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0) { |
287 LogPrintf(LogERROR, "get_ether_addr: sysctl: estimate: %s\n", 288 strerror(errno)); | 265 LogPrintf(LogERROR, "Index2Nam: sysctl: estimate: %s\n", strerror(errno)); |
289 return 0; 290 } | 266 return 0; 267 } |
291 if (needed < 0) | 268 269 if ((buf = malloc(needed)) == NULL) |
292 return 0; | 270 return 0; |
293 if ((sp = malloc(needed)) == NULL) | 271 272 if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0) { 273 free(buf); |
294 return 0; | 274 return 0; |
295 if (sysctl(mib, 6, sp, &needed, NULL, 0) < 0) { 296 LogPrintf(LogERROR, "ShowRoute: sysctl: getroute: %s\n", strerror(errno)); 297 free(sp); 298 return (1); | |
299 } | 275 } |
300 ep = sp + needed; | 276 end = buf + needed; |
301 | 277 |
302 for (cp = sp; cp < ep; cp += rtm->rtm_msglen) { 303 rtm = (struct rt_msghdr *) cp; 304 if (rtm->rtm_index == idx) { 305 wp = (char *)(rtm+1); 306 307 if (rtm->rtm_addrs & RTA_DST) { 308 sa_dst = (struct sockaddr *)wp; 309 wp += sa_dst->sa_len; 310 } else 311 sa_dst = NULL; 312 313 if (rtm->rtm_addrs & RTA_GATEWAY) { 314 sa_gw = (struct sockaddr *)wp; 315 if (sa_gw->sa_family == AF_LINK) { 316 dl = (struct sockaddr_dl *)wp; 317 if (!dl->sdl_nlen && !dl->sdl_alen && !dl->sdl_slen) { 318 memcpy(hwaddr, dl, dl->sdl_len); 319 free(sp); 320 return 1; 321 } | 278 ptr = buf; 279 while (ptr < end) { 280 ifm = (struct if_msghdr *)ptr; /* On if_msghdr */ 281 if (ifm->ifm_type != RTM_IFINFO) 282 break; 283 dl = (struct sockaddr_dl *)(ifm + 1); /* Single _dl at end */ 284 skip = (ifm->ifm_flags & (IFF_UP | IFF_BROADCAST | IFF_POINTOPOINT | 285 IFF_NOARP | IFF_LOOPBACK)) != (IFF_UP | IFF_BROADCAST); 286 ptr += ifm->ifm_msglen; /* First ifa_msghdr */ 287 while (ptr < end) { 288 ifam = (struct ifa_msghdr *)ptr; /* Next ifa_msghdr (alias) */ 289 if (ifam->ifam_type != RTM_NEWADDR) /* finished ? */ 290 break; 291 sa = (struct sockaddr *)(ifam+1); /* pile of sa's at end */ 292 ptr += ifam->ifam_msglen; 293 if (skip || (ifam->ifam_addrs & (RTA_NETMASK|RTA_IFA)) != 294 (RTA_NETMASK|RTA_IFA)) 295 continue; 296 /* Found a candidate. Do the addresses match ? */ 297 if (LogIsKept(LogDEBUG) && 298 ptr == (char *)ifm + ifm->ifm_msglen + ifam->ifam_msglen) 299 LogPrintf(LogDEBUG, "%.*s interface is a candidate for proxy\n", 300 dl->sdl_nlen, dl->sdl_data); 301 b = 1; 302 while (b < (RTA_NETMASK|RTA_IFA) && sa < (struct sockaddr *)ptr) { 303 switch (b) { 304 case RTA_IFA: 305 ifa = (struct sockaddr_in *)sa; 306 break; 307 case RTA_NETMASK: 308 /* 309 * Careful here ! this sockaddr doesn't have sa_family set to 310 * AF_INET, and is only 8 bytes big ! I have no idea why ! 311 */ 312 mask = (struct sockaddr_in *)sa; 313 break; |
322 } | 314 } |
315 if (ifam->ifam_addrs & b) { 316#define ALN sizeof(ifa->sin_addr.s_addr) 317 sa_len = sa->sa_len > 0 ? ((sa->sa_len-1)|(ALN-1))+1 : ALN; 318 sa = (struct sockaddr *)((char *)sa + sa_len); 319 } 320 b <<= 1; |
|
323 } | 321 } |
322 if (LogIsKept(LogDEBUG)) { 323 char a[16]; 324 strncpy(a, inet_ntoa(mask->sin_addr), sizeof a - 1); 325 a[sizeof a - 1] = '\0'; 326 LogPrintf(LogDEBUG, "Check addr %s, mask %s\n", 327 inet_ntoa(ifa->sin_addr), a); 328 } 329 if (ifa->sin_family == AF_INET && 330 (ifa->sin_addr.s_addr & mask->sin_addr.s_addr) == 331 (ipaddr.s_addr & mask->sin_addr.s_addr)) { 332 LogPrintf(LogPHASE, "Found interface %.*s for proxy arp\n", 333 dl->sdl_alen, dl->sdl_data); 334 memcpy(hwaddr, dl, dl->sdl_len); 335 free(buf); 336 return 1; 337 } |
|
324 } 325 } | 338 } 339 } |
326 free(sp); | 340 free(buf); 341 |
327 return 0; 328} 329 330#ifdef DEBUG 331int 332main(int argc, char **argv) 333{ 334 struct in_addr ipaddr; 335 int s, f; 336 337 s = socket(AF_INET, SOCK_DGRAM, 0); 338 for (f = 1; f < argc; f++) { 339 if (inet_aton(argv[f], &ipaddr)) 340 sifproxyarp(s, ipaddr); 341 } 342 close(s); 343} 344#endif | 342 return 0; 343} 344 345#ifdef DEBUG 346int 347main(int argc, char **argv) 348{ 349 struct in_addr ipaddr; 350 int s, f; 351 352 s = socket(AF_INET, SOCK_DGRAM, 0); 353 for (f = 1; f < argc; f++) { 354 if (inet_aton(argv[f], &ipaddr)) 355 sifproxyarp(s, ipaddr); 356 } 357 close(s); 358} 359#endif |