Show
Ignore:
Timestamp:
08/01/06 12:24:04 (2 years ago)
Author:
aturner
Message:

fix compile issues under linux w/ PF_PACKET, refs #4

Files:
1 modified

Legend:

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

    r1547 r1561  
    5353  * 5. pcap_sendpacket() 
    5454  * 
    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. 
    5961  *  
    6062  * Please note that some of this code was copied from Libnet 1.1.3 
     
    7981#include <sys/sysctl.h> 
    8082#include <net/route.h> 
    81 #include <net/if_dl.h> 
    8283#include <stdlib.h> 
    8384#include <unistd.h> 
     
    9394#include <net/ethernet.h> 
    9495#endif 
     96#include <net/if.h> 
    9597 
    9698static sendpacket_t *sendpacket_open_pf(const char *, char *); 
    9799static struct tcpr_ether_addr *sendpacket_get_hwaddr_pf(sendpacket_t *); 
     100static int get_iface_index(int fd, const int8_t *device); 
    98101 
    99102#elif defined HAVE_BPF 
     
    102105#include <net/if.h> 
    103106#include <sys/uio.h> 
     107#include <net/if_dl.h> // used for get_hwaddr_bpf() 
    104108 
    105109static sendpacket_t *sendpacket_open_bpf(const char *, char *); 
     
    133137    int retcode; 
    134138 
    135  
    136139    assert(sp); 
    137140    assert(data); 
     
    145148#if defined HAVE_PF_PACKET  
    146149    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)); 
    148151    if (retcode < 0 && errno == ENOBUFS && !didsig) { 
    149152        sp->retry ++; 
     
    373376    int mysocket; 
    374377    sendpacket_t *sp; 
    375     struct ifreq ifr;        
    376      
     378    struct ifreq ifr; 
     379    int n = 1; 
     380    struct sockaddr_ll sa; 
     381 
    377382    assert(device); 
    378383    assert(errbuf); 
    379      
     384    
     385    /* open our socket */ 
    380386    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: 
    395394            break; 
    396395        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); 
    399398            return NULL; 
    400399    } 
    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 */ 
    402427    sp = (sendpacket_t *)safe_malloc(sizeof(sendpacket_t)); 
    403428    strlcpy(sp->device, device, sizeof(sp->device)); 
    404429    sp->handle.fd = mysocket; 
    405430     
    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));  
    409433     
    410434    return sp; 
    411435} 
    412436 
     437/* get the interface index (necessary for sending packets w/ PF_PACKET) */ 
     438static int 
     439get_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}               
    413451 
    414452/* 
     
    421459    struct ifreq ifr; 
    422460    int fd; 
    423     struct struct tcpr_ether_addr &eap; 
    424461     
    425462    assert(sp); 
     
    438475 
    439476    memset(&ifr, 0, sizeof(ifr)); 
    440     eap = &ea; 
    441477    strlcpy(ifr.ifr_name, sp->device, sizeof(ifr.ifr_name)); 
    442478     
    443479    if (ioctl(fd, SIOCGIFHWADDR, (int8_t *)&ifr) < 0) { 
    444480        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); 
    450486    close(fd); 
    451487    return(&sp->ether);