diff options
| author | Xin LI <delphij@FreeBSD.org> | 2017-02-12 07:04:44 +0000 | 
|---|---|---|
| committer | Xin LI <delphij@FreeBSD.org> | 2017-02-12 07:04:44 +0000 | 
| commit | c8c6d70e300aa9261c4766502c179fc4cd2b22a0 (patch) | |
| tree | 14c068bb8b49db9f9ae540e8e2be80a9035e403a /pcap-dos.c | |
| parent | 50224b10fa4e157f09ee1cd03c790c9e61e76c5e (diff) | |
Diffstat (limited to 'pcap-dos.c')
| -rw-r--r-- | pcap-dos.c | 136 | 
1 files changed, 76 insertions, 60 deletions
| diff --git a/pcap-dos.c b/pcap-dos.c index 43f50c7f13b2..ea6b225a23ef 100644 --- a/pcap-dos.c +++ b/pcap-dos.c @@ -1,6 +1,6 @@  /*   *  This file is part of DOS-libpcap - *  Ported to DOS/DOSX by G. Vanem <gvanem@broadpark.no> + *  Ported to DOS/DOSX by G. Vanem <gvanem@yahoo.no>   *   *  pcap-dos.c: Interface to PKTDRVR, NDIS2 and 32-bit pmode   *              network drivers. @@ -145,15 +145,15 @@ static struct device *get_device (int fd)   * Private data for capturing on MS-DOS.   */  struct pcap_dos { -	void (*wait_proc)(void); /*          call proc while waiting */ +	void (*wait_proc)(void); /* call proc while waiting */  	struct pcap_stat stat;  }; -pcap_t *pcap_create_interface (const char *device, char *ebuf) +pcap_t *pcap_create_interface (const char *device _U_, char *ebuf)  {  	pcap_t *p; -	p = pcap_create_common(device, ebuf, sizeof (struct pcap_dos)); +	p = pcap_create_common(ebuf, sizeof (struct pcap_dos));  	if (p == NULL)  		return (NULL); @@ -166,9 +166,7 @@ pcap_t *pcap_create_interface (const char *device, char *ebuf)   * network packets.   */  static int pcap_activate_dos (pcap_t *pcap) -{  -  struct pcap_dos *pcapd = pcap->priv; - +{    if (pcap->opt.rfmon) {      /*       * No monitor mode on DOS. @@ -188,23 +186,26 @@ static int pcap_activate_dos (pcap_t *pcap)    pcap->stats_op          = pcap_stats_dos;    pcap->inject_op         = pcap_sendpacket_dos;    pcap->setfilter_op      = pcap_setfilter_dos; -  pcap->setdirection_op   = NULL; /* Not implemented.*/ +  pcap->setdirection_op   = NULL;  /* Not implemented.*/    pcap->fd                = ++ref_count; +  pcap->bufsize = ETH_MAX+100;     /* add some margin */ +  pcap->buffer = calloc (pcap->bufsize, 1); +    if (pcap->fd == 1)  /* first time we're called */    { -    if (!init_watt32(pcap, pcap->opt.source, pcap->errbuf) || -        !first_init(pcap->opt.source, pcap->errbuf, pcap->opt.promisc)) +    if (!init_watt32(pcap, pcap->opt.device, pcap->errbuf) || +        !first_init(pcap->opt.device, pcap->errbuf, pcap->opt.promisc))      {        return (PCAP_ERROR); -    }  +    }      atexit (close_driver);    } -  else if (stricmp(active_dev->name,pcap->opt.source)) +  else if (stricmp(active_dev->name,pcap->opt.device))    { -    snprintf (pcap->errbuf, PCAP_ERRBUF_SIZE, -              "Cannot use different devices simultaneously " -              "(`%s' vs. `%s')", active_dev->name, pcap->opt.source); +    pcap_snprintf (pcap->errbuf, PCAP_ERRBUF_SIZE, +                   "Cannot use different devices simultaneously " +                   "(`%s' vs. `%s')", active_dev->name, pcap->opt.device);      return (PCAP_ERROR);    }    handle_to_device [pcap->fd-1] = active_dev; @@ -221,7 +222,6 @@ pcap_read_one (pcap_t *p, pcap_handler callback, u_char *data)    struct pcap_dos *pd = p->priv;    struct pcap_pkthdr pcap;    struct timeval     now, expiry = { 0,0 }; -  BYTE  *rx_buf;    int    rx_len = 0;    if (p->opt.timeout > 0) @@ -253,13 +253,11 @@ pcap_read_one (pcap_t *p, pcap_handler callback, u_char *data)      if (dev->peek_rx_buf)      {        PCAP_ASSERT (dev->release_rx_buf); -      rx_len = (*dev->peek_rx_buf) (&rx_buf); +      rx_len = (*dev->peek_rx_buf) (&p->buffer);      }      else      { -      BYTE buf [ETH_MAX+100]; /* add some margin */ -      rx_len = (*dev->copy_rx_buf) (buf, p->snapshot); -      rx_buf = buf; +      rx_len = (*dev->copy_rx_buf) (p->buffer, p->snapshot);      }      if (rx_len > 0)  /* got a packet */ @@ -272,7 +270,7 @@ pcap_read_one (pcap_t *p, pcap_handler callback, u_char *data)        pcap.len    = rx_len;        if (callback && -          (!p->fcode.bf_insns || bpf_filter(p->fcode.bf_insns, rx_buf, pcap.len, pcap.caplen))) +          (!p->fcode.bf_insns || bpf_filter(p->fcode.bf_insns, p->buffer, pcap.len, pcap.caplen)))        {          filter_count++; @@ -280,11 +278,11 @@ pcap_read_one (pcap_t *p, pcap_handler callback, u_char *data)           * capture.           */          gettimeofday2 (&pcap.ts, NULL); -        (*callback) (data, &pcap, rx_buf); +        (*callback) (data, &pcap, p->buffer);        }        if (dev->release_rx_buf) -        (*dev->release_rx_buf) (rx_buf); +        (*dev->release_rx_buf) (p->buffer);        if (pcap_pkt_debug > 0)        { @@ -296,6 +294,18 @@ pcap_read_one (pcap_t *p, pcap_handler callback, u_char *data)        return (1);      } +    /* Has "pcap_breakloop()" been called? +     */ +    if (p->break_loop) { +      /* +       * Yes - clear the flag that indicates that it +       * has, and return -2 to indicate that we were +       * told to break out of the loop. +       */ +      p->break_loop = 0; +      return (-2); +    } +      /* If not to wait for a packet or pcap_cleanup_dos() called from       * e.g. SIGINT handler, exit loop now.       */ @@ -311,8 +321,8 @@ pcap_read_one (pcap_t *p, pcap_handler callback, u_char *data)      kbhit();    /* a real CPU hog */  #endif -    if (p->wait_proc) -      (*p->wait_proc)();     /* call yield func */ +    if (pd->wait_proc) +      (*pd->wait_proc)();     /* call yield func */    }    if (rx_len < 0)            /* receive error */ @@ -330,7 +340,6 @@ pcap_read_one (pcap_t *p, pcap_handler callback, u_char *data)  static int  pcap_read_dos (pcap_t *p, int cnt, pcap_handler callback, u_char *data)  { -  struct pcap_dos *pd = p->priv;    int rc, num = 0;    while (num <= cnt || PACKET_COUNT_IS_UNLIMITED(cnt)) @@ -401,7 +410,7 @@ int pcap_stats_ex (pcap_t *p, struct pcap_stat_ex *se)      strlcpy (p->errbuf, "pktdrvr doesn't have detailed statistics",               PCAP_ERRBUF_SIZE);      return (-1); -  }              +  }    memcpy (se, (*dev->get_stats)(dev), sizeof(*se));    return (0);  } @@ -442,7 +451,7 @@ static void pcap_cleanup_dos (pcap_t *p)  {    struct pcap_dos *pd; -  if (p && !exc_occured) +  if (!exc_occured)    {      pd = p->priv;      if (pcap_stats(p,NULL) < 0) @@ -495,6 +504,8 @@ char *pcap_lookupdev (char *ebuf)  int pcap_lookupnet (const char *device, bpf_u_int32 *localnet,                      bpf_u_int32 *netmask, char *errbuf)  { +  DWORD mask, net; +    if (!_watt_is_init)    {      strcpy (errbuf, "pcap_open_offline() or pcap_activate() must be " @@ -502,40 +513,43 @@ int pcap_lookupnet (const char *device, bpf_u_int32 *localnet,      return (-1);    } -  *netmask  = _w32_sin_mask; -  *localnet = my_ip_addr & *netmask; -  if (*localnet == 0) +  mask  = _w32_sin_mask; +  net = my_ip_addr & mask; +  if (net == 0)    {      if (IN_CLASSA(*netmask)) -       *localnet = IN_CLASSA_NET; +       net = IN_CLASSA_NET;      else if (IN_CLASSB(*netmask)) -       *localnet = IN_CLASSB_NET; +       net = IN_CLASSB_NET;      else if (IN_CLASSC(*netmask)) -       *localnet = IN_CLASSC_NET; +       net = IN_CLASSC_NET;      else      { -      sprintf (errbuf, "inet class for 0x%lx unknown", *netmask); +      pcap_snprintf (errbuf, PCAP_ERRBUF_SIZE, "inet class for 0x%lx unknown", mask);        return (-1);      }    } +  *localnet = htonl (net); +  *netmask = htonl (mask); +    ARGSUSED (device);    return (0); -}       +}  /*   * Get a list of all interfaces that are present and that we probe okay.   * Returns -1 on error, 0 otherwise. - * The list, as returned through "alldevsp", may be null if no interfaces + * The list, as returned through "alldevsp", may be NULL if no interfaces   * were up and could be opened.   */ -int pcap_findalldevs (pcap_if_t **alldevsp, char *errbuf) +int pcap_platform_finddevs  (pcap_if_t **alldevsp, char *errbuf)  {    struct device     *dev; -  struct sockaddr_ll sa_ll_1, sa_ll_2; +  struct sockaddr_in sa_ll_1, sa_ll_2;    struct sockaddr   *addr, *netmask, *broadaddr, *dstaddr;    pcap_if_t *devlist = NULL;    int       ret = 0; -  size_t    addr_size = sizeof(struct sockaddr_ll); +  size_t    addr_size = sizeof(*addr);    for (dev = (struct device*)dev_base; dev; dev = dev->next)    { @@ -550,14 +564,14 @@ int pcap_findalldevs (pcap_if_t **alldevsp, char *errbuf)      memset (&sa_ll_1, 0, sizeof(sa_ll_1));      memset (&sa_ll_2, 0, sizeof(sa_ll_2)); -    sa_ll_1.sll_family = AF_PACKET; -    sa_ll_2.sll_family = AF_PACKET; +    sa_ll_1.sin_family = AF_INET; +    sa_ll_2.sin_family = AF_INET;      addr      = (struct sockaddr*) &sa_ll_1;      netmask   = (struct sockaddr*) &sa_ll_1;      dstaddr   = (struct sockaddr*) &sa_ll_1;      broadaddr = (struct sockaddr*) &sa_ll_2; -    memset (&sa_ll_2.sll_addr, 0xFF, sizeof(sa_ll_2.sll_addr)); +    memset (&sa_ll_2.sin_addr, 0xFF, sizeof(sa_ll_2.sin_addr));      if (pcap_add_if(&devlist, dev->name, dev->flags,                      dev->long_name, errbuf) < 0) @@ -565,13 +579,15 @@ int pcap_findalldevs (pcap_if_t **alldevsp, char *errbuf)        ret = -1;        break;      } -    if (add_addr_to_iflist(&devlist,dev->name, dev->flags, addr, addr_size, +#if 0   /* Pkt drivers should have no addresses */ +    if (add_addr_to_iflist(&devlist, dev->name, dev->flags, addr, addr_size,                             netmask, addr_size, broadaddr, addr_size,                             dstaddr, addr_size, errbuf) < 0)      {        ret = -1;        break;      } +#endif    }    if (devlist && ret < 0) @@ -605,12 +621,12 @@ void pcap_assert (const char *what, const char *file, unsigned line)   */  void pcap_set_wait (pcap_t *p, void (*yield)(void), int wait)  { -  struct pcap_dos *pd;    if (p)    { -    pd                   = p->priv; -    pd->wait_proc        = yield; -    p->opt.timeout        = wait; +    struct pcap_dos *pd = p->priv; + +    pd->wait_proc  = yield; +    p->opt.timeout = wait;    }  } @@ -635,7 +651,7 @@ open_driver (const char *dev_name, char *ebuf, int promisc)        if (!(*dev->probe)(dev))    /* call the xx_probe() function */        { -        sprintf (ebuf, "failed to detect device `%s'", dev_name); +        pcap_snprintf (ebuf, PCAP_ERRBUF_SIZE, "failed to detect device `%s'", dev_name);          return (NULL);        }        probed_dev = dev;  /* device is probed okay and may be used */ @@ -657,7 +673,7 @@ open_driver (const char *dev_name, char *ebuf, int promisc)      if (!(*dev->open)(dev))      { -      sprintf (ebuf, "failed to activate device `%s'", dev_name); +      pcap_snprintf (ebuf, PCAP_ERRBUF_SIZE, "failed to activate device `%s'", dev_name);        if (pktInfo.error && !strncmp(dev->name,"pkt",3))        {          strcat (ebuf, ": "); @@ -679,14 +695,14 @@ open_driver (const char *dev_name, char *ebuf, int promisc)     */    if (!dev)    { -    sprintf (ebuf, "device `%s' not supported", dev_name); +    pcap_snprintf (ebuf, PCAP_ERRBUF_SIZE, "device `%s' not supported", dev_name);      return (NULL);    }  not_probed:    if (!probed_dev)    { -    sprintf (ebuf, "device `%s' not probed", dev_name); +    pcap_snprintf (ebuf, PCAP_ERRBUF_SIZE, "device `%s' not probed", dev_name);      return (NULL);    }    return (dev); @@ -756,7 +772,7 @@ static void exc_handler (int sig)           fprintf (stderr, "Catching signal %d.\n", sig);    }    exc_occured = 1; -  pcap_cleanup_dos (NULL); +  close_driver();  }  #endif  /* __DJGPP__ */ @@ -933,7 +949,7 @@ static int init_watt32 (struct pcap *pcap, const char *dev_name, char *err_buf)    if (_watt_is_init)       sock_exit(); -  env = getenv ("PCAP_DEBUG"); +  env = getenv ("PCAP_TRACE");    if (env && atoi(env) > 0 &&        pcap_pkt_debug < 0)   /* if not already set */    { @@ -960,7 +976,7 @@ static int init_watt32 (struct pcap *pcap, const char *dev_name, char *err_buf)     *            have default values. Should be taken from another     *            ini-file/environment in any case (ref. tcpdump.ini)     */ -  _watt_is_init = 1;   +  _watt_is_init = 1;    if (!using_pktdrv || !has_ip_addr)  /* for now .... */    { @@ -973,7 +989,7 @@ static int init_watt32 (struct pcap *pcap, const char *dev_name, char *err_buf)    }    else if (rc && using_pktdrv)    { -    sprintf (err_buf, "sock_init() failed, code %d", rc); +    pcap_snprintf (err_buf, PCAP_ERRBUF_SIZE, "sock_init() failed, code %d", rc);      return (0);    } @@ -1053,9 +1069,9 @@ static const struct config_table debug_tab[] = {   * pcap_config_hook() is an extension to application's config   * handling. Uses Watt-32's config-table function.   */ -int pcap_config_hook (const char *name, const char *value) +int pcap_config_hook (const char *keyword, const char *value)  { -  return parse_config_table (debug_tab, NULL, name, value); +  return parse_config_table (debug_tab, NULL, keyword, value);  }  /* @@ -1092,7 +1108,7 @@ static int pkt_open (struct device *dev)    if (!PktInitDriver(mode))       return (0); -  +    PktResetStatistics (pktInfo.handle);    PktQueueBusy (FALSE);    return (1); @@ -1290,7 +1306,7 @@ struct device rtl8139_dev LOCKED_VAR = {                0,0,0,0,0,0,                &cs89_dev,                rtl8139_probe     /* dev->probe routine */ -            };             +            };  /*   * Dequeue routine is called by polling. | 
