Diff for /libaitio/src/bpf.c between versions 1.5 and 1.8

version 1.5, 2013/12/15 22:57:20 version 1.8, 2016/08/18 09:06:31
Line 12  terms: Line 12  terms:
 All of the documentation and software included in the ELWIX and AITNET  All of the documentation and software included in the ELWIX and AITNET
 Releases is copyrighted by ELWIX - Sofia/Bulgaria <info@elwix.org>  Releases is copyrighted by ELWIX - Sofia/Bulgaria <info@elwix.org>
   
Copyright 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013Copyright 2004 - 2016
         by Michael Pounov <misho@elwix.org>.  All rights reserved.          by Michael Pounov <misho@elwix.org>.  All rights reserved.
   
 Redistribution and use in source and binary forms, with or without  Redistribution and use in source and binary forms, with or without
Line 47  SUCH DAMAGE. Line 47  SUCH DAMAGE.
   
   
 /*  /*
  * io_get1stiface() - Get first interface of host  
  *  
  * @szIface = interface string buffer  
  * @iflen = size of interface buffer  
  * return: -1 error or 0 ok  
  */  
 int  
 io_get1stiface(char *szIface, int iflen)  
 {  
         struct ifaddrs *ifa;  
   
         if (!szIface || !iflen)  
                 return -1;  
   
         getifaddrs(&ifa);  
         strlcpy(szIface, ifa->ifa_name, iflen);  
         freeifaddrs(ifa);  
         return 0;  
 }  
   
 /*  
  * io_getmaciface() - Get MAC address from interface name  
  *  
  * @csIface = interface name  
  * @ea = ethernet address  
  * return: -1 error, 0 ok or 1 not found  
  */  
 int  
 io_getmaciface(const char *csIface, ether_addr_t * __restrict ea)  
 {  
         struct ifaddrs *ifa, *ifp;  
         struct sockaddr_dl *dl;  
         int ret = 1;  
   
         if (!csIface || !ea)  
                 return -1;  
         else  
                 memset(ea, 0, sizeof(ether_addr_t));  
   
         getifaddrs(&ifa);  
         for (ifp = ifa; ifp; ifp = ifp->ifa_next)  
                 if (!strcmp(csIface, ifp->ifa_name) && ifp->ifa_addr &&   
                                 ifp->ifa_addr->sa_family == AF_LINK) {  
                         dl = (struct sockaddr_dl*) ifp->ifa_addr;  
                         if ((dl->sdl_type == IFT_ETHER || dl->sdl_type == IFT_L2VLAN ||   
                                         dl->sdl_type == IFT_BRIDGE) &&   
                                         dl->sdl_alen == ETHER_ADDR_LEN) {  
                                 memcpy(ea, LLADDR(dl), sizeof(ether_addr_t));  
                                 ret = 0;  
                                 break;  
                         }  
                 }  
         freeifaddrs(ifa);  
   
         return ret;  
 }  
   
 /*  
  * io_etherClose() - Close BPF interface   * io_etherClose() - Close BPF interface
  *   *
  * @eth = bpf handle   * @eth = bpf handle
Line 114  io_getmaciface(const char *csIface, ether_addr_t * __r Line 56  io_getmaciface(const char *csIface, ether_addr_t * __r
 void  void
 io_etherClose(int eth, void **zcbuf)  io_etherClose(int eth, void **zcbuf)
 {  {
#ifdef __FreeBSD__#if defined(__FreeBSD__) && defined(ZCBUF_ENABLE)
         struct bpf_zbuf *zbuf = NULL;          struct bpf_zbuf *zbuf = NULL;
 #endif  #endif
   
         if (eth > STDERR_FILENO)          if (eth > STDERR_FILENO)
                 close(eth);                  close(eth);
   
   #if defined(__FreeBSD__) && defined(ZCBUF_ENABLE)
         if (zcbuf && *zcbuf) {          if (zcbuf && *zcbuf) {
 #ifdef __FreeBSD__  
                 zbuf = *zcbuf;                  zbuf = *zcbuf;
                 munmap(zbuf->bz_bufb, zbuf->bz_buflen);                  munmap(zbuf->bz_bufb, zbuf->bz_buflen);
                 munmap(zbuf->bz_bufa, zbuf->bz_buflen);                  munmap(zbuf->bz_bufa, zbuf->bz_buflen);
                 e_free(*zcbuf);                  e_free(*zcbuf);
                 *zcbuf = NULL;                  *zcbuf = NULL;
 #endif  
         }          }
   #endif
 }  }
   
#ifdef __FreeBSD__#if defined(__FreeBSD__) && defined(ZCBUF_ENABLE)
 static inline struct bpf_zbuf *  static inline struct bpf_zbuf *
 allocZCbuf(u_int len)  allocZCbuf(u_int len)
 {  {
Line 172  allocZCbuf(u_int len) Line 114  allocZCbuf(u_int len)
  * @csIface = interface name   * @csIface = interface name
  * @flags = open flags   * @flags = open flags
  * @whdr = with complete headers   * @whdr = with complete headers
 * @wdlt = with data link type * @wdlt = with data link type, on Linux is protocol number
  * @buflen = buffer length   * @buflen = buffer length
  * @zcbuf = zero copy buffer, if BPF supports it and isn't NULL   * @zcbuf = zero copy buffer, if BPF supports it and isn't NULL
  * return: -1 error or >-1 bpf handle   * return: -1 error or >-1 bpf handle
  */   */
 int  int
