Changeset 1535 for trunk/src/common/sendpacket.c
- Timestamp:
- 07/28/06 20:36:04 (2 years ago)
- Files:
-
- 1 modified
-
trunk/src/common/sendpacket.c (modified) (11 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/common/sendpacket.c
r1533 r1535 76 76 #include <net/if_dl.h> 77 77 #include <stdlib.h> 78 #include <unistd.h> 78 79 79 80 #if defined HAVE_PF_PACKET … … 96 97 #include <sys/socket.h> 97 98 #include <net/if.h> 99 #include <sys/uio.h> 100 98 101 static sendpacket_t *sendpacket_open_bpf(const char *, char *); 99 102 static struct tcpr_ether_addr *get_hwaddr_bpf(sendpacket_t *); … … 126 129 { 127 130 int retcode; 128 #if defined HAVE_PF_PACKET || defined HAVE_BPF131 #if defined HAVE_PF_PACKET 129 132 struct sockaddr sa; 130 133 #endif … … 137 140 138 141 sp->attempt ++; 139 140 #if defined HAVE_PF_PACKET || defined HAVE_BPF 142 143 TRY_SEND_AGAIN: 144 145 #if defined HAVE_PF_PACKET 141 146 memset(&sa, 0, sizeof(sa)); 142 147 strlcpy(sa.sa_data, sp->device, sizeof(sa.sa_data)); 143 if ((retcode = (int)sendto(sp->handle.fd, (void *)data, (size_t)len, 0, 144 &sa, sizeof(struct sockaddr))) < 0) { 148 retcode = (int)sendto(sp->handle.fd, (void *)data, (size_t)len, 0, 149 &sa, sizeof(struct sockaddr)); 150 if (retcode < 0 && errno == ENOBUFS && !didsig) { 151 sp->retry ++; 152 goto TRY_SEND_AGAIN; 153 } else if (retcode < 0) { 145 154 sendpacket_seterr(sp, "Error with sendto(): %s", strerror(errno)); 146 155 } 147 156 157 #elif defined HAVE_BPF 158 retcode = write(sp->handle.fd, (void *)data, len); 159 if (retcode < 0 && errno == ENOBUFS && !didsig) { 160 sp->retry ++; 161 goto TRY_SEND_AGAIN; 162 } else if (retcode < 0) { 163 sendpacket_seterr(sp, "Error with bpf write(): %s", strerror(errno)); 164 } 165 166 /* 167 * pcap methods don't seem to support ENOBUFS, so we just straight fail 168 * is there a better way??? 169 */ 148 170 #elif defined HAVE_PCAP_INJECT 149 171 if ((retcode = pcap_inject(sp->handle.pcap, (void*)data, len)) < 0) … … 154 176 sendpacket_seterr(sp, "Error with pcap_sendpacket(): %s", pcap_geterr(sp->handle.pcap)); 155 177 156 157 178 #elif defined HAVE_LIBNET 158 SEND_VIA_LIBNET:159 179 retcode = libnet_adv_write_link(sp->handle.lnet, (u_int8_t*)data, (u_int32_t)len); 160 180 if (retcode < 0 && errno == ENOBUFS && !didsig) { 161 181 sp->retry ++; 162 goto SEND_VIA_LIBNET;182 goto TRY_SEND_AGAIN; 163 183 } else if (retcode < 0) { 164 184 sendpacket_seterr(sp, "Error with libnet_adv_write_link: %s", libnet_geterr(sp->lnet)); … … 168 188 if (retcode < 0) { 169 189 sp->failed ++; 170 } else if (retcode != len) {171 sendpacket_seterr(sp, "Only able to write %d bytes out of % dbytes total",172 retcode, (int)len);190 } else if (retcode != (int)len) { 191 sendpacket_seterr(sp, "Only able to write %d bytes out of %u bytes total", 192 retcode, len); 173 193 } else { 174 194 sp->bytes_sent += len; … … 192 212 #elif defined HAVE_BPF 193 213 sp = sendpacket_open_bpf(device, errbuf); 194 #elif defined HAVE_PCAP_INJECT || defined HAVE_PCAP_SENDPACKET214 #elif (defined HAVE_PCAP_INJECT || defined HAVE_PCAP_SENDPACKET) 195 215 sp = sendpacket_open_pcap(device, errbuf); 196 216 #elif defined HAVE_LIBNET 197 217 sp = sendpacket_open_libnet(device, errbuf); 198 218 #endif 199 sp->open = 1; 219 if (sp != NULL) 220 sp->open = 1; 200 221 return sp; 201 222 } … … 222 243 { 223 244 assert(sp); 224 sp->open = 0; 245 246 free(sp); 225 247 return 0; 226 248 } … … 236 258 assert(sp); 237 259 238 260 /* if we already have our MAC address stored, just return it */ 261 if (memcmp(&sp->ether, "\00\00\00\00\00\00", ETHER_ADDR_LEN) != 0) 262 return &sp->ether; 263 239 264 #if defined HAVE_PF_PACKET 240 265 addr = get_hwaddr_pf(sp); 241 266 #elif defined HAVE_BPF 242 267 addr = get_hwaddr_bpf(sp); 243 #elif defined HAVE_PCAP_INJECT || defined HAVE_PCAP_SENDPACKET268 #elif (defined HAVE_PCAP_INJECT || defined HAVE_PCAP_SENDPACKET) 244 269 addr = get_hwaddr_pcap(sp); 245 270 #elif defined HAVE_LIBNET … … 291 316 assert(errbuf); 292 317 293 if ((pcap = pcap_open_live(device, 0, 0, 0, errbuf)) == NULL) 318 /* open_pcap_live automatically fills out our errbuf for us */ 319 if ((pcap = pcap_open_live(device, 0, 0, 0, errbuf)) == NULL) 294 320 return NULL; 295 321 … … 433 459 sendpacket_t *sp; 434 460 char bpf_dev[10]; 435 int dev, mysocket; 436 struct ifreq ifr; 461 int dev, mysocket, link_offset, link_type; 462 struct ifreq ifr; 463 struct bpf_version bv; 464 u_int v; 465 #if defined(BIOCGHDRCMPLT) && defined(BIOCSHDRCMPLT) && !(__APPLE__) 466 u_int spoof_eth_src = 1; 467 #endif 437 468 438 469 assert(device); 439 470 assert(errbuf); 440 441 for (dev = 0; dev <= 20; dev ++) { 471 memset(&ifr, '\0', sizeof(struct ifreq)); 472 473 /* open socket */ 474 mysocket = -1; 475 for (dev = 0; dev <= 9; dev ++) { 442 476 memset(bpf_dev, '\0', sizeof(bpf_dev)); 443 477 snprintf(bpf_dev, sizeof(bpf_dev), "/dev/bpf%d", dev); 444 if ((mysocket = open(bpf_dev, O_RDWR |O_NONBLOCK, 0)) > 0) {445 continue;478 if ((mysocket = open(bpf_dev, O_RDWR, 0)) > 0) { 479 break; 446 480 } 447 481 } 448 482 449 /* error */ 450 if (mysocket < 0) 451 return NULL; 452 483 /* error?? */ 484 if (mysocket < 0) { 485 snprintf(errbuf, SENDPACKET_ERRBUF_SIZE, 486 "Unable to open /dev/bpfX: %s", strerror(errno)); 487 errbuf[SENDPACKET_ERRBUF_SIZE -1] = '\0'; 488 return NULL; 489 } 490 491 /* get BPF version */ 492 if (ioctl(mysocket, BIOCVERSION, (caddr_t)&bv) < 0) { 493 snprintf(errbuf, SENDPACKET_ERRBUF_SIZE, "Unable to get bpf version: %s", strerror(errno)); 494 return NULL; 495 } 496 497 if (bv.bv_major != BPF_MAJOR_VERSION || bv.bv_minor != BPF_MINOR_VERSION) { 498 snprintf(errbuf, SENDPACKET_ERRBUF_SIZE, "Kernel's bpf version is out of date."); 499 return NULL; 500 } 501 502 /* attach to device */ 453 503 strlcpy(ifr.ifr_name, device, sizeof(ifr.ifr_name)); 454 if (ioctl(mysocket, BIOCSETIF, &ifr) < 0) { 455 snprintf(errbuf, PCAP_ERRBUF_SIZE, "BIOCSETIF: %s", strerror(errno)); 504 if (ioctl(mysocket, BIOCSETIF, (caddr_t)&ifr) < 0) { 505 snprintf(errbuf, SENDPACKET_ERRBUF_SIZE, "Unable to bind %s to %s: %s", 506 bpf_dev, device, strerror(errno)); 456 507 return NULL; 457 508 } 458 509 510 /* get datalink type */ 511 if (ioctl(mysocket, BIOCGDLT, (caddr_t)&v) < 0) { 512 snprintf(errbuf, SENDPACKET_ERRBUF_SIZE, "Unable to get datalink type: %s", 513 strerror(errno)); 514 return NULL; 515 } 516 517 /* 518 * NetBSD and FreeBSD BPF have an ioctl for enabling/disabling 519 * automatic filling of the link level source address. 520 */ 521 #if defined(BIOCGHDRCMPLT) && defined(BIOCSHDRCMPLT) && !(__APPLE__) 522 if (ioctl(mysocket, BIOCSHDRCMPLT, &spoof_eth_src) == -1) { 523 snprintf(errbuf, SENDPACKET_ERRBUF_SIZE, 524 "Unable to enable spoofing src MAC: %s", strerror(errno)); 525 return NULL; 526 } 527 #endif 528 529 /* assign link type and offset */ 530 switch (v) { 531 case DLT_SLIP: 532 link_offset = 0x10; 533 break; 534 case DLT_RAW: 535 link_offset = 0x0; 536 break; 537 case DLT_PPP: 538 link_offset = 0x04; 539 break; 540 case DLT_EN10MB: 541 default: /* default to Ethernet */ 542 link_offset = 0xe; 543 break; 544 } 545 #if _BSDI_VERSION - 0 > 199510 546 switch (v) { 547 case DLT_SLIP: 548 v = DLT_SLIP_BSDOS; 549 link_offset = 0x10; 550 break; 551 case DLT_PPP: 552 v = DLT_PPP_BSDOS; 553 link_offset = 0x04; 554 break; 555 } 556 #endif 557 558 link_type = v; 559 560 /* allocate our sp handle, and return it */ 459 561 sp = (sendpacket_t *)safe_malloc(sizeof(sendpacket_t)); 460 562 strlcpy(sp->device, device, sizeof(sp->device)); 461 563 sp->handle.fd = mysocket; 564 //sp->link_type = link_type; 565 //sp->link_offset = link_offset; 566 462 567 return sp; 463 568 }
