Changeset 1547 for trunk/src/common/sendpacket.c
- Timestamp:
- 07/29/06 17:46:31 (2 years ago)
- Files:
-
- 1 modified
-
trunk/src/common/sendpacket.c (modified) (17 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/common/sendpacket.c
r1539 r1547 39 39 40 40 /* sendpacket.[ch] is my attempt to write a universal packet injection 41 * API for libpcap, libnet, and Linux's PF_PACKET. I got sick41 * API for BPF, libpcap, libnet, and Linux's PF_PACKET. I got sick 42 42 * and tired dealing with libnet bugs and its lack of active maintenence, 43 43 * but unfortunately, libpcap frame injection support is relatively new 44 * and not everyone uses Linux, so I decided to support all threeas44 * and not everyone uses Linux, so I decided to support all four as 45 45 * best as possible. If your platform/OS/hardware supports an additional 46 46 * injection method, then by all means add it here (and send me a patch). … … 49 49 * 1. PF_PACKET 50 50 * 2. BPF 51 * 3. pcap_inject() 52 * 4. pcap_sendpacket() 53 * 5. libnet 54 * Once I get some Linux testing, I should move PF_PACKET to the top of the list 55 * as it is the most direct method. 51 * 3. libnet 52 * 4. pcap_inject() 53 * 5. pcap_sendpacket() 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. 56 59 * 57 60 * Please note that some of this code was copied from Libnet 1.1.3 … … 81 84 82 85 #if defined HAVE_PF_PACKET 83 84 86 /* older versions of glibc require different headers */ 85 87 #if __GLIBC__ >= 2 && __GLIBC_MINOR >= 1 … … 93 95 94 96 static sendpacket_t *sendpacket_open_pf(const char *, char *); 95 static struct tcpr_ether_addr * get_hwaddr_pf(sendpacket_t *);97 static struct tcpr_ether_addr *sendpacket_get_hwaddr_pf(sendpacket_t *); 96 98 97 99 #elif defined HAVE_BPF … … 102 104 103 105 static sendpacket_t *sendpacket_open_bpf(const char *, char *); 104 static struct tcpr_ether_addr *get_hwaddr_bpf(sendpacket_t *); 106 static struct tcpr_ether_addr *sendpacket_get_hwaddr_bpf(sendpacket_t *); 107 108 #elif defined HAVE_LIBNET 109 static sendpacket_t *sendpacket_open_libnet(const char *, char *); 110 static struct tcpr_ether_addr *sendpacket_get_hwaddr_libnet(sendpacket_t *); 105 111 106 112 #elif defined HAVE_PCAP_INJECT || defined HAVE_PACKET_SENDPACKET 107 113 #include <pcap.h> 108 114 static sendpacket_t *sendpacket_open_pcap(const char *, char *); 109 static struct tcpr_ether_addr *get_hwaddr_pcap(sendpacket_t *); 110 111 #elif defined HAVE_LIBNET 112 static sendpacket_t *sendpacket_open_libnet(const char *, char *); 113 static struct tcpr_ether_addr *get_hwaddr_libnet(sendpacket_t *); 115 static struct tcpr_ether_addr *sendpacket_get_hwaddr_pcap(sendpacket_t *); 114 116 #endif 115 117 … … 130 132 { 131 133 int retcode; 132 #if defined HAVE_PF_PACKET 133 struct sockaddr sa; 134 #endif 134 135 135 136 136 assert(sp); … … 140 140 return -1; 141 141 142 TRY_SEND_AGAIN: 142 143 sp->attempt ++; 143 144 TRY_SEND_AGAIN:145 144 146 145 #if defined HAVE_PF_PACKET 147 memset(&sa, 0, sizeof(sa));148 strlcpy(sa.sa_data, sp->device, sizeof(sa.sa_data));149 146 retcode = (int)sendto(sp->handle.fd, (void *)data, (size_t)len, 0, 150 &s a, sizeof(struct sockaddr));147 &sp->sa, sizeof(struct sockaddr)); 151 148 if (retcode < 0 && errno == ENOBUFS && !didsig) { 152 149 sp->retry ++; … … 165 162 } 166 163 164 #elif defined HAVE_LIBNET 165 retcode = libnet_adv_write_link(sp->handle.lnet, (u_int8_t*)data, (u_int32_t)len); 166 if (retcode < 0 && errno == ENOBUFS && !didsig) { 167 sp->retry ++; 168 goto TRY_SEND_AGAIN; 169 } else if (retcode < 0) { 170 sendpacket_seterr(sp, "Error with libnet_adv_write_link: %s", libnet_geterror(sp->handle.lnet)); 171 } 172 167 173 /* 168 174 * pcap methods don't seem to support ENOBUFS, so we just straight fail … … 172 178 if ((retcode = pcap_inject(sp->handle.pcap, (void*)data, len)) < 0) 173 179 sendpacket_seterr(sp, "Error with pcap_inject(): %s", pcap_geterr(sp->handle.pcap)); 174 180 175 181 #elif defined HAVE_PCAP_SENDPACKET 176 182 if ((retcode = pcap_sendpacket(sp->handle.pcap, data, (int)len)) < 0) 177 183 sendpacket_seterr(sp, "Error with pcap_sendpacket(): %s", pcap_geterr(sp->handle.pcap)); 178 179 #elif defined HAVE_LIBNET180 retcode = libnet_adv_write_link(sp->handle.lnet, (u_int8_t*)data, (u_int32_t)len);181 if (retcode < 0 && errno == ENOBUFS && !didsig) {182 sp->retry ++;183 goto TRY_SEND_AGAIN;184 } else if (retcode < 0) {185 sendpacket_seterr(sp, "Error with libnet_adv_write_link: %s", libnet_geterror(sp->handle.lnet));186 }187 184 #endif 188 185 … … 213 210 #elif defined HAVE_BPF 214 211 sp = sendpacket_open_bpf(device, errbuf); 212 #elif defined HAVE_LIBNET 213 sp = sendpacket_open_libnet(device, errbuf); 215 214 #elif (defined HAVE_PCAP_INJECT || defined HAVE_PCAP_SENDPACKET) 216 215 sp = sendpacket_open_pcap(device, errbuf); 217 #elif defined HAVE_LIBNET218 sp = sendpacket_open_libnet(device, errbuf);219 216 #endif 220 217 if (sp != NULL) … … 264 261 265 262 #if defined HAVE_PF_PACKET 266 addr = get_hwaddr_pf(sp);263 addr = sendpacket_get_hwaddr_pf(sp); 267 264 #elif defined HAVE_BPF 268 addr = get_hwaddr_bpf(sp); 265 addr = sendpacket_get_hwaddr_bpf(sp); 266 #elif defined HAVE_LIBNET 267 addr = sendpacket_get_hwaddr_libnet(sp); 269 268 #elif (defined HAVE_PCAP_INJECT || defined HAVE_PCAP_SENDPACKET) 270 addr = get_hwaddr_pcap(sp); 271 #elif defined HAVE_LIBNET 272 addr = get_hwaddr_libnet(sp); 269 addr = sendpacket_get_hwaddr_pcap(sp); 273 270 #endif 274 271 return addr; … … 304 301 305 302 306 307 308 309 303 #if defined HAVE_PCAP_INJECT || defined HAVE_PCAP_SENDPACKET 310 304 static sendpacket_t * … … 328 322 329 323 static struct tcpr_ether_addr * 330 get_hwaddr_pcap(sendpacket_t *sp)331 { 332 assert(sp); 333 sendpacket_seterr(sp, "Error: get_hwaddr() not yet supported for pcap injection");324 sendpacket_get_hwaddr_pcap(sendpacket_t *sp) 325 { 326 assert(sp); 327 sendpacket_seterr(sp, "Error: sendpacket_get_hwaddr() not yet supported for pcap injection"); 334 328 return NULL; 335 329 } … … 356 350 357 351 static struct tcpr_ether_addr * 358 get_hwaddr_libnet(sendpacket_t *sp)352 sendpacket_get_hwaddr_libnet(sendpacket_t *sp) 359 353 { 360 354 struct tcpr_ether_addr *addr; … … 409 403 strlcpy(sp->device, device, sizeof(sp->device)); 410 404 sp->handle.fd = mysocket; 405 406 /* need this to do a write */ 407 strlcpy(sp->sa.sa_data, sp->device, sizeof(sp->sa.sa_data)); 408 409 411 410 return sp; 412 411 } … … 418 417 */ 419 418 struct tcpr_ether_addr * 420 get_hwaddr_pf(sendpacket_t *sp)419 sendpacket_get_hwaddr_pf(sendpacket_t *sp) 421 420 { 422 421 struct ifreq ifr; … … 570 569 571 570 struct tcpr_ether_addr * 572 get_hwaddr_bpf(sendpacket_t *sp)571 sendpacket_get_hwaddr_bpf(sendpacket_t *sp) 573 572 { 574 573 int mib[6];
