Show
Ignore:
Timestamp:
03/31/07 21:05:16 (22 months ago)
Author:
aturner
Message:

- fix stats report
- fix pcap_sendpacket() return on error
refs #137

Files:
1 modified

Legend:

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

    r1773 r1778  
    8181#include <errno.h> 
    8282#include <stdarg.h> 
     83#include <stdio.h> 
    8384#include <sys/types.h> 
    8485#include <sys/time.h> 
     
    129130static sendpacket_t *sendpacket_open_libnet(const char *, char *) __attribute__((unused)); 
    130131static struct tcpr_ether_addr *sendpacket_get_hwaddr_libnet(sendpacket_t *) __attribute__((unused)); 
    131  
    132132#endif /* HAVE_LIBNET */ 
    133133 
     
    175175        sendpacket_seterr(sp, "Error with pf send(): %s", strerror(errno)); 
    176176    } 
    177      
     177 
    178178#elif defined HAVE_BPF 
    179179    retcode = write(sp->handle.fd, (void *)data, len); 
     
    184184        sendpacket_seterr(sp, "Error with bpf write(): %s", strerror(errno)); 
    185185    } 
    186      
     186 
    187187#elif defined HAVE_LIBNET 
    188188    retcode = libnet_adv_write_link(sp->handle.lnet, (u_int8_t*)data, (u_int32_t)len); 
     
    194194    } 
    195195 
     196#elif defined HAVE_PCAP_INJECT 
    196197    /*  
    197198     * pcap methods don't seem to support ENOBUFS, so we just straight fail 
    198199     * is there a better way??? 
    199200     */     
    200 #elif defined HAVE_PCAP_INJECT 
    201     if ((retcode = pcap_inject(sp->handle.pcap, (void*)data, len)) < 0) 
    202         sendpacket_seterr(sp, "Error with pcap_inject(): %s", pcap_geterr(sp->handle.pcap)); 
     201    retcode = pcap_inject(sp->handle.pcap, (void*)data, len); 
     202    if (retcode < 0 && errno == ENOBUFS && !didsig) { 
     203        sp->retry ++; 
     204        goto TRY_SEND_AGAIN; 
     205    } else if (retcode < 0) { 
     206        sendpacket_seterr(sp, "Error with pcap_inject(packet " COUNTER_SPEC "): %s (%d)",  
     207            sp->sent + 1, pcap_geterr(sp->handle.pcap), errno); 
     208    } 
    203209 
    204210#elif defined HAVE_PCAP_SENDPACKET 
    205     if ((retcode = pcap_sendpacket(sp->handle.pcap, data, (int)len)) < 0) 
    206         sendpacket_seterr(sp, "Error with pcap_sendpacket(): %s", pcap_geterr(sp->handle.pcap)); 
    207  
    208     /*  
    209      * pcap_sendpacket returns 0 on success, not the packet length!  
    210      * hence, as a special case, update the counters here and return len 
    211      */ 
    212     sp->bytes_sent += len; 
    213     sp->sent ++; 
    214     return len; 
     211    retcode = pcap_sendpacket(sp->handle.pcap, data, (int)len); 
     212    if (retcode < 0 && errno == ENOBUFS && !didsig) { 
     213        sp->retry ++; 
     214        goto TRY_SEND_AGAIN; 
     215    } else if (retcode < 0) { 
     216        sendpacket_seterr(sp, "Error with pcap_sendpacket(packet " COUNTER_SPEC "): %s", 
     217            sp->sent + 1, pcap_geterr(sp->handle.pcap)); 
     218    } else { 
     219        /*  
     220         * pcap_sendpacket returns 0 on success, not the packet length!  
     221         * hence, we have to fix retcode to be more standard on success 
     222         */ 
     223        retcode = len; 
     224    } 
     225 
    215226#endif 
    216227 
     
    259270     
    260271    memset(buf, 0, sizeof(buf)); 
    261     sprintf(buf, "Statistics for network device: %s\n", sp->device); 
    262     sprintf(buf, "Attempted packets:   " COUNTER_SPEC "\n", sp->attempt); 
    263     sprintf(buf, "Successful packets:  " COUNTER_SPEC "\n", sp->sent); 
    264     sprintf(buf, "Failed packets:      " COUNTER_SPEC "\n", sp->failed); 
    265     sprintf(buf, "Retried packets:     " COUNTER_SPEC "\n", sp->retry); 
     272    sprintf(buf, "Statistics for network device: %s\n" 
     273        "\tAttempted packets:   " COUNTER_SPEC "\n" 
     274        "\tSuccessful packets:  " COUNTER_SPEC "\n" 
     275        "\tFailed packets:      " COUNTER_SPEC "\n" 
     276        "\tRetried packets:     " COUNTER_SPEC "\n", 
     277        sp->device, sp->attempt, sp->sent, sp->failed, sp->retry); 
    266278    return(buf); 
    267279} 
     
    337349    pcap_t *pcap; 
    338350    sendpacket_t *sp; 
    339      
     351    /* 
     352    u_int spoof_eth_src = 1; 
     353    int fd; 
     354    */ 
    340355    assert(device); 
    341356    assert(errbuf); 
     357 
     358    dbg(1, "sendpacket: using Libpcap"); 
    342359     
    343360    /* open_pcap_live automatically fills out our errbuf for us */ 
     
    348365    strlcpy(sp->device, device, sizeof(sp->device)); 
    349366    sp->handle.pcap = pcap; 
     367/* 
     368    fd = pcap_get_selectable_fd(pcap); 
     369    if (ioctl(fd, BIOCSHDRCMPLT, &spoof_eth_src) == -1) { 
     370        errx(1, "Unable to enable source MAC spoof support: %s", strerror(errno)); 
     371    } 
     372*/     
    350373    return sp; 
    351374} 
     
    369392    assert(device); 
    370393    assert(errbuf); 
     394     
     395    dbg(1, "sendpacket: using Libnet"); 
    371396     
    372397    if ((lnet = libnet_init(LIBNET_LINK_ADV, device, errbuf)) == NULL) 
     
    411436    assert(errbuf); 
    412437    
     438   dbg(1, "sendpacket: using PF_PACKET"); 
     439 
    413440    /* open our socket */ 
    414441    if ((mysocket = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL))) < 0) { 
     
    568595    memset(&ifr, '\0', sizeof(struct ifreq)); 
    569596     
     597    dbg(1, "sendpacket: using BPF"); 
    570598    /* open socket */ 
    571599    mysocket = -1; 
     
    720748{ 
    721749    int dlt; 
    722 #if defined HAVE_PF_PACKET || defined HAVE_LIBNET 
     750#if defined HAVE_BPF 
     751    int rcode; 
     752 
     753    if ((rcode = ioctl(sp->handle.fd, BIOCGDLT, &dlt)) < 0) { 
     754        warnx("Unable to get DLT value for BPF device (%s): %s", sp->device, strerror(errno)); 
     755        return(-1); 
     756    } 
     757#elif defined HAVE_PF_PACKET || defined HAVE_LIBNET 
    723758    /* use libpcap to get dlt */ 
    724759    pcap_t *pcap; 
     
    730765    dlt = pcap_datalink(pcap); 
    731766    pcap_close(pcap); 
    732 #elif defined HAVE_BPF 
    733     int rcode; 
    734  
    735     if ((rcode = ioctl(sp->handle.fd, BIOCGDLT, &dlt)) < 0) { 
    736         warnx("Unable to get DLT value for BPF device (%s): %s", sp->device, strerror(errno)); 
    737         return(-1); 
    738     } 
    739 #else /* HAVE_PCAP_SENDPACKET / HAVE_PCAP_INJECT */ 
     767#elif defined HAVE_PCAP_SENDPACKET || defined HAVE_PCAP_INJECT 
    740768    dlt = pcap_datalink(sp->handle.pcap); 
    741769#endif 
    742770    return dlt; 
    743771} 
    744  
    745