io_etherOpen(const char *csIface, int flags, int whdr, int wdlt, io_etherOpen(const char *csIface, int flags, u_int whdr, u_int wdlt, 
                 u_int *buflen, void **zcbuf)                  u_int *buflen, void **zcbuf)
 {  {
         int eth = -1;          int eth = -1;
         register int i;  
         char szStr[STRSIZ];          char szStr[STRSIZ];
         struct ifreq ifr;          struct ifreq ifr;
   #ifndef __linux__
           register int i;
         u_int n = 1;          u_int n = 1;
   #else
           sockaddr_t sa = {{ 0 }};
   #endif
   
#ifndef __FreeBSD__#if !defined(__FreeBSD__) || !defined(ZCBUF_ENABLE)
         if (zcbuf) {          if (zcbuf) {
                 io_SetErr(ENOTSUP, "bpf zero copy buffer mode is not supported");                  io_SetErr(ENOTSUP, "bpf zero copy buffer mode is not supported");
                 return -1;                  return -1;
         }          }
 #endif  #endif
   
   #ifndef __linux__
         for (i = 0; i < BPF_DEV_MAX; i++) {          for (i = 0; i < BPF_DEV_MAX; i++) {
                 memset(szStr, 0, sizeof szStr);                  memset(szStr, 0, sizeof szStr);
                 snprintf(szStr, sizeof szStr, "/dev/bpf%d", i);                  snprintf(szStr, sizeof szStr, "/dev/bpf%d", i);
Line 201  io_etherOpen(const char *csIface, int flags, int whdr, Line 148  io_etherOpen(const char *csIface, int flags, int whdr,
                 if (eth > STDERR_FILENO)                  if (eth > STDERR_FILENO)
                         break;                          break;
         }          }
   #else
           eth = socket(AF_PACKET, whdr ? SOCK_RAW : SOCK_DGRAM, htons((u_short) wdlt));
   #endif
         if (eth < 3) {          if (eth < 3) {
                 LOGERR;                  LOGERR;
                 return -1;                  return -1;
Line 208  io_etherOpen(const char *csIface, int flags, int whdr, Line 158  io_etherOpen(const char *csIface, int flags, int whdr,
   
         if (csIface)          if (csIface)
                 strlcpy(szStr, csIface, sizeof szStr);                  strlcpy(szStr, csIface, sizeof szStr);
        else if (io_get1stiface(szStr, sizeof szStr) == -1) {        else if (e_get1stiface(szStr, sizeof szStr) == -1) {
                 close(eth);                  close(eth);
                 return -1;                  return -1;
         }          }
   
   #ifndef __linux__
         n = 1;          n = 1;
         if (whdr && ioctl(eth, BIOCSHDRCMPLT, &n) == -1) {          if (whdr && ioctl(eth, BIOCSHDRCMPLT, &n) == -1) {
                 LOGERR;                  LOGERR;
                 close(eth);                  close(eth);
                 return -1;                  return -1;
         }          }
         if (wdlt && ioctl(eth, BIOCSDLT, &wdlt) == -1) {  
                 LOGERR;  
                 close(eth);  
                 return -1;  
         }  
         if (ioctl(eth, BIOCIMMEDIATE, &n) == -1) {          if (ioctl(eth, BIOCIMMEDIATE, &n) == -1) {
                 LOGERR;                  LOGERR;
                 close(eth);                  close(eth);
Line 246  io_etherOpen(const char *csIface, int flags, int whdr, Line 192  io_etherOpen(const char *csIface, int flags, int whdr,
                 if (buflen)                  if (buflen)
                         *buflen = n;                          *buflen = n;
         } else {          } else {
#ifdef __FreeBSD__#if defined(__FreeBSD__) && defined(ZCBUF_ENABLE)
                 n = BPF_BUFMODE_ZBUF;                  n = BPF_BUFMODE_ZBUF;
                 if (ioctl(eth, BIOCSETBUFMODE, &n) == -1) {                  if (ioctl(eth, BIOCSETBUFMODE, &n) == -1) {
                         LOGERR;                          LOGERR;
Line 281  io_etherOpen(const char *csIface, int flags, int whdr, Line 227  io_etherOpen(const char *csIface, int flags, int whdr,
                 return -1;                  return -1;
         }          }
   
           n = wdlt;
           if (wdlt && ioctl(eth, BIOCSDLT, &n) == -1) {
                   LOGERR;
                   close(eth);
                   return -1;
           }
   #else
           memset(&ifr, 0, sizeof ifr);
           strlcpy(ifr.ifr_name, szStr, sizeof ifr.ifr_name);
           if (ioctl(eth, SIOCGIFINDEX, &ifr)) {
                   LOGERR;
                   close(eth);
                   return -1;
           }
   
           sa.sll.sll_family = AF_PACKET;
           sa.sll.sll_ifindex = ifr.ifr_ifindex;
           sa.sll.sll_protocol = htons((u_short) wdlt);
           if (bind(eth, &sa.sa, sizeof(sa.sll)) == -1) {
                   LOGERR;
                   close(eth);
                   return -1;
           }
   #endif
   
         return eth;          return eth;
 }  }
   
Line 308  io_etherSend(int eth, const void *buf, size_t buflen) Line 279  io_etherSend(int eth, const void *buf, size_t buflen)
         return wlen;          return wlen;
 }  }
   
#ifdef __FreeBSD__#if defined(__FreeBSD__) && defined(ZCBUF_ENABLE)
 static inline void  static inline void
 ackZCbuf(struct bpf_zbuf_header *bzh)  ackZCbuf(struct bpf_zbuf_header *bzh)
 {  {
Line 367  ssize_t Line 338  ssize_t
 io_etherRecv(int eth, void * __restrict buf, size_t buflen, void * __restrict zcbuf)  io_etherRecv(int eth, void * __restrict buf, size_t buflen, void * __restrict zcbuf)
 {  {
         ssize_t rlen = 0;          ssize_t rlen = 0;
   #ifndef __linux__
         struct bpf_hdr *h;          struct bpf_hdr *h;
   #endif
   
         if (!buf || !buflen) {          if (!buf || !buflen) {
                 io_SetErr(EINVAL, "invalid arguments");                  io_SetErr(EINVAL, "invalid arguments");
Line 381  io_etherRecv(int eth, void * __restrict buf, size_t bu Line 354  io_etherRecv(int eth, void * __restrict buf, size_t bu
                         return -1;                          return -1;
                 }                  }
         } else {          } else {
#ifdef __FreeBSD__#if defined(__FreeBSD__) && defined(ZCBUF_ENABLE)
                 rlen = nextZCbuf(eth, (struct bpf_zbuf*) zcbuf, buf, buflen);                  rlen = nextZCbuf(eth, (struct bpf_zbuf*) zcbuf, buf, buflen);
                 if (!rlen)                  if (!rlen)
                         rlen = nextZCbuf(eth, (struct bpf_zbuf*) zcbuf, buf, buflen);                          rlen = nextZCbuf(eth, (struct bpf_zbuf*) zcbuf, buf, buflen);
Line 391  io_etherRecv(int eth, void * __restrict buf, size_t bu Line 364  io_etherRecv(int eth, void * __restrict buf, size_t bu
 #endif  #endif
         }          }
   
   #ifndef __linux__
         h = (struct bpf_hdr*) buf;          h = (struct bpf_hdr*) buf;
         rlen -= h->bh_hdrlen;          rlen -= h->bh_hdrlen;
   
Line 405  io_etherRecv(int eth, void * __restrict buf, size_t bu Line 379  io_etherRecv(int eth, void * __restrict buf, size_t bu
         }          }
   
         memmove(buf, buf + h->bh_hdrlen, rlen);          memmove(buf, buf + h->bh_hdrlen, rlen);
   #endif
         return rlen;          return rlen;
 }  }
   
   #ifndef __linux__
 /*  /*
  * io_etherFilter() - BPF filter routine   * io_etherFilter() - BPF filter routine
  *   *
Line 454  io_etherFilter(int eth, int io, struct bpf_insn * __re Line 430  io_etherFilter(int eth, int io, struct bpf_insn * __re
                 LOGERR;                  LOGERR;
         return ret;          return ret;
 }  }
   #endif

Removed from v.1.5  
changed lines
  Added in v.1.8


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