Hi Paolo,

Wouldn't the autoconf check for the symbol (pcap_set_protocol) be
sufficient here?

+  AC_CHECK_LIB([pcap], [pcap_set_protocol], [ AC_DEFINE(PCAP_SET_PROTOCOL, 1) 
], [])

Just checking for the version number wouldn't necessarily mean that
the symbol is available, because the function will only be provided by
libpcap.so on Linux (as it has no effect on other platforms).


Cheers,
Lennert


On Wed, Aug 30, 2017 at 01:58:48PM +0000, Paolo Lucente wrote:

> Hi Lennert,
> 
> Fantastic, please proceed. I guess the patch should be wrapped around
> some version checking of libpcap a-la if greater or equal than current
> release in master then compile the code. I did jus review configure.ac
> and libpcap version is not captured plus i seem to read libpcap folks
> are anti pkg-config, that would have made things extremely simple. We
> may have to resort to something a-la MySQL (since they also do have a
> mysql-config thing and only in 5.7 added pkg-config support):
> 
> https://github.com/pmacct/pmacct/blob/master/m4/ax_lib_mysql.m4
> 
> Paolo
> 
> On Wed, Aug 30, 2017 at 03:59:34PM +0300, Lennert Buytenhek wrote:
> > Hi again!
> > 
> > 
> > On Mon, Jul 03, 2017 at 05:15:33PM +0300, Lennert Buytenhek wrote:
> > 
> > > > I'd be curious what is your strategy to move this forward, especially on
> > > > the libpcap side. If it makes any convenient to you, we can indeed merge
> > > > the pmacct part - since it's all wrapped around that PCAP_SET_PROTOCOL
> > > > definition - and see/re-evaluate how things stand later, at the time of
> > > > 1.7.0 release.
> > > 
> > > Your positive feedback is enough for now, I think -- I'll use that to
> > > try to get the patch merged into libpcap, and if that's successful, I'll
> > > report back here.
> > 
> > The patch was merged into libpcap:
> > 
> >     
> > https://github.com/the-tcpdump-group/libpcap/commit/55c690f6f834b4762697d7a134de439c9096c921
> > 
> > I re-tested with latest libpcap git HEAD with pmacct with the patch I
> > sent earlier (and which is down below), and things still seem to work
> > as expected, i.e. I can restrict capturing to sFlow-sampled packets
> > on Arista swithes.  I guess that means we can merge the pmacct patch.
> > 
> > Thanks!
> > 
> > 
> > Cheers,
> > Lennert
> > 
> > 
> > > > On Fri, Jun 30, 2017 at 05:10:29PM +0300, Lennert Buytenhek wrote:
> > > > > Hi!
> > > > > 
> > > > > Attached is a patch against pmacctd that allows you to specify a
> > > > > specific PF_PACKET protocol to capture, using the following option:
> > > > > 
> > > > >       pcap_protocol: 0xdead
> > > > > 
> > > > > This functionality depends on an extension to libpcap which is not in
> > > > > mainline libpcap (yet), so I've attached the corresponding libpcap 
> > > > > patch
> > > > > as well, for reference.
> > > > > 
> > > > > The main use case for this is running pmacctd on Arista switches, 
> > > > > where
> > > > > packets sampled by the switch fabric are delivered to virtual 
> > > > > interfaces
> > > > > on the management CPU with skb->protocol set to the magic value 0x002d
> > > > > (independently of the sampled packet's ethertype!), and we want to
> > > > > capture only those sampled packets, and not the packets generated by 
> > > > > or
> > > > > destined for the switch's control plane, which also traverse those
> > > > > virtual interfaces.
> > > > > 
> > > > > This pmacctd patch depends on a libpcap patch that hasn't been merged 
> > > > > or
> > > > > even submitted upstream yet, and I would first like to get some 
> > > > > feedback
> > > > > on the pmacctd patch.  If it looks okay, I can then use that feedback
> > > > > when submitting the libpcap patch.
> > > > > 
> > > > > Any feedback appreciated!
> > > > > 
> > > > > 
> > > > > Cheers,
> > > > > Lennert
> > > > 
> > > > > diff --git a/configure.ac b/configure.ac
> > > > > index 415f7b3..8f41b69 100644
> > > > > --- a/configure.ac
> > > > > +++ b/configure.ac
> > > > > @@ -447,7 +447,7 @@ if test x"$PFRING_LIB_FOUND" = x""; then
> > > > >      ERROR: missing pcap library. Refer to: http://www.tcpdump.org/
> > > > >    ])])
> > > > >  
> > > > > -  AC_CHECK_LIB([pcap], [pcap_setnonblock], [ AC_DEFINE(PCAP_7, 1) ], 
> > > > > [])
> > > > > +  AC_CHECK_LIB([pcap], [pcap_set_protocol], [ 
> > > > > AC_DEFINE(PCAP_SET_PROTOCOL, 1) ], [])
> > > > >    AC_CHECK_LIB([pcap], [bpf_filter], [ AC_DEFINE(PCAP_NOBPF, 1) ], 
> > > > > [])
> > > > >  else
> > > > >    dnl Unable to test: we should check for these libs
> > > > > diff --git a/src/cfg.h b/src/cfg.h
> > > > > index 3206282..58c315c 100644
> > > > > --- a/src/cfg.h
> > > > > +++ b/src/cfg.h
> > > > > @@ -447,6 +447,7 @@ struct configuration {
> > > > >  #endif
> > > > >    int promisc; /* pcap_open_live() promisc parameter */
> > > > >    char *clbuf; /* pcap filter */
> > > > > +  int pcap_protocol;
> > > > >    char *pcap_savefile;
> > > > >    char *dev;
> > > > >    int if_wait;
> > > > > diff --git a/src/cfg_handlers.c b/src/cfg_handlers.c
> > > > > index d9237c0..25885ec 100644
> > > > > --- a/src/cfg_handlers.c
> > > > > +++ b/src/cfg_handlers.c
> > > > > @@ -462,6 +462,18 @@ int cfg_key_pcap_filter(char *filename, char 
> > > > > *name, char *value_ptr)
> > > > >    return changes;
> > > > >  }
> > > > >  
> > > > > +int cfg_key_pcap_protocol(char *filename, char *name, char 
> > > > > *value_ptr)
> > > > > +{
> > > > > +  struct plugins_list_entry *list = plugins_list;
> > > > > +  int value, changes = 0;
> > > > > +
> > > > > +  value = strtol(value_ptr, NULL, 0);
> > > > > +  for (; list; list = list->next, changes++) list->cfg.pcap_protocol 
> > > > > = value;
> > > > > +  if (name) Log(LOG_WARNING, "WARN: [%s] plugin name not supported 
> > > > > for key 'pcap_protocol'. Globalized.\n", filename);
> > > > > +
> > > > > +  return changes;
> > > > > +}
> > > > > +
> > > > >  int cfg_key_interface(char *filename, char *name, char *value_ptr)
> > > > >  {
> > > > >    struct plugins_list_entry *list = plugins_list;
> > > > > diff --git a/src/cfg_handlers.h b/src/cfg_handlers.h
> > > > > index 41100ef..5fec930 100644
> > > > > --- a/src/cfg_handlers.h
> > > > > +++ b/src/cfg_handlers.h
> > > > > @@ -42,6 +42,7 @@ EXT int cfg_key_aggregate_primitives(char *, char 
> > > > > *, char *);
> > > > >  EXT int cfg_key_snaplen(char *, char *, char *);
> > > > >  EXT int cfg_key_aggregate_filter(char *, char *, char *);
> > > > >  EXT int cfg_key_pcap_filter(char *, char *, char *);
> > > > > +EXT int cfg_key_pcap_protocol(char *, char *, char *);
> > > > >  EXT int cfg_key_use_ip_next_hop(char *, char *, char *);
> > > > >  EXT int cfg_key_thread_stack(char *, char *, char *);
> > > > >  EXT int cfg_key_interface(char *, char *, char *);
> > > > > diff --git a/src/pmacct-data.h b/src/pmacct-data.h
> > > > > index 6f5ac0a..64319f6 100644
> > > > > --- a/src/pmacct-data.h
> > > > > +++ b/src/pmacct-data.h
> > > > > @@ -320,6 +320,7 @@ static const struct _dictionary_line dictionary[] 
> > > > > = {
> > > > >    {"aggregate_filter", cfg_key_aggregate_filter},
> > > > >    {"promisc", cfg_key_promisc},
> > > > >    {"pcap_filter", cfg_key_pcap_filter},
> > > > > +  {"pcap_protocol", cfg_key_pcap_protocol},
> > > > >    {"core_proc_name", cfg_key_proc_name},
> > > > >    {"proc_priority", cfg_key_proc_priority},
> > > > >    {"pmacctd_as", cfg_key_nfacctd_as_new},
> > > > > diff --git a/src/pmacctd.c b/src/pmacctd.c
> > > > > index 7e13796..c7e9d34 100644
> > > > > --- a/src/pmacctd.c
> > > > > +++ b/src/pmacctd.c
> > > > > @@ -91,6 +91,59 @@ void usage_daemon(char *prog_name)
> > > > >    printf("For suggestions, critics, bugs, contact me: %s.\n", 
> > > > > MANTAINER);
> > > > >  }
> > > > >  
> > > > > +static pcap_t *do_pcap_open(const char *device, int snaplen, int 
> > > > > promisc,
> > > > > +                         int to_ms, int protocol, char *errbuf)
> > > > > +{
> > > > > +  pcap_t *p;
> > > > > +  int ret;
> > > > > +
> > > > > +  p = pcap_create(device, errbuf);
> > > > > +  if (p == NULL)
> > > > > +    return NULL;
> > > > > +
> > > > > +  ret = pcap_set_snaplen(p, snaplen);
> > > > > +  if (ret < 0)
> > > > > +    goto err;
> > > > > +
> > > > > +  ret = pcap_set_promisc(p, promisc);
> > > > > +  if (ret < 0)
> > > > > +    goto err;
> > > > > +
> > > > > +  ret = pcap_set_timeout(p, to_ms);
> > > > > +  if (ret < 0)
> > > > > +    goto err;
> > > > > +
> > > > > +#ifdef PCAP_SET_PROTOCOL
> > > > > +  ret = pcap_set_protocol(p, protocol);
> > > > > +  if (ret < 0)
> > > > > +    goto err;
> > > > > +#else
> > > > > +  if (protocol)
> > > > > +    Log(LOG_WARNING, "WARN ( %s/core ): pcap_protocol specified but 
> > > > > linked against a version of libpcap that does not support 
> > > > > pcap_set_protocol.\n", config.name);
> > > > > +#endif
> > > > > +
> > > > > +  ret = pcap_activate(p);
> > > > > +  if (ret < 0)
> > > > > +    goto err;
> > > > > +
> > > > > +  return p;
> > > > > +
> > > > > +err:
> > > > > +  if (ret == PCAP_ERROR)
> > > > > +    snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s", device, 
> > > > > pcap_geterr(p));
> > > > > +  else if (ret == PCAP_ERROR_NO_SUCH_DEVICE ||
> > > > > +        ret == PCAP_ERROR_PERM_DENIED ||
> > > > > +        ret == PCAP_ERROR_PROMISC_PERM_DENIED)
> > > > > +    snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s (%s)", device,
> > > > > +          pcap_statustostr(ret), pcap_geterr(p));
> > > > > +  else
> > > > > +    snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s", device,
> > > > > +          pcap_statustostr(ret));
> > > > > +
> > > > > +  pcap_close(p);
> > > > > +
> > > > > +  return NULL;
> > > > > +}
> > > > >  
> > > > >  int main(int argc,char **argv, char **envp)
> > > > >  {
> > > > > @@ -692,9 +745,9 @@ int main(int argc,char **argv, char **envp)
> > > > >  
> > > > >    throttle_startup:
> > > > >    if (config.dev) {
> > > > > -    if ((device.dev_desc = pcap_open_live(config.dev, psize, 
> > > > > config.promisc, 1000, errbuf)) == NULL) {
> > > > > +    if ((device.dev_desc = do_pcap_open(config.dev, psize, 
> > > > > config.promisc, 1000, config.pcap_protocol, errbuf)) == NULL) {
> > > > >        if (!config.if_wait) {
> > > > > -        Log(LOG_ERR, "ERROR ( %s/core ): pcap_open_live(): %s\n", 
> > > > > config.name, errbuf);
> > > > > +        Log(LOG_ERR, "ERROR ( %s/core ): do_pcap_open(): %s\n", 
> > > > > config.name, errbuf);
> > > > >          exit_all(1);
> > > > >        }
> > > > >        else {
> > > > > @@ -901,7 +954,7 @@ int main(int argc,char **argv, char **envp)
> > > > >        Log(LOG_WARNING, "WARN ( %s/core ): %s has become unavailable; 
> > > > > throttling ...\n", config.name, config.dev);
> > > > >        throttle_loop:
> > > > >        sleep(5); /* XXX: user defined ? */
> > > > > -      if ((device.dev_desc = pcap_open_live(config.dev, psize, 
> > > > > config.promisc, 1000, errbuf)) == NULL)
> > > > > +      if ((device.dev_desc = do_pcap_open(config.dev, psize, 
> > > > > config.promisc, 1000, config.pcap_protocol, errbuf)) == NULL)
> > > > >          goto throttle_loop;
> > > > >        pcap_setfilter(device.dev_desc, &filter);
> > > > >        device.active = TRUE;
> > > > 
> > > > > diff --git a/Makefile.in b/Makefile.in
> > > > > index bbe470c..35f2ea4 100644
> > > > > --- a/Makefile.in
> > > > > +++ b/Makefile.in
> > > > > @@ -231,6 +231,7 @@ MAN3PCAP_NOEXPAND = \
> > > > >       pcap_set_datalink.3pcap \
> > > > >       pcap_set_immediate_mode.3pcap \
> > > > >       pcap_set_promisc.3pcap \
> > > > > +     pcap_set_protocol.3pcap \
> > > > >       pcap_set_rfmon.3pcap \
> > > > >       pcap_set_snaplen.3pcap \
> > > > >       pcap_set_timeout.3pcap \
> > > > > diff --git a/pcap-int.h b/pcap-int.h
> > > > > index 66c3d06..c6d1bfa 100644
> > > > > --- a/pcap-int.h
> > > > > +++ b/pcap-int.h
> > > > > @@ -112,6 +112,7 @@ struct pcap_opt {
> > > > >       int     timeout;        /* timeout for buffering */
> > > > >       u_int   buffer_size;
> > > > >       int     promisc;
> > > > > +     int     protocol;
> > > > >       int     rfmon;          /* monitor mode */
> > > > >       int     immediate;      /* immediate mode - deliver packets as 
> > > > > soon as they arrive */
> > > > >       int     nonblock;       /* non-blocking mode - don't wait for 
> > > > > packets to be delivered, return "no packets available" */
> > > > > diff --git a/pcap-linux.c b/pcap-linux.c
> > > > > index 179fd34..cf74a5e 100644
> > > > > --- a/pcap-linux.c
> > > > > +++ b/pcap-linux.c
> > > > > @@ -425,7 +425,7 @@ static int        iface_get_id(int fd, const char 
> > > > > *device, char *ebuf);
> > > > >  static int   iface_get_mtu(int fd, const char *device, char *ebuf);
> > > > >  static int   iface_get_arptype(int fd, const char *device, char 
> > > > > *ebuf);
> > > > >  #ifdef HAVE_PF_PACKET_SOCKETS
> > > > > -static int   iface_bind(int fd, int ifindex, char *ebuf);
> > > > > +static int   iface_bind(int fd, int ifindex, char *ebuf, int 
> > > > > protocol);
> > > > >  #ifdef IW_MODE_MONITOR
> > > > >  static int   has_wext(int sock_fd, const char *device, char *ebuf);
> > > > >  #endif /* IW_MODE_MONITOR */
> > > > > @@ -1008,6 +1008,17 @@ is_bonding_device(int fd, const char *device)
> > > > >  }
> > > > >  #endif /* IW_MODE_MONITOR */
> > > > >  
> > > > > +static int pcap_protocol(pcap_t *handle)
> > > > > +{
> > > > > +     int protocol;
> > > > > +
> > > > > +     protocol = handle->opt.protocol;
> > > > > +     if (protocol == 0)
> > > > > +             protocol = ETH_P_ALL;
> > > > > +
> > > > > +     return htons(protocol);
> > > > > +}
> > > > > +
> > > > >  static int
> > > > >  pcap_can_set_rfmon_linux(pcap_t *handle)
> > > > >  {
> > > > > @@ -1059,7 +1070,7 @@ pcap_can_set_rfmon_linux(pcap_t *handle)
> > > > >        * (We assume that if we have Wireless Extensions support
> > > > >        * we also have PF_PACKET support.)
> > > > >        */
> > > > > -     sock_fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
> > > > > +     sock_fd = socket(PF_PACKET, SOCK_RAW, pcap_protocol(handle));
> > > > >       if (sock_fd == -1) {
> > > > >               (void)pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
> > > > >                   "socket: %s", pcap_strerror(errno));
> > > > > @@ -3328,6 +3339,7 @@ activate_new(pcap_t *handle)
> > > > >       struct pcap_linux *handlep = handle->priv;
> > > > >       const char              *device = handle->opt.device;
> > > > >       int                     is_any_device = (strcmp(device, "any") 
> > > > > == 0);
> > > > > +     int                     protocol = pcap_protocol(handle);
> > > > >       int                     sock_fd = -1, arptype;
> > > > >  #ifdef HAVE_PACKET_AUXDATA
> > > > >       int                     val;
> > > > > @@ -3346,8 +3358,8 @@ activate_new(pcap_t *handle)
> > > > >        * try a SOCK_RAW socket for the raw interface.
> > > > >        */
> > > > >       sock_fd = is_any_device ?
> > > > > -             socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_ALL)) :
> > > > > -             socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
> > > > > +             socket(PF_PACKET, SOCK_DGRAM, protocol) :
> > > > > +             socket(PF_PACKET, SOCK_RAW, protocol);
> > > > >  
> > > > >       if (sock_fd == -1) {
> > > > >               if (errno == EINVAL || errno == EAFNOSUPPORT) {
> > > > > @@ -3464,8 +3476,7 @@ activate_new(pcap_t *handle)
> > > > >                                        "close: %s", 
> > > > > pcap_strerror(errno));
> > > > >                               return PCAP_ERROR;
> > > > >                       }
> > > > > -                     sock_fd = socket(PF_PACKET, SOCK_DGRAM,
> > > > > -                         htons(ETH_P_ALL));
> > > > > +                     sock_fd = socket(PF_PACKET, SOCK_DGRAM, 
> > > > > protocol);
> > > > >                       if (sock_fd == -1) {
> > > > >                               pcap_snprintf(handle->errbuf, 
> > > > > PCAP_ERRBUF_SIZE,
> > > > >                                   "socket: %s", pcap_strerror(errno));
> > > > > @@ -3529,7 +3540,7 @@ activate_new(pcap_t *handle)
> > > > >               }
> > > > >  
> > > > >               if ((err = iface_bind(sock_fd, handlep->ifindex,
> > > > > -                 handle->errbuf)) != 1) {
> > > > > +                 handle->errbuf, handle->opt.protocol)) != 1) {
> > > > >                       close(sock_fd);
> > > > >                       if (err < 0)
> > > > >                               return err;
> > > > > @@ -5310,7 +5321,7 @@ iface_get_id(int fd, const char *device, char 
> > > > > *ebuf)
> > > > >   *  or a PCAP_ERROR_ value on a hard error.
> > > > >   */
> > > > >  static int
> > > > > -iface_bind(int fd, int ifindex, char *ebuf)
> > > > > +iface_bind(int fd, int ifindex, char *ebuf, int protocol)
> > > > >  {
> > > > >       struct sockaddr_ll      sll;
> > > > >       int                     err;
> > > > > @@ -5319,7 +5330,7 @@ iface_bind(int fd, int ifindex, char *ebuf)
> > > > >       memset(&sll, 0, sizeof(sll));
> > > > >       sll.sll_family          = AF_PACKET;
> > > > >       sll.sll_ifindex         = ifindex;
> > > > > -     sll.sll_protocol        = htons(ETH_P_ALL);
> > > > > +     sll.sll_protocol        = htons(protocol ? : ETH_P_ALL);
> > > > >  
> > > > >       if (bind(fd, (struct sockaddr *) &sll, sizeof(sll)) == -1) {
> > > > >               if (errno == ENETDOWN) {
> > > > > diff --git a/pcap.3pcap.in b/pcap.3pcap.in
> > > > > index 544e79c..9a53ee4 100644
> > > > > --- a/pcap.3pcap.in
> > > > > +++ b/pcap.3pcap.in
> > > > > @@ -394,6 +394,11 @@ set promiscuous mode for a not-yet-activated
> > > > >  .B pcap_t
> > > > >  for live capture
> > > > >  .TP
> > > > > +.BR pcap_set_protocol (3PCAP)
> > > > > +set capture protocol for a not-yet-activated
> > > > > +.B pcap_t
> > > > > +for live capture
> > > > > +.TP
> > > > >  .BR pcap_set_rfmon (3PCAP)
> > > > >  set monitor mode for a not-yet-activated
> > > > >  .B pcap_t
> > > > > diff --git a/pcap.c b/pcap.c
> > > > > index bb5e648..b25b7db 100644
> > > > > --- a/pcap.c
> > > > > +++ b/pcap.c
> > > > > @@ -1338,6 +1338,7 @@ pcap_create_common(char *ebuf, size_t size)
> > > > >       p->opt.timeout = 0;             /* no timeout specified */
> > > > >       p->opt.buffer_size = 0;         /* use the platform's default */
> > > > >       p->opt.promisc = 0;
> > > > > +     p->opt.protocol = 0;
> > > > >       p->opt.rfmon = 0;
> > > > >       p->opt.immediate = 0;
> > > > >       p->opt.tstamp_type = -1;        /* default to not setting time 
> > > > > stamp type */
> > > > > @@ -1381,6 +1382,15 @@ pcap_set_promisc(pcap_t *p, int promisc)
> > > > >  }
> > > > >  
> > > > >  int
> > > > > +pcap_set_protocol(pcap_t *p, int protocol)
> > > > > +{
> > > > > +     if (pcap_check_activated(p))
> > > > > +             return (PCAP_ERROR_ACTIVATED);
> > > > > +     p->opt.protocol = protocol;
> > > > > +     return (0);
> > > > > +}
> > > > > +
> > > > > +int
> > > > >  pcap_set_rfmon(pcap_t *p, int rfmon)
> > > > >  {
> > > > >       if (pcap_check_activated(p))
> > > > > diff --git a/pcap/pcap.h b/pcap/pcap.h
> > > > > index adff853..76ecec4 100644
> > > > > --- a/pcap/pcap.h
> > > > > +++ b/pcap/pcap.h
> > > > > @@ -315,6 +315,7 @@ PCAP_API int      pcap_lookupnet(const char *, 
> > > > > bpf_u_int32 *, bpf_u_int32 *, char *);
> > > > >  PCAP_API pcap_t      *pcap_create(const char *, char *);
> > > > >  PCAP_API int pcap_set_snaplen(pcap_t *, int);
> > > > >  PCAP_API int pcap_set_promisc(pcap_t *, int);
> > > > > +PCAP_API int pcap_set_protocol(pcap_t *, int);
> > > > >  PCAP_API int pcap_can_set_rfmon(pcap_t *);
> > > > >  PCAP_API int pcap_set_rfmon(pcap_t *, int);
> > > > >  PCAP_API int pcap_set_timeout(pcap_t *, int);
> > > > > diff --git a/pcap_set_protocol.3pcap b/pcap_set_protocol.3pcap
> > > > > new file mode 100644
> > > > > index 0000000..b9acf16
> > > > > --- /dev/null
> > > > > +++ b/pcap_set_protocol.3pcap
> > > > > @@ -0,0 +1,47 @@
> > > > > +.\" Copyright (c) 1994, 1996, 1997
> > > > > +.\"  The Regents of the University of California.  All rights 
> > > > > reserved.
> > > > > +.\"
> > > > > +.\" Redistribution and use in source and binary forms, with or 
> > > > > without
> > > > > +.\" modification, are permitted provided that: (1) source code 
> > > > > distributions
> > > > > +.\" retain the above copyright notice and this paragraph in its 
> > > > > entirety, (2)
> > > > > +.\" distributions including binary code include the above copyright 
> > > > > notice and
> > > > > +.\" this paragraph in its entirety in the documentation or other 
> > > > > materials
> > > > > +.\" provided with the distribution, and (3) all advertising 
> > > > > materials mentioning
> > > > > +.\" features or use of this software display the following 
> > > > > acknowledgement:
> > > > > +.\" ``This product includes software developed by the University of 
> > > > > California,
> > > > > +.\" Lawrence Berkeley Laboratory and its contributors.'' Neither the 
> > > > > name of
> > > > > +.\" the University nor the names of its contributors may be used to 
> > > > > endorse
> > > > > +.\" or promote products derived from this software without specific 
> > > > > prior
> > > > > +.\" written permission.
> > > > > +.\" THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 
> > > > > IMPLIED
> > > > > +.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 
> > > > > WARRANTIES OF
> > > > > +.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
> > > > > +.\"
> > > > > +.TH PCAP_SET_PROTOCOL 3PCAP "3 January 2014"
> > > > > +.SH NAME
> > > > > +pcap_set_protocol \- set capture protocol for a not-yet-activated
> > > > > +capture handle
> > > > > +.SH SYNOPSIS
> > > > > +.nf
> > > > > +.ft B
> > > > > +#include <pcap/pcap.h>
> > > > > +.LP
> > > > > +.ft B
> > > > > +int pcap_set_protocol(pcap_t *p, int protocol);
> > > > > +.ft
> > > > > +.fi
> > > > > +.SH DESCRIPTION
> > > > > +.B pcap_set_protocol()
> > > > > +sets the capture protocol to use on a capture handle when the handle
> > > > > +is activated.
> > > > > +If
> > > > > +.I protocol
> > > > > +is non-zero, packets of that protocol will be captured when the
> > > > > +handle is activated, otherwise, all packets will be captured.
> > > > > +.SH RETURN VALUE
> > > > > +.B pcap_set_protocol()
> > > > > +returns 0 on success or
> > > > > +.B PCAP_ERROR_ACTIVATED
> > > > > +if called on a capture handle that has been activated.
> > > > > +.SH SEE ALSO
> > > > > +pcap(3PCAP), pcap_create(3PCAP), pcap_activate(3PCAP)
> > > > 
> > > > > _______________________________________________
> > > > > pmacct-discussion mailing list
> > > > > http://www.pmacct.net/#mailinglists
> > > > 
> > > > 
> > > > _______________________________________________
> > > > pmacct-discussion mailing list
> > > > http://www.pmacct.net/#mailinglists
> > > 
> > > _______________________________________________
> > > pmacct-discussion mailing list
> > > http://www.pmacct.net/#mailinglists

_______________________________________________
pmacct-discussion mailing list
http://www.pmacct.net/#mailinglists

Reply via email to