📄 pcap-dos.c
字号:
return (1);}int EISA_bus = 0; /* Where is natural place for this? *//* * Application config hooks to set various driver parameters. */static struct config_table debug_tab[] = { { "PKT.DEBUG", ARG_ATOI, &pcap_pkt_debug }, { "PKT.VECTOR", ARG_ATOX_W, NULL }, { "NDIS.DEBUG", ARG_ATOI, NULL },#ifdef USE_32BIT_DRIVERS { "3C503.DEBUG", ARG_ATOI, &ei_debug }, { "3C503.IO_BASE", ARG_ATOX_W, &el2_dev.base_addr }, { "3C503.MEMORY", ARG_ATOX_W, &el2_dev.mem_start }, { "3C503.IRQ", ARG_ATOI, &el2_dev.irq }, { "3C505.DEBUG", ARG_ATOI, NULL }, { "3C505.BASE", ARG_ATOX_W, NULL }, { "3C507.DEBUG", ARG_ATOI, NULL }, { "3C509.DEBUG", ARG_ATOI, &el3_debug }, { "3C509.ILOOP", ARG_ATOI, &el3_max_loop }, { "3C529.DEBUG", ARG_ATOI, NULL }, { "3C575.DEBUG", ARG_ATOI, &debug_3c575 }, { "3C59X.DEBUG", ARG_ATOI, &vortex_debug }, { "3C59X.IFACE0", ARG_ATOI, &vortex_options[0] }, { "3C59X.IFACE1", ARG_ATOI, &vortex_options[1] }, { "3C59X.IFACE2", ARG_ATOI, &vortex_options[2] }, { "3C59X.IFACE3", ARG_ATOI, &vortex_options[3] }, { "3C90X.DEBUG", ARG_ATOX_W, &tc90xbc_debug }, { "ACCT.DEBUG", ARG_ATOI, ðpk_debug }, { "CS89.DEBUG", ARG_ATOI, &cs89_debug }, { "RTL8139.DEBUG", ARG_ATOI, &rtl8139_debug }, /* { "RTL8139.FDUPLEX", ARG_ATOI, &rtl8139_options }, */ { "SMC.DEBUG", ARG_ATOI, &ei_debug }, /* { "E100.DEBUG", ARG_ATOI, &e100_debug }, */ { "PCI.DEBUG", ARG_ATOI, &pci_debug }, { "BIOS32.DEBUG", ARG_ATOI, &bios32_debug }, { "IRQ.DEBUG", ARG_ATOI, &irq_debug }, { "TIMER.IRQ", ARG_ATOI, &timer_irq },#endif { NULL } };/* * 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){ return parse_config_table (debug_tab, NULL, name, value);}/* * Linked list of supported devices */struct device *active_dev = NULL; /* the device we have opened */struct device *probed_dev = NULL; /* the device we have probed */const struct device *dev_base = &pkt_dev; /* list of network devices *//* * PKTDRVR device functions */int pcap_pkt_debug = -1;static void pkt_close (struct device *dev){ BOOL okay = PktExitDriver(); if (pcap_pkt_debug > 1) fprintf (stderr, "pkt_close(): %d\n", okay); if (dev->priv) free (dev->priv); dev->priv = NULL;}static int pkt_open (struct device *dev){ PKT_RX_MODE mode; if (dev->flags & IFF_PROMISC) mode = PDRX_ALL_PACKETS; else mode = PDRX_BROADCAST; if (!PktInitDriver(mode)) return (0); PktResetStatistics (pktInfo.handle); PktQueueBusy (FALSE); return (1);}static int pkt_xmit (struct device *dev, const void *buf, int len){ struct net_device_stats *stats = (struct net_device_stats*) dev->priv; if (pcap_pkt_debug > 0) dbug_write ("pcap_xmit\n"); if (!PktTransmit(buf,len)) { stats->tx_errors++; return (0); } return (len);}static void *pkt_stats (struct device *dev){ struct net_device_stats *stats = (struct net_device_stats*) dev->priv; if (!stats || !PktSessStatistics(pktInfo.handle)) return (NULL); stats->rx_packets = pktStat.inPackets; stats->rx_errors = pktStat.lost; stats->rx_missed_errors = PktRxDropped(); return (stats);}static int pkt_probe (struct device *dev){ if (!PktSearchDriver()) return (0); dev->open = pkt_open; dev->xmit = pkt_xmit; dev->close = pkt_close; dev->get_stats = pkt_stats; dev->copy_rx_buf = PktReceive; /* farmem peek and copy routine */ dev->get_rx_buf = NULL; dev->peek_rx_buf = NULL; dev->release_rx_buf = NULL; dev->priv = calloc (sizeof(struct net_device_stats), 1); if (!dev->priv) return (0); return (1);}/* * NDIS device functions */static void ndis_close (struct device *dev){#ifdef USE_NDIS2 NdisShutdown();#endif ARGSUSED (dev);}static int ndis_open (struct device *dev){ int promis = (dev->flags & IFF_PROMISC);#ifdef USE_NDIS2 if (!NdisInit(promis)) return (0); return (1);#else ARGSUSED (promis); return (0);#endif}static void *ndis_stats (struct device *dev){ static struct net_device_stats stats; /* to-do */ ARGSUSED (dev); return (&stats);}static int ndis_probe (struct device *dev){#ifdef USE_NDIS2 if (!NdisOpen()) return (0);#endif dev->open = ndis_open; dev->xmit = NULL; dev->close = ndis_close; dev->get_stats = ndis_stats; dev->copy_rx_buf = NULL; /* to-do */ dev->get_rx_buf = NULL; /* upcall is from rmode driver */ dev->peek_rx_buf = NULL; dev->release_rx_buf = NULL; return (0);}/* * Search & probe for supported 32-bit (pmode) pcap devices */#if defined(USE_32BIT_DRIVERS)struct device el2_dev LOCKED_VAR = { "3c503", "EtherLink II", 0, 0,0,0,0,0,0, NULL, el2_probe };struct device el3_dev LOCKED_VAR = { "3c509", "EtherLink III", 0, 0,0,0,0,0,0, &el2_dev, el3_probe };struct device tc515_dev LOCKED_VAR = { "3c515", "EtherLink PCI", 0, 0,0,0,0,0,0, &el3_dev, tc515_probe };struct device tc59_dev LOCKED_VAR = { "3c59x", "EtherLink PCI", 0, 0,0,0,0,0,0, &tc515_dev, tc59x_probe };struct device tc90xbc_dev LOCKED_VAR = { "3c90x", "EtherLink 90X", 0, 0,0,0,0,0,0, &tc59_dev, tc90xbc_probe };struct device wd_dev LOCKED_VAR = { "wd", "Westen Digital", 0, 0,0,0,0,0,0, &tc90xbc_dev, wd_probe };struct device ne_dev LOCKED_VAR = { "ne", "NEx000", 0, 0,0,0,0,0,0, &wd_dev, ne_probe };struct device acct_dev LOCKED_VAR = { "acct", "Accton EtherPocket", 0, 0,0,0,0,0,0, &ne_dev, ethpk_probe };struct device cs89_dev LOCKED_VAR = { "cs89", "Crystal Semiconductor", 0, 0,0,0,0,0,0, &acct_dev, cs89x0_probe };struct device rtl8139_dev LOCKED_VAR = { "rtl8139", "RealTek PCI", 0, 0,0,0,0,0,0, &cs89_dev, rtl8139_probe /* dev->probe routine */ }; /* * Dequeue routine is called by polling. * NOTE: the queue-element is not copied, only a pointer is * returned at '*buf' */int peek_rxbuf (BYTE **buf){ struct rx_elem *tail, *head; PCAP_ASSERT (pktq_check (&active_dev->queue)); DISABLE(); tail = pktq_out_elem (&active_dev->queue); head = pktq_in_elem (&active_dev->queue); ENABLE(); if (head != tail) { PCAP_ASSERT (tail->size < active_dev->queue.elem_size-4-2); *buf = &tail->data[0]; return (tail->size); } *buf = NULL; return (0);}/* * Release buffer we peeked at above. */int release_rxbuf (BYTE *buf){#ifndef NDEBUG struct rx_elem *tail = pktq_out_elem (&active_dev->queue); PCAP_ASSERT (&tail->data[0] == buf);#else ARGSUSED (buf);#endif pktq_inc_out (&active_dev->queue); return (1);}/* * get_rxbuf() routine (in locked code) is called from IRQ handler * to request a buffer. Interrupts are disabled and we have a 32kB stack. */BYTE *get_rxbuf (int len){ int idx; if (len < ETH_MIN || len > ETH_MAX) return (NULL); idx = pktq_in_index (&active_dev->queue);#ifdef DEBUG { static int fan_idx LOCKED_VAR = 0; writew ("-\\|/"[fan_idx++] | (15 << 8), /* white on black colour */ 0xB8000 + 2*79); /* upper-right corner, 80-col colour screen */ fan_idx &= 3; }/* writew (idx + '0' + 0x0F00, 0xB8000 + 2*78); */#endif if (idx != active_dev->queue.out_index) { struct rx_elem *head = pktq_in_elem (&active_dev->queue); head->size = len; active_dev->queue.in_index = idx; return (&head->data[0]); } /* !!to-do: drop 25% of the oldest element */ pktq_clear (&active_dev->queue); return (NULL);}/* * Simple ring-buffer queue handler for reception of packets * from network driver. */#define PKTQ_MARKER 0xDEADBEEFstatic int pktq_check (struct rx_ringbuf *q){#ifndef NDEBUG int i; char *buf;#endif if (!q || !q->num_elem || !q->buf_start) return (0);#ifndef NDEBUG buf = q->buf_start; for (i = 0; i < q->num_elem; i++) { buf += q->elem_size; if (*(DWORD*)(buf - sizeof(DWORD)) != PKTQ_MARKER) return (0); }#endif return (1);}static int pktq_init (struct rx_ringbuf *q, int size, int num, char *pool){ int i; q->elem_size = size; q->num_elem = num; q->buf_start = pool; q->in_index = 0; q->out_index = 0; PCAP_ASSERT (size >= sizeof(struct rx_elem) + sizeof(DWORD)); PCAP_ASSERT (num); PCAP_ASSERT (pool); for (i = 0; i < num; i++) {#if 0 struct rx_elem *elem = (struct rx_elem*) pool; /* assert dword aligned elements */ PCAP_ASSERT (((unsigned)(&elem->data[0]) & 3) == 0);#endif pool += size; *(DWORD*) (pool - sizeof(DWORD)) = PKTQ_MARKER; } return (1);}/* * Increment the queue 'out_index' (tail). * Check for wraps. */static int pktq_inc_out (struct rx_ringbuf *q){ q->out_index++; if (q->out_index >= q->num_elem) q->out_index = 0; return (q->out_index);}/* * Return the queue's next 'in_index' (head). * Check for wraps. */static int pktq_in_index (struct rx_ringbuf *q){ volatile int index = q->in_index + 1; if (index >= q->num_elem) index = 0; return (index);}/* * Return the queue's head-buffer. */static struct rx_elem *pktq_in_elem (struct rx_ringbuf *q){ return (struct rx_elem*) (q->buf_start + (q->elem_size * q->in_index));}/* * Return the queue's tail-buffer. */static struct rx_elem *pktq_out_elem (struct rx_ringbuf *q){ return (struct rx_elem*) (q->buf_start + (q->elem_size * q->out_index));}/* * Clear the queue ring-buffer by setting head=tail. */static void pktq_clear (struct rx_ringbuf *q){ q->in_index = q->out_index;}/* * Symbols that must be linkable for "gcc -O0" */#undef __IOPORT_H#undef __DMA_H#define extern#define __inline__#include "msdos/pm_drvr/ioport.h"#include "msdos/pm_drvr/dma.h"#endif /* USE_32BIT_DRIVERS */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -