Show
Ignore:
Timestamp:
07/29/06 17:46:31 (2 years ago)
Author:
aturner
Message:

change injection priority to reflect that pcap_* methods don't support
sendpacket_get_hwaddr() refs #4

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • trunk/src/common/sendpacket.c

    r1539 r1547  
    3939  
    4040 /* sendpacket.[ch] is my attempt to write a universal packet injection 
    41   * API for libpcap, libnet, and Linux's PF_PACKET.  I got sick 
     41  * API for BPF, libpcap, libnet, and Linux's PF_PACKET.  I got sick 
    4242  * and tired dealing with libnet bugs and its lack of active maintenence, 
    4343  * but unfortunately, libpcap frame injection support is relatively new  
    44   * and not everyone uses Linux, so I decided to support all three as 
     44  * and not everyone uses Linux, so I decided to support all four as 
    4545  * best as possible.  If your platform/OS/hardware supports an additional 
    4646  * injection method, then by all means add it here (and send me a patch). 
     
    4949  * 1. PF_PACKET 
    5050  * 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. 
    5659  *  
    5760  * Please note that some of this code was copied from Libnet 1.1.3 
     
    8184 
    8285#if defined HAVE_PF_PACKET 
    83  
    8486/* older versions of glibc require different headers */ 
    8587#if __GLIBC__ >= 2 && __GLIBC_MINOR >= 1 
     
    9395 
    9496static sendpacket_t *sendpacket_open_pf(const char *, char *); 
    95 static struct tcpr_ether_addr *get_hwaddr_pf(sendpacket_t *); 
     97static struct tcpr_ether_addr *sendpacket_get_hwaddr_pf(sendpacket_t *); 
    9698 
    9799#elif defined HAVE_BPF 
     
    102104 
    103105static sendpacket_t *sendpacket_open_bpf(const char *, char *); 
    104 static struct tcpr_ether_addr *get_hwaddr_bpf(sendpacket_t *); 
     106static struct tcpr_ether_addr *sendpacket_get_hwaddr_bpf(sendpacket_t *); 
     107 
     108#elif defined HAVE_LIBNET 
     109static sendpacket_t *sendpacket_open_libnet(const char *, char *); 
     110static struct tcpr_ether_addr *sendpacket_get_hwaddr_libnet(sendpacket_t *); 
    105111 
    106112#elif defined HAVE_PCAP_INJECT || defined HAVE_PACKET_SENDPACKET 
    107113#include <pcap.h> 
    108114static 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 *); 
     115static struct tcpr_ether_addr *sendpacket_get_hwaddr_pcap(sendpacket_t *); 
    114116#endif 
    115117 
     
    130132{ 
    131133    int retcode; 
    132 #if defined HAVE_PF_PACKET 
    133     struct sockaddr sa; 
    134 #endif 
     134 
    135135 
    136136    assert(sp); 
     
    140140        return -1; 
    141141                 
     142TRY_SEND_AGAIN: 
    142143    sp->attempt ++; 
    143      
    144 TRY_SEND_AGAIN: 
    145144 
    146145#if defined HAVE_PF_PACKET  
    147     memset(&sa, 0, sizeof(sa)); 
    148     strlcpy(sa.sa_data, sp->device, sizeof(sa.sa_data)); 
    149146    retcode = (int)sendto(sp->handle.fd, (void *)data, (size_t)len, 0,  
    150         &sa, sizeof(struct sockaddr)); 
     147        &sp->sa, sizeof(struct sockaddr)); 
    151148    if (retcode < 0 && errno == ENOBUFS && !didsig) { 
    152149        sp->retry ++; 
     
    165162    } 
    166163     
     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 
    167173    /*  
    168174     * pcap methods don't seem to support ENOBUFS, so we just straight fail 
     
    172178    if ((retcode = pcap_inject(sp->handle.pcap, (void*)data, len)) < 0) 
    173179        sendpacket_seterr(sp, "Error with pcap_inject(): %s", pcap_geterr(sp->handle.pcap)); 
    174      
     180 
    175181#elif defined HAVE_PCAP_SENDPACKET 
    176182    if ((retcode = pcap_sendpacket(sp->handle.pcap, data, (int)len)) < 0) 
    177183        sendpacket_seterr(sp, "Error with pcap_sendpacket(): %s", pcap_geterr(sp->handle.pcap)); 
    178  
    179 #elif defined HAVE_LIBNET 
    180     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     } 
    187184#endif 
    188185 
     
    213210#elif defined HAVE_BPF 
    214211    sp = sendpacket_open_bpf(device, errbuf); 
     212#elif defined HAVE_LIBNET 
     213    sp = sendpacket_open_libnet(device, errbuf); 
    215214#elif (defined HAVE_PCAP_INJECT || defined HAVE_PCAP_SENDPACKET) 
    216215    sp = sendpacket_open_pcap(device, errbuf); 
    217 #elif defined HAVE_LIBNET 
    218     sp = sendpacket_open_libnet(device, errbuf); 
    219216#endif 
    220217    if (sp != NULL) 
     
    264261         
    265262#if defined HAVE_PF_PACKET 
    266     addr = get_hwaddr_pf(sp); 
     263    addr = sendpacket_get_hwaddr_pf(sp); 
    267264#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); 
    269268#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); 
    273270#endif 
    274271    return addr; 
     
    304301 
    305302 
    306  
    307  
    308  
    309303#if defined HAVE_PCAP_INJECT || defined HAVE_PCAP_SENDPACKET 
    310304static sendpacket_t * 
     
    328322 
    329323static 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"); 
     324sendpacket_get_hwaddr_pcap(sendpacket_t *sp) 
     325{ 
     326    assert(sp); 
     327    sendpacket_seterr(sp, "Error: sendpacket_get_hwaddr() not yet supported for pcap injection"); 
    334328    return NULL; 
    335329} 
     
    356350 
    357351static struct tcpr_ether_addr * 
    358 get_hwaddr_libnet(sendpacket_t *sp) 
     352sendpacket_get_hwaddr_libnet(sendpacket_t *sp) 
    359353{ 
    360354    struct tcpr_ether_addr *addr; 
     
    409403    strlcpy(sp->device, device, sizeof(sp->device)); 
    410404    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     
    411410    return sp; 
    412411} 
     
    418417 */ 
    419418struct tcpr_ether_addr * 
    420 get_hwaddr_pf(sendpacket_t *sp) 
     419sendpacket_get_hwaddr_pf(sendpacket_t *sp) 
    421420{ 
    422421    struct ifreq ifr; 
     
    570569 
    571570struct tcpr_ether_addr * 
    572 get_hwaddr_bpf(sendpacket_t *sp) 
     571sendpacket_get_hwaddr_bpf(sendpacket_t *sp) 
    573572{ 
    574573    int mib[6];