Changeset 1561 for trunk/src/common/sendpacket.c
- Timestamp:
- 08/01/06 12:24:04 (2 years ago)
- Files:
-
- 1 modified
-
trunk/src/common/sendpacket.c (modified) (9 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/common/sendpacket.c
r1547 r1561 53 53 * 5. pcap_sendpacket() 54 54 * 55 * Right now, one big problem with the pcap_* methods is that libpcap doesn't provide a 56 * reliable method of getting the MAC address of an interface (required for tcpbridge). 57 * You can use PF_PACKET or BPF to get that, but if your system suports those, might 58 * as well inject directly without going through another level of indirection. 55 * Right now, one big problem with the pcap_* methods is that libpcap 56 * doesn't provide a reliable method of getting the MAC address of 57 * an interface (required for tcpbridge). 58 * You can use PF_PACKET or BPF to get that, but if your system suports 59 * those, might as well inject directly without going through another 60 * level of indirection. 59 61 * 60 62 * Please note that some of this code was copied from Libnet 1.1.3 … … 79 81 #include <sys/sysctl.h> 80 82 #include <net/route.h> 81 #include <net/if_dl.h>82 83 #include <stdlib.h> 83 84 #include <unistd.h> … … 93 94 #include <net/ethernet.h> 94 95 #endif 96 #include <net/if.h> 95 97 96 98 static sendpacket_t *sendpacket_open_pf(const char *, char *); 97 99 static struct tcpr_ether_addr *sendpacket_get_hwaddr_pf(sendpacket_t *); 100 static int get_iface_index(int fd, const int8_t *device); 98 101 99 102 #elif defined HAVE_BPF … … 102 105 #include <net/if.h> 103 106 #include <sys/uio.h> 107 #include <net/if_dl.h> // used for get_hwaddr_bpf() 104 108 105 109 static sendpacket_t *sendpacket_open_bpf(const char *, char *); … … 133 137 int retcode; 134 138 135 136 139 assert(sp); 137 140 assert(data); … … 145 148 #if defined HAVE_PF_PACKET 146 149 retcode = (int)sendto(sp->handle.fd, (void *)data, (size_t)len, 0, 147 &sp->sa, sizeof(struct sockaddr));150 (struct sockaddr *)&sp->sa, sizeof(struct sockaddr)); 148 151 if (retcode < 0 && errno == ENOBUFS && !didsig) { 149 152 sp->retry ++; … … 373 376 int mysocket; 374 377 sendpacket_t *sp; 375 struct ifreq ifr; 376 378 struct ifreq ifr; 379 int n = 1; 380 struct sockaddr_ll sa; 381 377 382 assert(device); 378 383 assert(errbuf); 379 384 385 /* open our socket */ 380 386 if ((mysocket = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL))) < 0) { 381 snprintf(errbuf, PCAP_ERRBUF_SIZE, "socket: %s", strerror(errno)); 382 return NULL; 383 } 384 385 memset(&ifr, 0, sizeof(struct ifreq)); 386 strlcpy(ifr.ifr_name, device, sizeof(ifr.ifr_name)); 387 if (ioctl(mysocket, SIOCGIFHWADDR, &ifr) < 0) { 388 snprintf(errbuf, PCAP_ERRBUF_SIZE, "SIOCGIFHWADDR: %s", strerror(errno)); 389 return NULL; 390 } 391 392 switch (ifr.ifr_hwaddr.sa_family) 393 { 394 case ARPHRD_ETHER; 387 snprintf(errbuf, SENDPACKET_ERRBUF_SIZE, "socket: %s", strerror(errno)); 388 return NULL; 389 } 390 391 /* make sure it's ethernet */ 392 switch (ifr.ifr_hwaddr.sa_family) { 393 case ARPHRD_ETHER: 395 394 break; 396 395 default: 397 snprintf(errbuf, PCAP_ERRBUF_SIZE, "unsupported pysical layer type 0x%x",398 ifr.ifr_hwaddr.sa_family);396 snprintf(errbuf, SENDPACKET_ERRBUF_SIZE, 397 "unsupported pysical layer type 0x%x", ifr.ifr_hwaddr.sa_family); 399 398 return NULL; 400 399 } 401 400 401 #ifdef SO_BROADCAST 402 /* 403 * man 7 socket 404 * 405 * Set or get the broadcast flag. When enabled, datagram sockets 406 * receive packets sent to a broadcast address and they are allowed 407 * to send packets to a broadcast address. This option has no 408 * effect on stream-oriented sockets. 409 */ 410 if (setsockopt(mysocket, SOL_SOCKET, SO_BROADCAST, &n, sizeof(n)) == -1) { 411 snprintf(errbuf, SENDPACKET_ERRBUF_SIZE, 412 "SO_BROADCAS: %s\n", strerror(errno)); 413 return NULL; 414 } 415 #endif /* SO_BROADCAST */ 416 417 /* get the sendto() sockaddr struct */ 418 memset(&sa, 0, sizeof(sa)); 419 sa.sll_family = AF_PACKET; 420 if ((sa.sll_ifindex = get_iface_index(sp->handle.fd, sp->device)) < 0) { 421 sendpacket_seterr(sp, "Unable to get inteface index: %s", 422 strerror(errno)); 423 return NULL; 424 } 425 426 /* prep & return our sp handle */ 402 427 sp = (sendpacket_t *)safe_malloc(sizeof(sendpacket_t)); 403 428 strlcpy(sp->device, device, sizeof(sp->device)); 404 429 sp->handle.fd = mysocket; 405 430 406 /* need this to do a write */ 407 strlcpy(sp->sa.sa_data, sp->device, sizeof(sp->sa.sa_data)); 408 431 /* need this to do a sendto() */ 432 memcpy(&sp->sa, &sa, sizeof(sa)); 409 433 410 434 return sp; 411 435 } 412 436 437 /* get the interface index (necessary for sending packets w/ PF_PACKET) */ 438 static int 439 get_iface_index(int fd, const int8_t *device) { 440 struct ifreq ifr; 441 442 /* memset(&ifr, 0, sizeof(ifr)); */ 443 strlcpy(ifr.ifr_name, device, sizeof(ifr.ifr_name)); 444 445 if (ioctl(fd, SIOCGIFINDEX, &ifr) == -1) { 446 return (-1); 447 } 448 449 return ifr.ifr_ifindex; 450 } 413 451 414 452 /* … … 421 459 struct ifreq ifr; 422 460 int fd; 423 struct struct tcpr_ether_addr &eap;424 461 425 462 assert(sp); … … 438 475 439 476 memset(&ifr, 0, sizeof(ifr)); 440 eap = &ea;441 477 strlcpy(ifr.ifr_name, sp->device, sizeof(ifr.ifr_name)); 442 478 443 479 if (ioctl(fd, SIOCGIFHWADDR, (int8_t *)&ifr) < 0) { 444 480 close(fd); 445 sendpacket_seterr( "Error callign SIOCGIFHWADDR: %s", strerror(errno));446 return NULL; 447 } 448 449 memcpy( sp->ether, &ifr.ifr_hwaddr.sa_data, ETHER_ADDR_LEN);481 sendpacket_seterr(sp, "Error callign SIOCGIFHWADDR: %s", strerror(errno)); 482 return NULL; 483 } 484 485 memcpy(&sp->ether, &ifr.ifr_hwaddr.sa_data, ETHER_ADDR_LEN); 450 486 close(fd); 451 487 return(&sp->ether);
