📄 pcap-dos.c
字号:
else if (IN_CLASSC(*netmask)) *localnet = IN_CLASSC_NET; else { sprintf (errbuf, "inet class for 0x%lx unknown", *netmask); return (-1); } } 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. */int pcap_findalldevs (pcap_if_t **alldevsp, char *errbuf){ struct device *dev; struct sockaddr_ll 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); for (dev = (struct device*)dev_base; dev; dev = dev->next) { PCAP_ASSERT (dev->probe); if (!(*dev->probe)(dev)) continue; PCAP_ASSERT (dev->close); /* set by probe routine */ FLUSHK(); (*dev->close) (dev); 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; 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)); 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) { ret = -1; break; } } if (devlist && ret < 0) { pcap_freealldevs (devlist); devlist = NULL; } else if (!devlist) strcpy (errbuf, "No drivers found"); *alldevsp = devlist; return (ret);}/* * pcap_assert() is mainly used for debugging */void pcap_assert (const char *what, const char *file, unsigned line){ FLUSHK(); fprintf (stderr, "%s (%u): Assertion \"%s\" failed\n", file, line, what); close_driver(); _exit (-1);}/* * For pcap_offline_read(): wait and yield between printing packets * to simulate the pace packets where actually recorded. */void pcap_set_wait (pcap_t *p, void (*yield)(void), int wait){ if (p) { p->wait_proc = yield; p->inter_packet_wait = wait; }}/* * Initialise a named network device. */static struct device *open_driver (const char *dev_name, char *ebuf, int promisc){ struct device *dev; for (dev = (struct device*)dev_base; dev; dev = dev->next) { PCAP_ASSERT (dev->name); if (strcmp (dev_name,dev->name)) continue; if (!probed_dev) /* user didn't call pcap_lookupdev() first */ { PCAP_ASSERT (dev->probe); if (!(*dev->probe)(dev)) /* call the xx_probe() function */ { sprintf (ebuf, "failed to detect device `%s'", dev_name); return (NULL); } probed_dev = dev; /* device is probed okay and may be used */ } else if (dev != probed_dev) { goto not_probed; } FLUSHK(); /* Select what traffic to receive */ if (promisc) dev->flags |= (IFF_ALLMULTI | IFF_PROMISC); else dev->flags &= ~(IFF_ALLMULTI | IFF_PROMISC); PCAP_ASSERT (dev->open); if (!(*dev->open)(dev)) { sprintf (ebuf, "failed to activate device `%s'", dev_name); if (pktInfo.error && !strncmp(dev->name,"pkt",3)) { strcat (ebuf, ": "); strcat (ebuf, pktInfo.error); } return (NULL); } /* Some devices need this to operate in promiscous mode */ if (promisc && dev->set_multicast_list) (*dev->set_multicast_list) (dev); active_dev = dev; /* remember our active device */ break; } /* 'dev_name' not matched in 'dev_base' list. */ if (!dev) { sprintf (ebuf, "device `%s' not supported", dev_name); return (NULL); }not_probed: if (!probed_dev) { sprintf (ebuf, "device `%s' not probed", dev_name); return (NULL); } return (dev);}/* * Deinitialise MAC driver. * Set receive mode back to default mode. */static void close_driver (void){ /* !!todo: loop over all 'handle_to_device[]' ? */ struct device *dev = active_dev; if (dev && dev->close) { (*dev->close) (dev); FLUSHK(); } active_dev = NULL;#ifdef USE_32BIT_DRIVERS if (rx_pool) { k_free (rx_pool); rx_pool = NULL; } if (dev) pcibios_exit();#endif}#ifdef __DJGPP__static void setup_signals (void (*handler)(int)){ signal (SIGSEGV,handler); signal (SIGILL, handler); signal (SIGFPE, handler);}static void exc_handler (int sig){#ifdef USE_32BIT_DRIVERS if (active_dev->irq > 0) /* excludes IRQ 0 */ { disable_irq (active_dev->irq); irq_eoi_cmd (active_dev->irq); _printk_safe = 1; }#endif switch (sig) { case SIGSEGV: fputs ("Catching SIGSEGV.\n", stderr); break; case SIGILL: fputs ("Catching SIGILL.\n", stderr); break; case SIGFPE: _fpreset(); fputs ("Catching SIGFPE.\n", stderr); break; default: fprintf (stderr, "Catching signal %d.\n", sig); } exc_occured = 1; pcap_close_dos (NULL);}#endif /* __DJGPP__ *//* * Open the pcap device for the first client calling pcap_open_live() */static int first_init (const char *name, char *ebuf, int promisc){ struct device *dev;#ifdef USE_32BIT_DRIVERS rx_pool = k_calloc (RECEIVE_BUF_SIZE, RECEIVE_QUEUE_SIZE); if (!rx_pool) { strcpy (ebuf, "Not enough memory (Rx pool)"); return (0); }#endif#ifdef __DJGPP__ setup_signals (exc_handler);#endif#ifdef USE_32BIT_DRIVERS init_32bit();#endif dev = open_driver (name, ebuf, promisc); if (!dev) {#ifdef USE_32BIT_DRIVERS k_free (rx_pool); rx_pool = NULL;#endif#ifdef __DJGPP__ setup_signals (SIG_DFL);#endif return (0); }#ifdef USE_32BIT_DRIVERS /* * If driver is NOT a 16-bit "pkt/ndis" driver (having a 'copy_rx_buf' * set in it's probe handler), initialise near-memory ring-buffer for * the 32-bit device. */ if (dev->copy_rx_buf == NULL) { dev->get_rx_buf = get_rxbuf; dev->peek_rx_buf = peek_rxbuf; dev->release_rx_buf = release_rxbuf; pktq_init (&dev->queue, RECEIVE_BUF_SIZE, RECEIVE_QUEUE_SIZE, rx_pool); }#endif return (1);}#ifdef USE_32BIT_DRIVERSstatic void init_32bit (void){ static int init_pci = 0; if (!_printk_file) _printk_init (64*1024, NULL); /* calls atexit(printk_exit) */ if (!init_pci) (void)pci_init(); /* init BIOS32+PCI interface */ init_pci = 1;}#endif/* * Hook functions for using Watt-32 together with pcap */static char rxbuf [ETH_MAX+100]; /* rx-buffer with some margin */static WORD etype;static pcap_t pcap_save;static void watt32_recv_hook (u_char *dummy, const struct pcap_pkthdr *pcap, const u_char *buf){ /* Fix me: assumes Ethernet II only */ struct ether_header *ep = (struct ether_header*) buf; memcpy (rxbuf, buf, pcap->caplen); etype = ep->ether_type; ARGSUSED (dummy);}#if (WATTCP_VER >= 0x0224)/* * This function is used by Watt-32 to poll for a packet. * i.e. it's set to bypass _eth_arrived() */static void *pcap_recv_hook (WORD *type){ int len = pcap_read_dos (&pcap_save, 1, watt32_recv_hook, NULL); if (len < 0) return (NULL); *type = etype; return (void*) &rxbuf;}/* * This function is called by Watt-32 (via _eth_xmit_hook). * If dbug_init() was called, we should trace packets sent. */static int pcap_xmit_hook (const void *buf, unsigned len){ int rc = 0; if (pcap_pkt_debug > 0) dbug_write ("pcap_xmit_hook: "); if (active_dev && active_dev->xmit) if ((*active_dev->xmit) (active_dev, buf, len) > 0) rc = len; if (pcap_pkt_debug > 0) dbug_write (rc ? "ok\n" : "fail\n"); return (rc);}#endifstatic int pcap_sendpacket_dos (pcap_t *p, const void *buf, size_t len){ struct device *dev = p ? get_device(p->fd) : NULL; if (!dev || !dev->xmit) return (-1); return (*dev->xmit) (dev, buf, len);}/* * This function is called by Watt-32 in tcp_post_init(). * We should prevent Watt-32 from using BOOTP/DHCP/RARP etc. */static void (*prev_post_hook) (void);static void pcap_init_hook (void){ _w32__bootp_on = _w32__dhcp_on = _w32__rarp_on = 0; _w32__do_mask_req = 0; _w32_dynamic_host = 0; if (prev_post_hook) (*prev_post_hook)();}/* * Supress PRINT message from Watt-32's sock_init() */static void null_print (void) {}/* * To use features of Watt-32 (netdb functions and socket etc.) * we must call sock_init(). But we set various hooks to prevent * using normal PKTDRVR functions in pcpkt.c. This should hopefully * make Watt-32 and pcap co-operate. */static int init_watt32 (struct pcap *pcap, const char *dev_name, char *err_buf){ char *env; int rc, MTU, has_ip_addr; int using_pktdrv = 1; /* If user called sock_init() first, we need to reinit in * order to open debug/trace-file properly */ if (_watt_is_init) sock_exit(); env = getenv ("PCAP_DEBUG"); if (env && atoi(env) > 0 && pcap_pkt_debug < 0) /* if not already set */ { dbug_init(); pcap_pkt_debug = atoi (env); } _watt_do_exit = 0; /* prevent sock_init() calling exit() */ prev_post_hook = _w32_usr_post_init; _w32_usr_post_init = pcap_init_hook; _w32_print_hook = null_print; if (dev_name && strncmp(dev_name,"pkt",3)) using_pktdrv = FALSE; rc = sock_init(); has_ip_addr = (rc != 8); /* IP-address assignment failed */ /* if pcap is using a 32-bit driver w/o a pktdrvr loaded, we * just pretend Watt-32 is initialised okay. * * !! fix-me: The Watt-32 config isn't done if no pktdrvr * was found. In that case my_ip_addr + sin_mask * have default values. Should be taken from another * ini-file/environment in any case (ref. tcpdump.ini) */ _watt_is_init = 1; if (!using_pktdrv || !has_ip_addr) /* for now .... */ { static const char myip[] = "192.168.0.1"; static const char mask[] = "255.255.255.0"; printf ("Just guessing, using IP %s and netmask %s\n", myip, mask); my_ip_addr = aton (myip); _w32_sin_mask = aton (mask); } else if (rc && using_pktdrv) { sprintf (err_buf, "sock_init() failed, code %d", rc); return (0); } /* Set recv-hook for peeking in _eth_arrived(). */#if (WATTCP_VER >= 0x0224) _eth_recv_hook = pcap_recv_hook; _eth_xmit_hook = pcap_xmit_hook;#endif /* Free the pkt-drvr handle allocated in pkt_init(). * The above hooks should thus use the handle reopened in open_driver() */ if (using_pktdrv) { _eth_release();/* _eth_is_init = 1; */ /* hack to get Rx/Tx-hooks in Watt-32 working */ } memcpy (&pcap_save, pcap, sizeof(pcap_save)); MTU = pkt_get_mtu(); pcap_save.fcode.bf_insns = NULL; pcap_save.linktype = _eth_get_hwtype (NULL, NULL); pcap_save.snapshot = MTU > 0 ? MTU : ETH_MAX; /* assume 1514 */#if 1 /* prevent use of resolve() and resolve_ip() */ last_nameserver = 0;#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -