diff options
Diffstat (limited to 'pcap-dos.c')
-rw-r--r-- | pcap-dos.c | 200 |
1 files changed, 120 insertions, 80 deletions
@@ -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. @@ -176,6 +174,17 @@ static int pcap_activate_dos (pcap_t *pcap) return (PCAP_ERROR_RFMON_NOTSUP); } + /* + * Turn a negative snapshot value (invalid), a snapshot value of + * 0 (unspecified), or a value bigger than the normal maximum + * value, into the maximum allowed value. + * + * If some application really *needs* a bigger snapshot + * length, we should just increase MAXIMUM_SNAPLEN. + */ + if (pcap->snapshot <= 0 || pcap->snapshot > MAXIMUM_SNAPLEN) + pcap->snapshot = MAXIMUM_SNAPLEN; + if (pcap->snapshot < ETH_MIN+8) pcap->snapshot = ETH_MIN+8; @@ -188,23 +197,28 @@ 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)) { + /* XXX - free pcap->buffer? */ 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); + /* XXX - free pcap->buffer? */ return (PCAP_ERROR); } handle_to_device [pcap->fd-1] = active_dev; @@ -221,7 +235,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 +266,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 +283,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 +291,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 +307,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 +334,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 +353,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)) @@ -391,17 +413,17 @@ int pcap_stats_ex (pcap_t *p, struct pcap_stat_ex *se) if (!dev || !dev->get_stats) { - strlcpy (p->errbuf, "detailed device statistics not available", + pcap_strlcpy (p->errbuf, "detailed device statistics not available", PCAP_ERRBUF_SIZE); return (-1); } if (!strnicmp(dev->name,"pkt",3)) { - strlcpy (p->errbuf, "pktdrvr doesn't have detailed statistics", + pcap_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 +464,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) @@ -458,6 +480,7 @@ static void pcap_cleanup_dos (pcap_t *p) return; } close_driver(); + /* XXX - call pcap_cleanup_live_common? */ } /* @@ -495,6 +518,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 +527,44 @@ 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 - * were up and could be opened. + * The list may be NULL epty if no interfaces were up and could be opened. */ -int pcap_findalldevs (pcap_if_t **alldevsp, char *errbuf) +int pcap_platform_finddevs (pcap_if_list_t *devlistp, char *errbuf) { struct device *dev; - struct sockaddr_ll sa_ll_1, sa_ll_2; + pcap_if_t *curdev; +#if 0 /* Pkt drivers should have no addresses */ + struct sockaddr_in sa_ll_1, sa_ll_2; struct sockaddr *addr, *netmask, *broadaddr, *dstaddr; - pcap_if_t *devlist = NULL; +#endif int ret = 0; - size_t addr_size = sizeof(struct sockaddr_ll); + int found = 0; for (dev = (struct device*)dev_base; dev; dev = dev->next) { @@ -548,42 +577,45 @@ int pcap_findalldevs (pcap_if_t **alldevsp, char *errbuf) FLUSHK(); (*dev->close) (dev); + /* + * XXX - find out whether it's up or running? Does that apply here? + * Can we find out if anything's plugged into the adapter, if it's + * a wired device, and set PCAP_IF_CONNECTION_STATUS_CONNECTED + * or PCAP_IF_CONNECTION_STATUS_DISCONNECTED? + */ + if ((curdev = add_dev(devlistp, dev->name, 0, + dev->long_name, errbuf)) == NULL) + { + ret = -1; + break; + } + found = 1; +#if 0 /* Pkt drivers should have no addresses */ 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) - { - ret = -1; - break; - } - if (add_addr_to_iflist(&devlist,dev->name, dev->flags, addr, addr_size, - netmask, addr_size, broadaddr, addr_size, - dstaddr, addr_size, errbuf) < 0) + if (add_addr_to_dev(curdev, addr, sizeof(*addr), + netmask, sizeof(*netmask), + broadaddr, sizeof(*broadaddr), + dstaddr, sizeof(*dstaddr), errbuf) < 0) { ret = -1; break; } +#endif } - if (devlist && ret < 0) - { - pcap_freealldevs (devlist); - devlist = NULL; - } - else - if (!devlist) + if (ret == 0 && !found) strcpy (errbuf, "No drivers found"); - *alldevsp = devlist; return (ret); } @@ -605,12 +637,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 +667,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 +689,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 +711,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 +788,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 +965,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 +992,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 +1005,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 +1085,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 +1124,7 @@ static int pkt_open (struct device *dev) if (!PktInitDriver(mode)) return (0); - + PktResetStatistics (pktInfo.handle); PktQueueBusy (FALSE); return (1); @@ -1290,7 +1322,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. @@ -1494,3 +1526,11 @@ static void pktq_clear (struct rx_ringbuf *q) #endif /* USE_32BIT_DRIVERS */ +/* + * Libpcap version string. + */ +const char * +pcap_lib_version(void) +{ + return ("DOS-" PCAP_VERSION_STRING); +} |