Annotation of embedaddon/coova-chilli/src/net.c, revision 1.1.1.1

1.1       misho       1: /*
                      2:  * net library functions.
                      3:  * Copyright (C) 2003, 2004, 2005, 2006 Mondru AB.
                      4:  * Copyright (c) 2006-2008 David Bird <david@coova.com>
                      5:  *
                      6:  * The contents of this file may be used under the terms of the GNU
                      7:  * General Public License Version 2, provided that the above copyright
                      8:  * notice and this permission notice is included in all copies or
                      9:  * substantial portions of the software.
                     10:  *
                     11:  */
                     12: 
                     13: #include "system.h"
                     14: #include "syserr.h"
                     15: #include "options.h"
                     16: #include "net.h"
                     17: 
                     18: int dev_set_flags(char const *dev, int flags) {
                     19:   struct ifreq ifr;
                     20:   int fd;
                     21:   
                     22:   memset(&ifr, 0, sizeof(ifr));
                     23:   ifr.ifr_flags = flags;
                     24:   strncpy(ifr.ifr_name, dev, IFNAMSIZ);
                     25:   ifr.ifr_name[IFNAMSIZ-1] = 0; /* Make sure to terminate */
                     26: 
                     27:   if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
                     28:     log_err(errno,"socket() failed");
                     29:     return -1;
                     30:   }
                     31: 
                     32:   if (ioctl(fd, SIOCSIFFLAGS, &ifr)) {
                     33:     log_err(errno,"ioctl(SIOCSIFFLAGS) failed");
                     34:     close(fd);
                     35:     return -1;
                     36:   }
                     37: 
                     38:   close(fd);
                     39: 
                     40:   return 0;
                     41: }
                     42: 
                     43: int dev_get_flags(char const *dev, int *flags) {
                     44:   struct ifreq ifr;
                     45:   int fd;
                     46:   
                     47:   memset(&ifr, 0, sizeof(ifr));
                     48:   strncpy(ifr.ifr_name, dev, IFNAMSIZ);
                     49:   ifr.ifr_name[IFNAMSIZ-1] = 0; 
                     50: 
                     51:   if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
                     52:     log_err(errno, "socket() failed");
                     53:     return -1;
                     54:   }
                     55: 
                     56:   if (ioctl(fd, SIOCGIFFLAGS, &ifr)) {
                     57:     log_err(errno, "ioctl(SIOCSIFFLAGS) failed");
                     58:     close(fd);
                     59:     return -1;
                     60:   }
                     61: 
                     62:   close(fd);
                     63: 
                     64:   *flags = ifr.ifr_flags;
                     65: 
                     66:   return 0;
                     67: }
                     68: 
                     69: int dev_set_address(char const *devname, struct in_addr *address, 
                     70:                    struct in_addr *dstaddr, struct in_addr *netmask) {
                     71:   struct ifreq ifr;
                     72:   int fd;
                     73: 
                     74:   memset (&ifr, 0, sizeof (ifr));
                     75:   ifr.ifr_addr.sa_family = AF_INET;
                     76:   ifr.ifr_dstaddr.sa_family = AF_INET;
                     77: 
                     78: #if defined(__linux__)
                     79:   ifr.ifr_netmask.sa_family = AF_INET;
                     80: 
                     81: #elif defined(__FreeBSD__) || defined (__APPLE__) || defined (__OpenBSD__) || defined (__NetBSD__)
                     82:   ((struct sockaddr_in *) &ifr.ifr_addr)->sin_len = sizeof (struct sockaddr_in);
                     83:   ((struct sockaddr_in *) &ifr.ifr_dstaddr)->sin_len = sizeof (struct sockaddr_in);
                     84: #endif
                     85: 
                     86:   strncpy(ifr.ifr_name, devname, IFNAMSIZ);
                     87:   ifr.ifr_name[IFNAMSIZ-1] = 0; /* Make sure to terminate */
                     88: 
                     89:   /* Create a channel to the NET kernel. */
                     90:   if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
                     91:     log_err(errno, "socket() failed");
                     92:     return -1;
                     93:   }
                     94: 
                     95:   if (address) { /* Set the interface address */
                     96:     ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr.s_addr = address->s_addr;
                     97:     if (ioctl(fd, SIOCSIFADDR, (void *) &ifr) < 0) {
                     98:       if (errno != EEXIST) {
                     99:        log_err(errno, "ioctl(SIOCSIFADDR) failed");
                    100:       }
                    101:       else {
                    102:        log_warn(errno, "ioctl(SIOCSIFADDR): Address already exists");
                    103:       }
                    104:       close(fd);
                    105:       return -1;
                    106:     }
                    107:   }
                    108: 
                    109:   if (dstaddr) { /* Set the destination address */
                    110:     ((struct sockaddr_in *) &ifr.ifr_dstaddr)->sin_addr.s_addr = dstaddr->s_addr;
                    111:     if (ioctl(fd, SIOCSIFDSTADDR, (caddr_t) &ifr) < 0) {
                    112:       log_err(errno, "ioctl(SIOCSIFDSTADDR) failed");
                    113:       close(fd);
                    114:       return -1; 
                    115:     }
                    116:   }
                    117: 
                    118:   if (netmask) { /* Set the netmask */
                    119: #if defined(__linux__)
                    120:     ((struct sockaddr_in *) &ifr.ifr_netmask)->sin_addr.s_addr =  netmask->s_addr;
                    121: 
                    122: #elif defined(__FreeBSD__) || defined (__APPLE__) || defined (__OpenBSD__) || defined (__NetBSD__)
                    123:     ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr.s_addr =  netmask->s_addr;
                    124: 
                    125: #elif defined(__sun__)
                    126:     ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr.s_addr =  netmask->s_addr;
                    127: #else
                    128: #error  "Unknown platform!" 
                    129: #endif
                    130: 
                    131:     if (ioctl(fd, SIOCSIFNETMASK, (void *) &ifr) < 0) {
                    132:       log_err(errno, "ioctl(SIOCSIFNETMASK) failed");
                    133:       close(fd);
                    134:       return -1;
                    135:     }
                    136:   }
                    137:   
                    138:   close(fd);
                    139:   
                    140:   return dev_set_flags(devname, IFF_UP | IFF_RUNNING); 
                    141: }
                    142: 
                    143: int net_init(net_interface *netif, char *ifname, uint16_t protocol, int promisc, uint8_t *mac) {
                    144:   memset(netif, 0, sizeof(net_interface));
                    145:   strncpy(netif->devname, ifname, IFNAMSIZ);
                    146:   netif->devname[IFNAMSIZ] = 0;
                    147:   netif->protocol = protocol;
                    148: 
                    149:   if (promisc) netif->flags |= NET_PROMISC;
                    150:   
                    151:   if (mac) {
                    152:     netif->flags |= NET_USEMAC;
                    153:     memcpy(netif->hwaddr, mac, PKT_ETH_ALEN);
                    154:   }
                    155:   
                    156:   return net_open(netif);
                    157: }
                    158: 
                    159: int net_open(net_interface *netif) {
                    160:   net_close(netif);
                    161:   net_gflags(netif);
                    162: 
                    163:   if (!(netif->devflags & IFF_UP) || !(netif->devflags & IFF_RUNNING)) {
                    164:     struct in_addr noaddr;
                    165:     net_sflags(netif, netif->devflags | IFF_NOARP);
                    166:     memset(&noaddr, 0, sizeof(noaddr));
                    167:     dev_set_address(netif->devname, &noaddr, NULL, NULL);
                    168:   }
                    169: 
                    170:   return net_open_eth(netif);
                    171: }
                    172: 
                    173: int net_reopen(net_interface *netif) {
                    174:   net_close(netif);
                    175:   return net_open(netif);
                    176: }
                    177: 
                    178: int net_set_address(net_interface *netif, struct in_addr *address, 
                    179:                    struct in_addr *dstaddr, struct in_addr *netmask) {
                    180:   netif->address.s_addr = address->s_addr;
                    181:   netif->gateway.s_addr = dstaddr->s_addr;
                    182:   netif->netmask.s_addr = netmask->s_addr;
                    183: 
                    184:   return dev_set_address(netif->devname, address, dstaddr, netmask);
                    185: }
                    186: 
                    187: ssize_t net_read(net_interface *netif, void *d, size_t dlen) {
                    188:   ssize_t len;
                    189:   
                    190:   if ((len = read(netif->fd, d, dlen)) < 0) {
                    191: #ifdef ENETDOWN
                    192:     if (errno == ENETDOWN) {
                    193:       net_reopen(netif);
                    194:     }
                    195: #endif
                    196:     log_err(errno, "read(fd=%d, len=%d) == %d", netif->fd, dlen, len);
                    197:     return -1;
                    198:   }
                    199: 
                    200:   return len;
                    201: }
                    202: 
                    203: ssize_t net_write(net_interface *netif, void *d, size_t dlen) {
                    204:   ssize_t len;
                    205:   
                    206:   if ((len = write(netif->fd, d, dlen)) < 0) {
                    207: #ifdef ENETDOWN
                    208:     if (errno == ENETDOWN) {
                    209:       net_reopen(netif);
                    210:     }
                    211: #endif
                    212:     log_err(errno, "write(fd=%d, len=%d) failed", netif->fd, dlen);
                    213:     return -1;
                    214:   }
                    215: 
                    216:   return len;
                    217: }
                    218: 
                    219: int net_route(struct in_addr *dst, struct in_addr *gateway, struct in_addr *mask, int delete) {
                    220: 
                    221:   /* TODO: solaris!  */
                    222: 
                    223: #if defined(__linux__)
                    224:   struct rtentry r;
                    225:   int fd;
                    226: 
                    227:   memset (&r, 0, sizeof (r));
                    228:   r.rt_flags = RTF_UP | RTF_GATEWAY; /* RTF_HOST not set */
                    229: 
                    230:   /* Create a channel to the NET kernel. */
                    231:   if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
                    232:     log_err(errno, "socket() failed");
                    233:     return -1;
                    234:   }
                    235: 
                    236:   r.rt_dst.sa_family     = AF_INET;
                    237:   r.rt_gateway.sa_family = AF_INET;
                    238:   r.rt_genmask.sa_family = AF_INET;
                    239:   ((struct sockaddr_in *) &r.rt_dst)->sin_addr.s_addr = dst->s_addr;
                    240:   ((struct sockaddr_in *) &r.rt_gateway)->sin_addr.s_addr = gateway->s_addr;
                    241:   ((struct sockaddr_in *) &r.rt_genmask)->sin_addr.s_addr = mask->s_addr;
                    242:   
                    243:   if (delete) {
                    244:     if (ioctl(fd, SIOCDELRT, (void *) &r) < 0) {
                    245:       log_err(errno,"ioctl(SIOCDELRT) failed");
                    246:       close(fd);
                    247:       return -1;
                    248:     }
                    249:   }
                    250:   else {
                    251:     if (ioctl(fd, SIOCADDRT, (void *) &r) < 0) {
                    252:       log_err(errno, "ioctl(SIOCADDRT) failed");
                    253:       close(fd);
                    254:       return -1;
                    255:     }
                    256:   }
                    257:   close(fd);
                    258:   return 0;
                    259:   
                    260: #elif defined(__FreeBSD__) || defined (__APPLE__) || defined (__OpenBSD__) || defined (__NetBSD__)
                    261: 
                    262:   struct {
                    263:     struct rt_msghdr rt;
                    264:     struct sockaddr_in dst;
                    265:     struct sockaddr_in gate;
                    266:     struct sockaddr_in mask;
                    267:   } req;
                    268:   
                    269:   int fd;
                    270:   struct rt_msghdr *rtm;
                    271:   
                    272:   if ((fd = socket(AF_ROUTE, SOCK_RAW, 0)) == -1) {
                    273:     log_err(errno, "socket() failed");
                    274:     return -1;
                    275:   }
                    276:   
                    277:   memset(&req, 0, sizeof(req));
                    278:   
                    279:   rtm  = &req.rt;
                    280:   
                    281:   rtm->rtm_msglen = sizeof(req);
                    282:   rtm->rtm_version = RTM_VERSION;
                    283:   if (delete) {
                    284:     rtm->rtm_type = RTM_DELETE;
                    285:   }
                    286:   else {
                    287:     rtm->rtm_type = RTM_ADD;
                    288:   }
                    289:   rtm->rtm_flags = RTF_UP | RTF_GATEWAY | RTF_STATIC;  /* TODO */
                    290:   rtm->rtm_addrs = RTA_DST | RTA_GATEWAY | RTA_NETMASK;
                    291:   rtm->rtm_pid = getpid();      
                    292:   rtm->rtm_seq = 0044;                                 /* TODO */
                    293:   
                    294:   req.dst.sin_family       = AF_INET;
                    295:   req.dst.sin_len          = sizeof(req.dst);
                    296:   req.mask.sin_family      = AF_INET;
                    297:   req.mask.sin_len         = sizeof(req.mask);
                    298:   req.gate.sin_family      = AF_INET;
                    299:   req.gate.sin_len         = sizeof(req.gate);
                    300:   
                    301:   req.dst.sin_addr.s_addr  = dst->s_addr;
                    302:   req.mask.sin_addr.s_addr = mask->s_addr;
                    303:   req.gate.sin_addr.s_addr = gateway->s_addr;
                    304:   
                    305:   if (write(fd, rtm, rtm->rtm_msglen) < 0) {
                    306:     log_err(errno, "write() failed");
                    307:     close(fd);
                    308:     return -1;
                    309:   }
                    310:   close(fd);
                    311:   return 0;
                    312:   
                    313: #elif defined(__sun__)
                    314:   log_err(errno, "Could not set up routing on Solaris. Please add route manually.");
                    315:   return 0;
                    316: #else
                    317: #error  "Unknown platform!"
                    318: #endif
                    319: }
                    320: 
                    321: #if defined(__linux__)
                    322: 
                    323: /**
                    324:  * Opens an Ethernet interface. As an option the interface can be set in
                    325:  * promisc mode. If not null macaddr and ifindex are filled with the
                    326:  * interface mac address and index
                    327:  **/
                    328: int net_open_eth(net_interface *netif) {
                    329:   struct ifreq ifr;
                    330:   struct packet_mreq mr;
                    331:   struct sockaddr_ll sa;
                    332:   int option = 1;
                    333: 
                    334:   memset(&ifr, 0, sizeof(ifr));
                    335: 
                    336:   /* Create socket */
                    337:   if ((netif->fd = socket(PF_PACKET, SOCK_RAW, htons(netif->protocol))) < 0) {
                    338:     if (errno == EPERM) {
                    339:       log_err(errno, "Cannot create raw socket. Must be root.");
                    340:     }
                    341: 
                    342:     log_err(errno, "socket(domain=%d, type=%lx, protocol=%d) failed",
                    343:            PF_PACKET, SOCK_RAW, netif->protocol);
                    344: 
                    345:     return -1;
                    346:   }
                    347: 
                    348:   /* Enable reception and transmission of broadcast frames */
                    349:   if (setsockopt(netif->fd, SOL_SOCKET, SO_BROADCAST, &option, sizeof(option)) < 0) {
                    350:     log_err(errno, "setsockopt(s=%d, level=%d, optname=%d, optlen=%d) failed",
                    351:            netif->fd, SOL_SOCKET, SO_BROADCAST, sizeof(option));
                    352:     return -1;
                    353:   }
                    354:   
                    355:   /* Get the MAC address of our interface */
                    356:   strncpy(ifr.ifr_name, netif->devname, sizeof(ifr.ifr_name));
                    357:   if (ioctl(netif->fd, SIOCGIFHWADDR, &ifr) < 0) {
                    358:     log_err(errno, "ioctl(d=%d, request=%d) failed", netif->fd, SIOCGIFHWADDR);
                    359:     return -1;
                    360:   }
                    361: 
                    362:   if (ifr.ifr_hwaddr.sa_family == ARPHRD_ETHER) {
                    363: 
                    364:     netif->flags |= NET_ETHHDR;
                    365: 
                    366:     if ((netif->flags & NET_USEMAC) == 0)
                    367:       memcpy(netif->hwaddr, ifr.ifr_hwaddr.sa_data, PKT_ETH_ALEN);
                    368:   }
                    369:   
                    370:   if (netif->hwaddr[0] & 0x01) {
                    371:     log_err(0, "Ethernet has broadcast or multicast address: %.16s", netif->devname);
                    372:   }
                    373: 
                    374:   /* Get the current interface address, network, and any destination address */
                    375: 
                    376:   /* Verify that MTU = ETH_DATA_LEN */
                    377:   strncpy(ifr.ifr_name, netif->devname, sizeof(ifr.ifr_name));
                    378:   if (ioctl(netif->fd, SIOCGIFMTU, &ifr) < 0) {
                    379:     log_err(errno, "ioctl(d=%d, request=%d) failed", netif->fd, SIOCGIFMTU);
                    380:     return -1;
                    381:   }
                    382:   if (ifr.ifr_mtu != ETH_DATA_LEN) {
                    383:     log_err(0, "MTU does not match EHT_DATA_LEN: %d %d", ifr.ifr_mtu, ETH_DATA_LEN);
                    384:     return -1;
                    385:   }
                    386: 
                    387:   /* Get ifindex */
                    388:   strncpy(ifr.ifr_name, netif->devname, sizeof(ifr.ifr_name));
                    389:   if (ioctl(netif->fd, SIOCGIFINDEX, &ifr) < 0) {
                    390:     log_err(errno, "ioctl(SIOCFIGINDEX) failed");
                    391:   }
                    392:   netif->ifindex = ifr.ifr_ifindex;
                    393:   
                    394:   /* Set interface in promisc mode */
                    395:   if (netif->flags & NET_PROMISC) {
                    396:     memset(&mr,0,sizeof(mr));
                    397:     mr.mr_ifindex = ifr.ifr_ifindex;
                    398:     mr.mr_type =  PACKET_MR_PROMISC;
                    399:     if (setsockopt(netif->fd, SOL_PACKET, PACKET_ADD_MEMBERSHIP, (char *)&mr, sizeof(mr)) < 0) {
                    400:       log_err(errno, "setsockopt(s=%d, level=%d, optname=%d, optlen=%d) failed",
                    401:              netif->fd, SOL_SOCKET, PACKET_ADD_MEMBERSHIP, sizeof(mr));
                    402:       return -1;
                    403:     }
                    404:   }
                    405: 
                    406:   /* Bind to particular interface */
                    407:   memset(&sa, 0, sizeof(sa));
                    408:   sa.sll_family = AF_PACKET;
                    409:   sa.sll_protocol = htons(netif->protocol);
                    410:   sa.sll_ifindex = ifr.ifr_ifindex;
                    411: 
                    412:   if (bind(netif->fd, (struct sockaddr *) &sa, sizeof(sa)) < 0) {
                    413:     log_err(errno, "bind(sockfd=%d) failed", netif->fd);
                    414:     return -1;
                    415:   }
                    416: 
                    417:   return 0;
                    418: }
                    419: 
                    420: #elif defined (__FreeBSD__) || defined (__APPLE__) || defined (__OpenBSD__) || defined (__NetBSD__)
                    421: 
                    422: int net_getmac(const char *ifname, char *macaddr) {
                    423: 
                    424:   struct ifaddrs *ifap, *ifa;
                    425:   struct sockaddr_dl *sdl;
                    426: 
                    427:   if (getifaddrs(&ifap)) {
                    428:     log_err(errno, "getifaddrs() failed!");
                    429:     return -1;
                    430:   }
                    431: 
                    432:   ifa = ifap;
                    433:   while (ifa) {
                    434:     if ((strcmp(ifa->ifa_name, ifname) == 0) &&
                    435:        (ifa->ifa_addr->sa_family == AF_LINK)) {
                    436:       sdl = (struct sockaddr_dl *)ifa->ifa_addr;
                    437:       switch(sdl->sdl_type) {
                    438:       case IFT_ETHER:
                    439: #ifdef IFT_IEEE80211
                    440:       case IFT_IEEE80211:
                    441: #endif
                    442:        break;
                    443:       default:
                    444:        continue;
                    445:       }
                    446:       if (sdl->sdl_alen != PKT_ETH_ALEN) {
                    447:        log_err(errno, "Wrong sdl_alen!");
                    448:        freeifaddrs(ifap);
                    449:        return -1;
                    450:       }
                    451:       memcpy(macaddr, LLADDR(sdl), PKT_ETH_ALEN);
                    452:       freeifaddrs(ifap);
                    453:       return 0;
                    454:     }
                    455:     ifa = ifa->ifa_next;
                    456:   }  
                    457:   freeifaddrs(ifap);
                    458:   return -1;
                    459: }
                    460: 
                    461: /**
                    462:  * Opens an Ethernet interface. As an option the interface can be set in
                    463:  * promisc mode. If not null macaddr and ifindex are filled with the
                    464:  * interface mac address and index
                    465:  **/
                    466: 
                    467: /* Relevant IOCTLs
                    468: FIONREAD Get the number of bytes in input buffer
                    469: SIOCGIFADDR Get interface address (IP)
                    470: BIOCGBLEN, BIOCSBLEN Get and set required buffer length
                    471: BIOCGDLT Type of underlying data interface
                    472: BIOCPROMISC Set in promisc mode
                    473: BIOCFLUSH Flushes the buffer of incoming packets
                    474: BIOCGETIF, BIOCSETIF Set hardware interface. Uses ift_name
                    475: BIOCSRTIMEOUT, BIOCGRTIMEOUT Set and get timeout for reads
                    476: BIOCGSTATS Return stats for the interface
                    477: BIOCIMMEDIATE Return immediately from reads as soon as packet arrives.
                    478: BIOCSETF Set filter
                    479: BIOCVERSION Return the version of BPF
                    480: BIOCSHDRCMPLT BIOCGHDRCMPLT Set flag of wheather to fill in MAC address
                    481: BIOCSSEESENT BIOCGSEESENT Return locally generated packets */
                    482: 
                    483: int net_open_eth(net_interface *netif) {
                    484:   char devname[IFNAMSIZ+5]; /* "/dev/" + ifname */
                    485:   int devnum;
                    486:   struct ifreq ifr;
                    487:   struct ifaliasreq areq;
                    488:   int local_fd;
                    489:   struct bpf_version bv;
                    490: 
                    491:   u_int32_t ipaddr;
                    492:   struct sockaddr_dl hwaddr;
                    493:   unsigned int value;
                    494: 
                    495:   /* Find suitable device */
                    496:   for (devnum = 0; devnum < 255; devnum++) { /* TODO 255 */ 
                    497:     snprintf(devname, sizeof(devname), "/dev/bpf%d", devnum);
                    498:     devname[sizeof(devname)] = 0;
                    499:     if ((netif->fd = open(devname, O_RDWR)) >= 0) break;
                    500:     if (errno != EBUSY) break;
                    501:   } 
                    502:   if (netif->fd < 0) {
                    503:     log_err(errno, "Can't find bpf device");
                    504:     return -1;
                    505:   }
                    506: 
                    507:   /* Set the interface */
                    508:   memset(&ifr, 0, sizeof(ifr));
                    509:   strncpy(ifr.ifr_name, netif->devname, sizeof(ifr.ifr_name));
                    510:   if (ioctl(netif->fd, BIOCSETIF, &ifr) < 0) {
                    511:     log_err(errno,"ioctl() failed");
                    512:     return -1;
                    513:   }
                    514: 
                    515:   /* Get and validate BPF version */
                    516:   if (ioctl(netif->fd, BIOCVERSION, &bv) < 0) {
                    517:     log_err(errno,"ioctl() failed!");
                    518:     return -1;
                    519:   }  
                    520:   if (bv.bv_major != BPF_MAJOR_VERSION ||
                    521:       bv.bv_minor < BPF_MINOR_VERSION) {
                    522:     log_err(errno,"wrong BPF version!");
                    523:     return -1;
                    524:   }
                    525: 
                    526:   /* Get the MAC address of our interface */
                    527:   if (net_getmac(netif->devname, netif->hwaddr)) {
                    528:     log_err(0,"Did not find MAC address!");
                    529:   }
                    530:   else {
                    531:     netif->flags |= NET_ETHHDR;
                    532:   }
                    533:   
                    534:   if (netif->hwaddr[0] & 0x01) {
                    535:     log_err(0, "Ethernet has broadcast or multicast address: %.16s", netif->devname);
                    536:     return -1;
                    537:   }
                    538: 
                    539:   /* Set interface in promisc mode */
                    540:   if (netif->flags & NET_PROMISC) {
                    541:     value = 1;
                    542:     if (ioctl(netif->fd, BIOCPROMISC, NULL) < 0) {
                    543:       log_err(errno,"ioctl() failed!");
                    544:       return -1;
                    545:     }  
                    546:     value = 1;
                    547:     if (ioctl(netif->fd, BIOCSHDRCMPLT, &value) < 0) {
                    548:       log_err(errno,"ioctl() failed!");
                    549:       return -1;
                    550:     }  
                    551:   }
                    552:   else {
                    553:     value = 0;
                    554:     if (ioctl(netif->fd, BIOCSHDRCMPLT, &value) < 0) {
                    555:       log_err(errno,"ioctl() failed!");
                    556:       return -1;
                    557:     }  
                    558:   }
                    559: 
                    560:   /* Make sure reads return as soon as packet has been received */
                    561:   value = 1;
                    562:   if (ioctl(netif->fd, BIOCIMMEDIATE, &value) < 0) {
                    563:     log_err(errno,"ioctl() failed!");
                    564:     return -1;
                    565:   }  
                    566: 
                    567:   return 0;
                    568: }
                    569: 
                    570: #endif
                    571: 

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>