Changeset 1565 for trunk/src/common/sendpacket.c
- Timestamp:
- 08/02/06 21:22:14 (2 years ago)
- Files:
-
- 1 modified
-
trunk/src/common/sendpacket.c (modified) (12 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/common/sendpacket.c
r1564 r1565 4 4 * Copyright (c) 2006 Aaron Turner. 5 5 * Copyright (c) 1998 - 2004 Mike D. Schiffman <mike@infonexus.com> 6 * Copyright (c) 2000 Torsten Landschoff <torsten@debian.org> 7 * Sebastian Krahmer <krahmer@cs.uni-potsdam.de> 6 8 * Copyright (c) 1993, 1994, 1995, 1996, 1998 7 9 * The Regents of the University of California. … … 85 87 86 88 #if defined HAVE_PF_PACKET 87 /* older versions of glibc require different headers */ 88 #if __GLIBC__ >= 2 && __GLIBC_MINOR >= 1 89 #include <fcntl.h> 90 #include <sys/socket.h> 91 #include <sys/utsname.h> 92 #include <net/if.h> 93 #include <netinet/in.h> 94 #include <linux/if_ether.h> 95 #include <net/if_arp.h> 89 96 #include <netpacket/packet.h> 90 #include <net/ethernet.h> 91 #else 92 #include <sys/socket.h> 93 #include <netpacket/packet.h> 94 #include <net/ethernet.h> 95 #endif 96 #include <net/if.h> 97 98 #ifndef __GLIBC__ 99 typedef int socklen_t; 100 #endif 97 101 98 102 static sendpacket_t *sendpacket_open_pf(const char *, char *); 99 103 static struct tcpr_ether_addr *sendpacket_get_hwaddr_pf(sendpacket_t *); 100 static int get_iface_index(int fd, const int8_t *device );104 static int get_iface_index(int fd, const int8_t *device, char *); 101 105 102 106 #elif defined HAVE_BPF … … 148 152 149 153 #if defined HAVE_PF_PACKET 150 retcode = (int)sendto(sp->handle.fd, (void *)data, len, 0, 151 (struct sockaddr *)&sp->sa, sizeof(struct sockaddr)); 154 retcode = (int)send(sp->handle.fd, (void *)data, len, 0); 155 156 /* out of buffers, silently retry */ 152 157 if (retcode < 0 && errno == ENOBUFS && !didsig) { 153 158 sp->retry ++; 154 159 goto TRY_SEND_AGAIN; 155 } else if (retcode < 0) { 156 sendpacket_seterr(sp, "Error with sendto(): %s", strerror(errno)); 160 } 161 /* some other kind of error */ 162 else if (retcode < 0) { 163 sendpacket_seterr(sp, "Error with pf send(): %s", strerror(errno)); 157 164 } 158 165 … … 172 179 goto TRY_SEND_AGAIN; 173 180 } else if (retcode < 0) { 174 sendpacket_seterr(sp, "Error with libnet _adv_write_link: %s", libnet_geterror(sp->handle.lnet));181 sendpacket_seterr(sp, "Error with libnet write: %s", libnet_geterror(sp->handle.lnet)); 175 182 } 176 183 … … 208 215 assert(device); 209 216 assert(errbuf); 210 211 217 212 218 #if defined HAVE_PF_PACKET … … 378 384 sendpacket_t *sp; 379 385 struct ifreq ifr; 380 int n = 1;381 386 struct sockaddr_ll sa; 387 int n = 1, err; 388 socklen_t errlen = sizeof(err); 382 389 383 390 assert(device); … … 390 397 } 391 398 399 400 /* get the interface id for the device */ 401 if ((sa.sll_ifindex = get_iface_index(mysocket, device, errbuf)) < 0) { 402 close(mysocket); 403 return NULL; 404 } 405 406 /* bind socket to our interface id */ 407 sa.sll_family = AF_PACKET; 408 sa.sll_protocol = htons(ETH_P_ALL); 409 if (bind(mysocket, (struct sockaddr *)&sa, sizeof(sa)) < 0) { 410 snprintf(errbuf, SENDPACKET_ERRBUF_SIZE, "bind error: %s", strerror(errno)); 411 close(mysocket); 412 return NULL; 413 } 414 415 /* check for errors, network down, etc... */ 416 if (getsockopt(mysocket, SOL_SOCKET, SO_ERROR, &err, &errlen) < 0) { 417 snprintf(errbuf, SENDPACKET_ERRBUF_SIZE, "error opening %s: %s", device, 418 strerror(errno)); 419 close(mysocket); 420 return NULL; 421 } 422 423 if (err > 0) { 424 snprintf(errbuf, SENDPACKET_ERRBUF_SIZE, "error opening %s: %s", device, 425 strerror(err)); 426 close(mysocket); 427 return NULL; 428 } 429 430 /* get hardware type for our interface */ 392 431 memset(&ifr, 0, sizeof(ifr)); 393 432 strlcpy(ifr.ifr_name, device, sizeof(ifr.ifr_name)); 394 433 395 if (ioctl(mysocket, SIOCGIFHWADDR, (int8_t *)&ifr) < 0) {434 if (ioctl(mysocket, SIOCGIFHWADDR, &ifr) < 0) { 396 435 close(mysocket); 397 sendpacket_seterr(sp, "Error calling SIOCGIFHWADDR: %s", strerror(errno));436 sendpacket_seterr(sp, "Error getting hardware type: %s", strerror(errno)); 398 437 return NULL; 399 438 } … … 406 445 snprintf(errbuf, SENDPACKET_ERRBUF_SIZE, 407 446 "unsupported pysical layer type 0x%x", ifr.ifr_hwaddr.sa_family); 447 close(mysocket); 408 448 return NULL; 409 449 } … … 421 461 snprintf(errbuf, SENDPACKET_ERRBUF_SIZE, 422 462 "SO_BROADCAS: %s\n", strerror(errno)); 463 close(mysocket); 423 464 return NULL; 424 465 } 425 466 #endif /* SO_BROADCAST */ 426 467 427 /* get the sendto() sockaddr struct */ 428 memset(&sa, 0, sizeof(sa)); 429 sa.sll_family = AF_PACKET; 430 if ((sa.sll_ifindex = get_iface_index(mysocket, device)) < 0) { 431 sendpacket_seterr(sp, "Unable to get inteface index: %s", 432 strerror(errno)); 433 return NULL; 434 } 435 468 436 469 /* prep & return our sp handle */ 437 470 sp = (sendpacket_t *)safe_malloc(sizeof(sendpacket_t)); 438 471 strlcpy(sp->device, device, sizeof(sp->device)); 439 sp->handle.fd = mysocket; 440 441 /* need this to do a sendto() */ 442 memcpy(&sp->sa, &sa, sizeof(sa)); 472 sp->handle.fd = mysocket; 443 473 444 474 return sp; … … 447 477 /* get the interface index (necessary for sending packets w/ PF_PACKET) */ 448 478 static int 449 get_iface_index(int fd, const int8_t *device ) {479 get_iface_index(int fd, const int8_t *device, char *errbuf) { 450 480 struct ifreq ifr; 451 481 452 /* memset(&ifr, 0, sizeof(ifr)); */482 memset(&ifr, 0, sizeof(ifr)); 453 483 strlcpy(ifr.ifr_name, device, sizeof(ifr.ifr_name)); 454 484 455 485 if (ioctl(fd, SIOCGIFINDEX, &ifr) == -1) { 486 snprintf(errbuf, SENDPACKET_ERRBUF_SIZE, "ioctl: %s", strerror(errno)); 456 487 return (-1); 457 488 } … … 478 509 479 510 480 /* create dummy devicefor ioctl */511 /* create dummy socket for ioctl */ 481 512 if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { 482 513 sendpacket_seterr(sp, "Unable to open dummy socket for get_hwaddr: %s", strerror(errno)); … … 489 520 if (ioctl(fd, SIOCGIFHWADDR, (int8_t *)&ifr) < 0) { 490 521 close(fd); 491 sendpacket_seterr(sp, "Error calling SIOCGIFHWADDR: %s", strerror(errno));522 sendpacket_seterr(sp, "Error getting hardware address: %s", strerror(errno)); 492 523 return NULL; 493 524 }
