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