Lines Matching +full:dma +full:- +full:poll +full:- +full:cnt
2 * This file is part of DOS-libpcap
5 * pcap-dos.c: Interface to PKTDRVR, NDIS2 and 32-bit pmode
35 #include "msdos/pm_drvr/ne2k-pci.h"
39 #include "pcap-dos.h"
40 #include "pcap-int.h"
76 * Internal variables/functions in Watt-32
87 extern void dbug_write (const char *); /* Watt-32 lib, pcdbug.c */
100 static int pcap_read_dos (pcap_t *p, int cnt, pcap_handler callback,
125 NDIS_NEXT_DEV, /* NULL or a 32-bit device */
131 "Packet-Driver",
142 return handle_to_device [fd-1]; in get_device()
146 * Private data for capturing on MS-DOS.
161 p->activate_op = pcap_activate_dos; in pcap_create_interface()
166 * Open MAC-driver with name 'device_name' for live capture of
171 if (pcap->opt.rfmon) { in pcap_activate_dos()
186 if (pcap->snapshot <= 0 || pcap->snapshot > MAXIMUM_SNAPLEN) in pcap_activate_dos()
187 pcap->snapshot = MAXIMUM_SNAPLEN; in pcap_activate_dos()
189 if (pcap->snapshot < ETH_MIN+8) in pcap_activate_dos()
190 pcap->snapshot = ETH_MIN+8; in pcap_activate_dos()
192 if (pcap->snapshot > ETH_MAX) /* silently accept and truncate large MTUs */ in pcap_activate_dos()
193 pcap->snapshot = ETH_MAX; in pcap_activate_dos()
195 pcap->linktype = DLT_EN10MB; /* !! */ in pcap_activate_dos()
196 pcap->cleanup_op = pcap_cleanup_dos; in pcap_activate_dos()
197 pcap->read_op = pcap_read_dos; in pcap_activate_dos()
198 pcap->stats_op = pcap_stats_dos; in pcap_activate_dos()
199 pcap->inject_op = pcap_sendpacket_dos; in pcap_activate_dos()
200 pcap->setfilter_op = pcap_setfilter_dos; in pcap_activate_dos()
201 pcap->setdirection_op = NULL; /* Not implemented.*/ in pcap_activate_dos()
202 pcap->fd = ++ref_count; in pcap_activate_dos()
204 pcap->bufsize = ETH_MAX+100; /* add some margin */ in pcap_activate_dos()
205 pcap->buffer = calloc (pcap->bufsize, 1); in pcap_activate_dos()
207 if (pcap->fd == 1) /* first time we're called */ in pcap_activate_dos()
209 if (!init_watt32(pcap, pcap->opt.device, pcap->errbuf) || in pcap_activate_dos()
210 !first_init(pcap->opt.device, pcap->errbuf, pcap->opt.promisc)) in pcap_activate_dos()
212 /* XXX - free pcap->buffer? */ in pcap_activate_dos()
217 else if (stricmp(active_dev->name,pcap->opt.device)) in pcap_activate_dos()
219 snprintf (pcap->errbuf, PCAP_ERRBUF_SIZE, in pcap_activate_dos()
221 "(`%s' vs. `%s')", active_dev->name, pcap->opt.device); in pcap_activate_dos()
222 /* XXX - free pcap->buffer? */ in pcap_activate_dos()
225 handle_to_device [pcap->fd-1] = active_dev; in pcap_activate_dos()
230 * Poll the receiver queue and call the pcap callback-handler
236 struct pcap_dos *pd = p->priv; in pcap_read_one()
241 if (p->opt.timeout > 0) in pcap_read_one()
244 expiry.tv_usec = now.tv_usec + 1000UL * p->opt.timeout; in pcap_read_one()
248 expiry.tv_usec -= 1000000L; in pcap_read_one()
257 dev = get_device (p->fd); in pcap_read_one()
261 PCAP_ASSERT (dev->copy_rx_buf || dev->peek_rx_buf); in pcap_read_one()
264 /* If driver has a zero-copy receive facility, peek at the queue, in pcap_read_one()
267 if (dev->peek_rx_buf) in pcap_read_one()
269 PCAP_ASSERT (dev->release_rx_buf); in pcap_read_one()
270 rx_len = (*dev->peek_rx_buf) (&p->buffer); in pcap_read_one()
274 rx_len = (*dev->copy_rx_buf) (p->buffer, p->snapshot); in pcap_read_one()
283 pcap.caplen = min (rx_len, p->snapshot); in pcap_read_one()
287 (!p->fcode.bf_insns || pcap_filter(p->fcode.bf_insns, p->buffer, pcap.len, pcap.caplen))) in pcap_read_one()
291 /* Fix-me!! Should be time of arrival. Not time of in pcap_read_one()
295 (*callback) (data, &pcap, p->buffer); in pcap_read_one()
298 if (dev->release_rx_buf) in pcap_read_one()
299 (*dev->release_rx_buf) (p->buffer); in pcap_read_one()
313 if (p->break_loop) { in pcap_read_one()
315 * Yes - clear the flag that indicates that it in pcap_read_one()
316 * has, and return -2 to indicate that we were in pcap_read_one()
319 p->break_loop = 0; in pcap_read_one()
320 return (-2); in pcap_read_one()
326 if (p->opt.timeout <= 0 || (volatile int)p->fd <= 0) in pcap_read_one()
338 if (pd->wait_proc) in pcap_read_one()
339 (*pd->wait_proc)(); /* call yield func */ in pcap_read_one()
344 pd->stat.ps_drop++; in pcap_read_one()
347 printk ("pkt-err %s\n", pktInfo.error); in pcap_read_one()
349 return (-1); in pcap_read_one()
355 pcap_read_dos (pcap_t *p, int cnt, pcap_handler callback, u_char *data) in pcap_read_dos() argument
365 * return a too-low count. in pcap_read_dos()
371 if (PACKET_COUNT_IS_UNLIMITED(cnt)) in pcap_read_dos()
372 cnt = INT_MAX; in pcap_read_dos()
374 while (num <= cnt) in pcap_read_dos()
376 if (p->fd <= 0) in pcap_read_dos()
377 return (-1); in pcap_read_dos()
395 struct device *dev = p ? get_device(p->fd) : NULL; in pcap_stats_dos()
399 strcpy (p->errbuf, "illegal pcap handle"); in pcap_stats_dos()
400 return (-1); in pcap_stats_dos()
403 if (!dev->get_stats || (stats = (*dev->get_stats)(dev)) == NULL) in pcap_stats_dos()
405 strcpy (p->errbuf, "device statistics not available"); in pcap_stats_dos()
406 return (-1); in pcap_stats_dos()
411 pd = p->priv; in pcap_stats_dos()
412 pd->stat.ps_recv = stats->rx_packets; in pcap_stats_dos()
413 pd->stat.ps_drop += stats->rx_missed_errors; in pcap_stats_dos()
414 pd->stat.ps_ifdrop = stats->rx_dropped + /* queue full */ in pcap_stats_dos()
415 stats->rx_errors; /* HW errors */ in pcap_stats_dos()
417 *ps = pd->stat; in pcap_stats_dos()
424 * May be called after 'dev->close' is called.
428 struct device *dev = p ? get_device (p->fd) : NULL; in pcap_stats_ex()
430 if (!dev || !dev->get_stats) in pcap_stats_ex()
432 pcap_strlcpy (p->errbuf, "detailed device statistics not available", in pcap_stats_ex()
434 return (-1); in pcap_stats_ex()
437 if (!strnicmp(dev->name,"pkt",3)) in pcap_stats_ex()
439 pcap_strlcpy (p->errbuf, "pktdrvr doesn't have detailed statistics", in pcap_stats_ex()
441 return (-1); in pcap_stats_ex()
443 memcpy (se, (*dev->get_stats)(dev), sizeof(*se)); in pcap_stats_ex()
448 * Simply store the filter-code for the pcap_read_dos() callback
449 * Some day the filter-code could be handed down to the active
450 * device (pkt_rx1.s or 32-bit device interrupt handler).
455 return (-1); in pcap_setfilter_dos()
456 p->fcode = *fp; in pcap_setfilter_dos()
485 pd = p->priv; in pcap_cleanup_dos()
487 pd->stat.ps_drop = 0; in pcap_cleanup_dos()
488 if (!get_device(p->fd)) in pcap_cleanup_dos()
491 handle_to_device [p->fd-1] = NULL; in pcap_cleanup_dos()
492 p->fd = 0; in pcap_cleanup_dos()
494 ref_count--; in pcap_cleanup_dos()
499 /* XXX - call pcap_cleanup_live_common? */ in pcap_cleanup_dos()
514 for (dev = (struct device*)dev_base; dev; dev = dev->next) in pcap_lookupdev()
516 PCAP_ASSERT (dev->probe); in pcap_lookupdev()
518 if ((*dev->probe)(dev)) in pcap_lookupdev()
522 return (char*) dev->name; in pcap_lookupdev()
532 * Gets localnet & netmask from Watt-32.
543 return (-1); in pcap_lookupnet()
559 return (-1); in pcap_lookupnet()
571 * Returns -1 on error, 0 otherwise.
585 for (dev = (struct device*)dev_base; dev; dev = dev->next) in pcap_platform_finddevs()
587 PCAP_ASSERT (dev->probe); in pcap_platform_finddevs()
589 if (!(*dev->probe)(dev)) in pcap_platform_finddevs()
592 PCAP_ASSERT (dev->close); /* set by probe routine */ in pcap_platform_finddevs()
594 (*dev->close) (dev); in pcap_platform_finddevs()
597 * XXX - find out whether it's up or running? Does that apply here? in pcap_platform_finddevs()
602 if ((curdev = pcap_add_dev(devlistp, dev->name, 0, in pcap_platform_finddevs()
603 dev->long_name, errbuf)) == NULL) in pcap_platform_finddevs()
605 ret = -1; in pcap_platform_finddevs()
626 ret = -1; in pcap_platform_finddevs()
647 _exit (-1); in pcap_assert()
658 struct pcap_dos *pd = p->priv; in pcap_set_wait()
660 pd->wait_proc = yield; in pcap_set_wait()
661 p->opt.timeout = wait; in pcap_set_wait()
673 for (dev = (struct device*)dev_base; dev; dev = dev->next) in open_driver()
675 PCAP_ASSERT (dev->name); in open_driver()
677 if (strcmp (dev_name,dev->name)) in open_driver()
682 PCAP_ASSERT (dev->probe); in open_driver()
684 if (!(*dev->probe)(dev)) /* call the xx_probe() function */ in open_driver()
701 dev->flags |= (IFF_ALLMULTI | IFF_PROMISC); in open_driver()
702 else dev->flags &= ~(IFF_ALLMULTI | IFF_PROMISC); in open_driver()
704 PCAP_ASSERT (dev->open); in open_driver()
706 if (!(*dev->open)(dev)) in open_driver()
709 if (pktInfo.error && !strncmp(dev->name,"pkt",3)) in open_driver()
719 if (promisc && dev->set_multicast_list) in open_driver()
720 (*dev->set_multicast_list) (dev); in open_driver()
752 if (dev && dev->close) in close_driver()
754 (*dev->close) (dev); in close_driver()
783 if (active_dev->irq > 0) /* excludes IRQ 0 */ in exc_handler()
785 disable_irq (active_dev->irq); in exc_handler()
786 irq_eoi_cmd (active_dev->irq); in exc_handler()
852 * If driver is NOT a 16-bit "pkt/ndis" driver (having a 'copy_rx_buf' in first_init()
853 * set in it's probe handler), initialize near-memory ring-buffer for in first_init()
854 * the 32-bit device. in first_init()
856 if (dev->copy_rx_buf == NULL) in first_init()
858 dev->get_rx_buf = get_rxbuf; in first_init()
859 dev->peek_rx_buf = peek_rxbuf; in first_init()
860 dev->release_rx_buf = release_rxbuf; in first_init()
861 pktq_init (&dev->queue, RECEIVE_BUF_SIZE, RECEIVE_QUEUE_SIZE, rx_pool); in first_init()
883 * Hook functions for using Watt-32 together with pcap
885 static char rxbuf [ETH_MAX+100]; /* rx-buffer with some margin */
895 memcpy (rxbuf, buf, pcap->caplen); in watt32_recv_hook()
896 etype = ep->ether_type; in watt32_recv_hook()
902 * This function is used by Watt-32 to poll for a packet.
917 * This function is called by Watt-32 (via _eth_xmit_hook).
927 if (active_dev && active_dev->xmit) in pcap_xmit_hook()
928 if ((*active_dev->xmit) (active_dev, buf, len) > 0) in pcap_xmit_hook()
939 struct device *dev = p ? get_device(p->fd) : NULL; in pcap_sendpacket_dos()
941 if (!dev || !dev->xmit) in pcap_sendpacket_dos()
942 return (-1); in pcap_sendpacket_dos()
943 return (*dev->xmit) (dev, buf, len); in pcap_sendpacket_dos()
947 * This function is called by Watt-32 in tcp_post_init().
948 * We should prevent Watt-32 from using BOOTP/DHCP/RARP etc.
962 * Suppress PRINT message from Watt-32's sock_init()
967 * To use features of Watt-32 (netdb functions and socket etc.)
970 * make Watt-32 and pcap co-operate.
979 * order to open debug/trace-file properly in init_watt32()
1001 has_ip_addr = (rc != 8); /* IP-address assignment failed */ in init_watt32()
1003 /* if pcap is using a 32-bit driver w/o a pktdrvr loaded, we in init_watt32()
1004 * just pretend Watt-32 is initialized okay. in init_watt32()
1006 * !! fix-me: The Watt-32 config isn't done if no pktdrvr in init_watt32()
1009 * ini-file/environment in any case (ref. tcpdump.ini) in init_watt32()
1028 /* Set recv-hook for peeking in _eth_arrived(). in init_watt32()
1035 /* Free the pkt-drvr handle allocated in pkt_init(). in init_watt32()
1041 /* _eth_is_init = 1; */ /* hack to get Rx/Tx-hooks in Watt-32 working */ in init_watt32()
1100 * handling. Uses Watt-32's config-table function.
1117 int pcap_pkt_debug = -1;
1126 if (dev->priv) in pkt_close()
1127 free (dev->priv); in pkt_close()
1128 dev->priv = NULL; in pkt_close()
1135 if (dev->flags & IFF_PROMISC) in pkt_open()
1149 struct net_device_stats *stats = (struct net_device_stats*) dev->priv; in pkt_xmit()
1156 stats->tx_errors++; in pkt_xmit()
1164 struct net_device_stats *stats = (struct net_device_stats*) dev->priv; in pkt_stats()
1169 stats->rx_packets = pktStat.inPackets; in pkt_stats()
1170 stats->rx_errors = pktStat.lost; in pkt_stats()
1171 stats->rx_missed_errors = PktRxDropped(); in pkt_stats()
1180 dev->open = pkt_open; in pkt_probe()
1181 dev->xmit = pkt_xmit; in pkt_probe()
1182 dev->close = pkt_close; in pkt_probe()
1183 dev->get_stats = pkt_stats; in pkt_probe()
1184 dev->copy_rx_buf = PktReceive; /* farmem peek and copy routine */ in pkt_probe()
1185 dev->get_rx_buf = NULL; in pkt_probe()
1186 dev->peek_rx_buf = NULL; in pkt_probe()
1187 dev->release_rx_buf = NULL; in pkt_probe()
1188 dev->priv = calloc (sizeof(struct net_device_stats), 1); in pkt_probe()
1189 if (!dev->priv) in pkt_probe()
1207 int promisc = (dev->flags & IFF_PROMISC); in ndis_open()
1223 /* to-do */ in ndis_stats()
1235 dev->open = ndis_open; in ndis_probe()
1236 dev->xmit = NULL; in ndis_probe()
1237 dev->close = ndis_close; in ndis_probe()
1238 dev->get_stats = ndis_stats; in ndis_probe()
1239 dev->copy_rx_buf = NULL; /* to-do */ in ndis_probe()
1240 dev->get_rx_buf = NULL; /* upcall is from rmode driver */ in ndis_probe()
1241 dev->peek_rx_buf = NULL; in ndis_probe()
1242 dev->release_rx_buf = NULL; in ndis_probe()
1247 * Search & probe for supported 32-bit (pmode) pcap devices
1338 rtl8139_probe /* dev->probe routine */
1343 * NOTE: the queue-element is not copied, only a pointer is
1350 PCAP_ASSERT (pktq_check (&active_dev->queue)); in peek_rxbuf()
1353 tail = pktq_out_elem (&active_dev->queue); in peek_rxbuf()
1354 head = pktq_in_elem (&active_dev->queue); in peek_rxbuf()
1359 PCAP_ASSERT (tail->size < active_dev->queue.elem_size-4-2); in peek_rxbuf()
1361 *buf = &tail->data[0]; in peek_rxbuf()
1362 return (tail->size); in peek_rxbuf()
1374 struct rx_elem *tail = pktq_out_elem (&active_dev->queue); in release_rxbuf()
1376 PCAP_ASSERT (&tail->data[0] == buf); in release_rxbuf()
1380 pktq_inc_out (&active_dev->queue); in release_rxbuf()
1395 idx = pktq_in_index (&active_dev->queue); in get_rxbuf()
1400 writew ("-\\|/"[fan_idx++] | (15 << 8), /* white on black colour */ in get_rxbuf()
1401 0xB8000 + 2*79); /* upper-right corner, 80-col colour screen */ in get_rxbuf()
1407 if (idx != active_dev->queue.out_index) in get_rxbuf()
1409 struct rx_elem *head = pktq_in_elem (&active_dev->queue); in get_rxbuf()
1411 head->size = len; in get_rxbuf()
1412 active_dev->queue.in_index = idx; in get_rxbuf()
1413 return (&head->data[0]); in get_rxbuf()
1416 /* !!to-do: drop 25% of the oldest element in get_rxbuf()
1418 pktq_clear (&active_dev->queue); in get_rxbuf()
1423 * Simple ring-buffer queue handler for reception of packets
1435 if (!q || !q->num_elem || !q->buf_start) in pktq_check()
1439 buf = q->buf_start; in pktq_check()
1441 for (i = 0; i < q->num_elem; i++) in pktq_check()
1443 buf += q->elem_size; in pktq_check()
1444 if (*(DWORD*)(buf - sizeof(DWORD)) != PKTQ_MARKER) in pktq_check()
1455 q->elem_size = size; in pktq_init()
1456 q->num_elem = num; in pktq_init()
1457 q->buf_start = pool; in pktq_init()
1458 q->in_index = 0; in pktq_init()
1459 q->out_index = 0; in pktq_init()
1472 PCAP_ASSERT (((unsigned)(&elem->data[0]) & 3) == 0); in pktq_init()
1475 *(DWORD*) (pool - sizeof(DWORD)) = PKTQ_MARKER; in pktq_init()
1486 q->out_index++; in pktq_inc_out()
1487 if (q->out_index >= q->num_elem) in pktq_inc_out()
1488 q->out_index = 0; in pktq_inc_out()
1489 return (q->out_index); in pktq_inc_out()
1498 volatile int index = q->in_index + 1; in pktq_in_index()
1500 if (index >= q->num_elem) in pktq_in_index()
1506 * Return the queue's head-buffer.
1510 return (struct rx_elem*) (q->buf_start + (q->elem_size * q->in_index)); in pktq_in_elem()
1514 * Return the queue's tail-buffer.
1518 return (struct rx_elem*) (q->buf_start + (q->elem_size * q->out_index)); in pktq_out_elem()
1522 * Clear the queue ring-buffer by setting head=tail.
1526 q->in_index = q->out_index; in pktq_clear()
1530 * Symbols that must be linkable for "gcc -O0"
1539 #include "msdos/pm_drvr/dma.h"
1549 return ("DOS-" PCAP_VERSION_STRING); in pcap_lib_version()