Watt-32 tcp/ip  2.2 dev-rel.10
pcsed.c
Go to the documentation of this file.
1 
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <string.h>
19 
20 #include "copyrigh.h"
21 #include "wattcp.h"
22 #include "wdpmi.h"
23 #include "strings.h"
24 #include "language.h"
25 #include "sock_ini.h"
26 #include "loopback.h"
27 #include "cpumodel.h"
28 #include "misc.h"
29 #include "run.h"
30 #include "timer.h"
31 #include "profile.h"
32 #include "rs232.h"
33 #include "split.h"
34 #include "ip4_in.h"
35 #include "ip6_in.h"
36 #include "bsddbug.h"
37 #include "pcigmp.h"
38 #include "pcqueue.h"
39 #include "pcconfig.h"
40 #include "pcdbug.h"
41 #include "pctcp.h"
42 #include "pcstat.h"
43 #include "pcpkt.h"
44 #include "pcsed.h"
45 #include "pppoe.h"
46 
47 /* !!fix-me: Should allow the largest possible MAC-address to be used;
48  * An AX-25 address is 7 bytes.
49  */
50 mac_address _eth_addr;
51 mac_address _eth_brdcast;
52 mac_address _eth_loop_addr;
53 mac_address _eth_real_addr;
55 BOOL _eth_is_init = FALSE;
56 BOOL _ip_recursion = FALSE;
57 BOOL _eth_ndis3pkt = FALSE;
58 BOOL _eth_SwsVpkt = FALSE;
59 BOOL _eth_airpcap = FALSE;
60 BOOL _eth_wanpacket = FALSE;
61 BOOL _eth_winpcap = FALSE;
63 const char *_eth_not_init = "Packet driver not initialised";
64 
69 
91 void *(W32_CALL *_eth_recv_hook) (WORD *type) = NULL;
92 int (W32_CALL *_eth_recv_peek) (void *mac_buf) = NULL;
93 int (W32_CALL *_eth_xmit_hook) (const void *mac_buf, unsigned len) = NULL;
94 
99 static void *(*mac_tx_format)(void *mac_buf, const void *mac_dest, WORD type);
100 static int (*mac_transmit) (const void *mac_buf, WORD len);
101 
102 static WORD proto; /* protocol set in _eth_formatpacket() */
103 static void *nw_pkt; /* where network protocol packet starts */
104 
105 static void __eth_release (void);
106 
116 #if (DOSX & (DOS4GW|X32VM))
117  #define TX_BUF() ((union link_Packet*) pkt_tx_buf())
118 
119 #elif (DOSX & DJGPP)
120  static union link_Packet outbuf;
121 
122  #define TX_BUF() (_pkt_inf && _pkt_inf->use_near_ptr ? \
123  (union link_Packet*)pkt_tx_buf() : \
124  (&outbuf))
125 #else
126  static union link_Packet outbuf;
127  #define TX_BUF() (&outbuf)
128 #endif
129 
135 void * W32_CALL _eth_formatpacket (const void *mac_dest, WORD eth_type)
136 {
137  SIO_TRACE (("_eth_formatpacket, type %04X", eth_type));
138 
139  nw_pkt = (*mac_tx_format) (TX_BUF(), mac_dest, eth_type);
140  return (nw_pkt);
141 }
142 
143 
144 #if defined(USE_LOOPBACK)
145 
154 static int send_loopback (link_Packet pkt, BOOL is_ip6, unsigned *err_line)
155 {
156  struct pkt_ringbuf *q;
157  const in_Header *ip;
158  int ip_len;
159 
160  SIO_TRACE (("send_loopback"));
161 
162  if (!_pkt_inf)
163  {
164  *err_line = __LINE__;
165  goto drop_it;
166  }
167 
168  /* Call loopback handler with IP-packet
169  */
170  ip = (in_Header*) ((BYTE*)&pkt + _pkt_ip_ofs);
171  ip_len = loopback_device ((in_Header*)ip);
172 
173  q = &_pkt_inf->pkt_queue;
174 
175  if (!q || ip_len > (int)_mtu)
176  {
177  *err_line = __LINE__;
178  goto drop_it;
179  }
180 
181  if (ip_len > 0)
182  {
183 #if defined(USE_FAST_PKT)
184  /*
185  * Don't let pkt_receiver() modify the queue while testing/copying.
186  */
187  if (pkt_buffers_used() >= _pkt_inf->pkt_queue.num_buf - 1)
188  {
189  *err_line = __LINE__;
190  goto drop_it;
191  }
192  {
193  char tx_buf [ETH_MAX];
194  unsigned len = ip_len;
195 
196  /* Enqueue packet to head of input IP-queue.
197  */
198  if (!_pktserial)
199  {
200  void *data = (*mac_tx_format) (tx_buf, _eth_addr,
201  is_ip6 ? IP6_TYPE : IP4_TYPE);
202  memcpy (MAC_SRC(data), &_eth_loop_addr, sizeof(mac_address));
203  memcpy (data, ip, ip_len);
204  len += _pkt_ip_ofs;
205  }
206  else
207  memcpy (tx_buf, ip, ip_len);
208 
209  if (!pkt_append_recv(tx_buf, len))
210  {
211  *err_line = __LINE__;
212  goto drop_it;
213  }
214  }
215 #elif defined(WIN32)
216  struct pkt_rx_element *head;
217 
218  ENTER_CRIT();
219  if (pktq_in_index(q) == q->out_index) /* queue is full, drop it */
220  {
221  q->num_drop++;
222  LEAVE_CRIT();
223  *err_line = __LINE__;
224  goto drop_it;
225  }
226 
227  head = (struct pkt_rx_element*) pktq_in_buf (q);
228  head->rx_length = _pkt_ip_ofs + ip_len;
229  head->tstamp_put = win_get_perf_count();
230 
231  /* Enqueue packet to head of input IP-queue.
232  */
233  if (!_pktserial)
234  {
235  void *data = (*mac_tx_format) (&head->rx_buf, _eth_addr,
236  is_ip6 ? IP6_TYPE : IP4_TYPE);
237  memcpy (MAC_SRC(data), &_eth_loop_addr, sizeof(mac_address));
238  memcpy (data, ip, ip_len);
239  }
240  else
241  memcpy (head, ip, ip_len);
242 
243  /* Update queue head index
244  */
245  q->in_index = pktq_in_index (q);
246 
247  LEAVE_CRIT();
248 
249 #else
250  union link_Packet *head;
251 
252  DISABLE();
253  if (pktq_in_index(q) == q->out_index) /* queue is full, drop it */
254  {
255  q->num_drop++;
256  ENABLE();
257  *err_line = __LINE__;
258  goto drop_it;
259  }
260 
261  head = (union link_Packet*) pktq_in_buf (q);
262 
263  /* Enqueue packet to head of input IP-queue.
264  */
265  if (!_pktserial)
266  {
267  void *data = (*mac_tx_format) (head, _eth_addr,
268  is_ip6 ? IP6_TYPE : IP4_TYPE);
269  memcpy (MAC_SRC(data), &_eth_loop_addr, sizeof(mac_address));
270  memcpy (data, ip, ip_len);
271  }
272  else
273  memcpy (head, ip, ip_len);
274 
275  /* Update queue head index
276  */
277  q->in_index = pktq_in_index (q);
278 
279  ENABLE();
280 #endif
281  }
282  *err_line = 0;
283  return (ip_len + _pkt_ip_ofs);
284 
285 drop_it:
286  /*
287  * Maybe this should be an input counter
288  */
289  if (is_ip6)
290  STAT (ip6stats.ip6s_odropped++);
291  else STAT (ip4stats.ips_odropped++);
292  return (0);
293 }
294 #endif /* USE_LOOPBACK */
295 
296 
306 int W32_CALL _eth_send (WORD len, const void *sock, const char *file, unsigned line)
307 {
308 #if defined(USE_DEBUG) || defined(USE_LOOPBACK)
309  unsigned errline = 0;
310 #endif
311  BOOL send_loopback_to_driver = FALSE;
312 
313  SIO_TRACE (("_eth_send, len %d", len));
314 
315  if (!_eth_is_init) /* GvB 2002-09, Lets us run without a working eth */
316  {
317  SOCK_ERRNO (ENETDOWN);
318  return (0);
319  }
320 
321 #if defined(WIN32)
322  /*
323  * Just a test for now; send it to the driver and look what happens....
324  * They go on the wire and not to the Winsock loopback provider.
325  * No surprise here yet.
326  */
327  if (loopback_mode & LBACK_MODE_WINSOCK)
328  send_loopback_to_driver = TRUE;
329 #endif
330 
331  if (proto == IP4_TYPE)
332  {
333  /* Sending to loopback device if IPv4.
334  */
335  const in_Header *ip = (const in_Header*) nw_pkt;
336 
337  if (!send_loopback_to_driver &&
338  _ip4_is_loopback_addr(intel(ip->destination)))
339  {
340 #if defined(USE_LOOPBACK)
341  len = send_loopback (*TX_BUF(), FALSE, &errline);
342 #else
343  STAT (ip4stats.ips_odropped++); /* packet dropped (null-device) */
344 #endif
345  goto debug_tx;
346  }
347  }
348 
349 #if defined(USE_IPV6)
350  else if (proto == IP6_TYPE)
351  {
352  const in6_Header *ip = (const in6_Header*) nw_pkt;
353 
354  if (!send_loopback_to_driver &&
355  IN6_IS_ADDR_LOOPBACK(&ip->destination))
356  {
357 #if defined(USE_LOOPBACK)
358  len = send_loopback (*TX_BUF(), TRUE, &errline);
359 #else
360  STAT (ip6stats.ip6s_odropped++);
361 #endif
362  goto debug_tx;
363  }
364  }
365 #endif /* USE_IPV6 */
366 
367 #if defined(USE_PPPOE)
368  else if (proto == PPPOE_SESS_TYPE)
369  {
370  pppoe_Packet *pppoe = (pppoe_Packet*) TX_BUF()->eth.data;
371 
372  pppoe->length = intel16 (len+2);
373  len += PPPOE_HDR_SIZE + 2; /* add 2 for protocol */
374  }
375 #endif
376 
377  /* Store the last Tx CPU timestamp (for debugging).
378  */
379 #if (DOSX)
380  if (debug_xmit && has_rdtsc)
381  {
382  #if defined(WIN32)
383  uint64 cnt = win_get_perf_count();
384  memcpy (&_eth_last.tx.tstamp, &cnt, sizeof(_eth_last.tx.tstamp));
385  #else
386  get_rdtsc2 (&_eth_last.tx.tstamp);
387  #endif
388  }
389 #endif
390 
391  /* Do the MAC-dependent transmit. `len' on return is total length
392  * of link-layer packet sent. `len' is 0 on failure. The xmit-hook
393  * is used by e.g. libpcap/libnet.
394  */
395  if (_eth_xmit_hook)
396  len = (*_eth_xmit_hook) (TX_BUF(), len + _pkt_ip_ofs);
397  else len = (*mac_transmit) (TX_BUF(), len + _pkt_ip_ofs);
398 
399  if (len > _pkt_ip_ofs)
400  {
401  _eth_last.tx.size = len;
402  len -= _pkt_ip_ofs;
403  }
404  else
405  {
406  if (debug_on)
407  outs ("Tx failed. ");
408  len = 0;
409  _eth_last.tx.size = 0;
410  }
411 
412 debug_tx:
413 
414 #if defined(NEED_PKT_SPLIT)
415  pkt_split_mac_out (TX_BUF());
416 #endif
417 
418 #if defined(USE_STATISTICS)
419  if (len > 0)
420  update_out_stat();
421 #endif
422 
423 #if defined(USE_DEBUG)
424  if (debug_xmit)
425  (*debug_xmit) (sock, (const in_Header*)nw_pkt, file, line);
426 
427  if (len == 0)
428  {
429  if (errline && !send_loopback_to_driver)
430  dbug_printf ("** Error in loopback handler, line %u\n", errline);
431  else
432  {
433  const char err[] = "** Transmit fault **\n";
434 
435  TCP_CONSOLE_MSG (1, (err));
436  dbug_printf (err);
437  }
438  }
439 #else
440  ARGSUSED (sock);
441  ARGSUSED (file);
442  ARGSUSED (line);
443 #endif
444 
445  /* Undo hack done in pppoe_mac_format()
446  */
447  if (proto == PPPOE_SESS_TYPE || _pktdevclass == PDCLASS_ETHER)
448  _pkt_ip_ofs = sizeof(eth_Header);
449  return (len);
450 }
451 
455 static void *eth_mac_format (void *mac_buf, const void *mac_dest, WORD type)
456 {
457  union link_Packet *buf = (union link_Packet*) mac_buf;
458 
459  SIO_TRACE (("eth_mac_format"));
460 
461  proto = type; /* remember protocol for _eth_send() */
462 
463  /* Clear any remains of an old small packet
464  */
465  memset (&buf->eth.data[0], 0, ETH_MIN-sizeof(eth_Header));
466 
467 #if defined(USE_PPPOE)
468  if (type == IP4_TYPE && pppoe_is_up(mac_dest))
469  {
470  proto = PPPOE_SESS_TYPE;
471  return pppoe_mac_format (buf);
472  }
473 #endif
474 
475  if (mac_dest)
476  memcpy (&buf->eth.head.destination, mac_dest, sizeof(mac_address));
477  memcpy (&buf->eth.head.source, &_eth_addr, sizeof(mac_address));
478 
479  buf->eth.head.type = type;
480  return (&buf->eth.data);
481 }
482 
486 static void *tok_mac_format (void *mac_buf, const void *mac_dest, WORD type)
487 {
488  union link_Packet *buf = (union link_Packet*) mac_buf;
489 
490  SIO_TRACE (("tok_mac_format"));
491 
492  /* No need to clear data behind header.
493  */
494  if (mac_dest)
495  memcpy (&buf->tok.head.destination, mac_dest, sizeof(mac_address));
496  memcpy (&buf->tok.head.source, &_eth_addr, sizeof(mac_address));
497 
498 #if 0
499  /* !!fix me: need to expand the RIF
500  */
501  if (_pktdevclass == PDCLASSS_TOKEN_RIF)
502  ((void)0);
503 #endif
504 
505  buf->tok.head.accessCtrl = TR_AC;
506  buf->tok.head.frameCtrl = TR_FC;
507  buf->tok.head.DSAP = TR_DSAP;
508  buf->tok.head.SSAP = TR_SSAP;
509  buf->tok.head.ctrl = TR_CTRL;
510  buf->tok.head.org[0] = TR_ORG;
511  buf->tok.head.org[1] = TR_ORG;
512  buf->tok.head.org[2] = TR_ORG;
513  buf->tok.head.type = type;
514  proto = type;
515  return (&buf->tok.data);
516 }
517 
521 static void *fddi_mac_format (void *mac_buf, const void *mac_dest, WORD type)
522 {
523  union link_Packet *buf = (union link_Packet*) mac_buf;
524 
525  SIO_TRACE (("fddi_mac_format"));
526 
527  memset (&buf->fddi.data[0], 0, FDDI_MIN-sizeof(fddi_Header));
528  if (mac_dest)
529  memcpy (&buf->fddi.head.destination, mac_dest, sizeof(mac_address));
530  memcpy (&buf->fddi.head.source, &_eth_addr, sizeof(mac_address));
531 
532  buf->fddi.head.frameCtrl = FDDI_FC;
533  buf->fddi.head.DSAP = FDDI_DSAP;
534  buf->fddi.head.SSAP = FDDI_SSAP;
535  buf->fddi.head.ctrl = FDDI_CTRL;
536  buf->fddi.head.org[0] = FDDI_ORG;
537  buf->fddi.head.org[1] = FDDI_ORG;
538  buf->fddi.head.org[2] = FDDI_ORG;
539  buf->fddi.head.type = type;
540  proto = type;
541  return (&buf->fddi.data);
542 }
543 
547 static void *arcnet_mac_format (void *mac_buf, const void *mac_dest, WORD type)
548 {
549  union link_Packet *buf = (union link_Packet*) mac_buf;
550  BYTE dest;
551 
552  if (type == IP4_TYPE) /* Map to DataPoint proto types */
553  type = ARCNET_IP_1201;
554  else if (type == IP6_TYPE)
555  type = ARCNET_IP6;
556  else if (type == ARP_TYPE)
557  type = ARCNET_ARP_1201;
558  else if (type == RARP_TYPE)
559  type = ARCNET_RARP_1201;
560 
561  if (!mac_dest || !memcmp(mac_dest, &_eth_brdcast, sizeof(_eth_brdcast)))
562  dest = 0x00; /* map to ARCNET broadcast */
563  else dest = *(BYTE*)mac_dest; /* Use MSB as destination */
564 
565  buf->arc.head.source = _eth_addr[0];
566  buf->arc.head.destination = dest;
567  buf->arc.head.type = (BYTE) type;
568  buf->arc.head.flags = 0; /* !! */
569  buf->arc.head.sequence = 0; /* !! */
570 #if 0 /* should never be transmitted */
571  buf->arc.head.type2 = type;
572  buf->arc.head.flags2 = 0; /* !! */
573  buf->arc.head.sequence2 = 0; /* !! */
574 #endif
575 
576  proto = (BYTE) type;
577  return (void*) ((BYTE*)&buf->arc + ARC_HDRLEN);
578 }
579 
584 static void *null_mac_format (void *mac_buf, const void *mac_dest, WORD type)
585 {
586  union link_Packet *buf = (union link_Packet*) mac_buf;
587 
588  SIO_TRACE (("null_mac_format"));
589 
590  memset (&buf->ip.head, 0, sizeof(buf->ip.head));
591  ARGSUSED (mac_dest);
592  ARGSUSED (type);
593  proto = IP4_TYPE;
594  return (void*) (&buf->ip.head);
595 }
596 
601 static int eth_mac_xmit (const void *buf, WORD len)
602 {
603  SIO_TRACE (("eth_mac_xmit, len %d", len));
604 
605  if (len < ETH_MIN)
606  len = ETH_MIN; /* zero padding already done in eth_mac_format() */
607  else if (len > ETH_MAX)
608  len = ETH_MAX;
609 
610  return pkt_send (buf, len);
611 }
612 
613 static int fddi_mac_xmit (const void *buf, WORD len)
614 {
615  SIO_TRACE (("fddi_mac_xmit, len %d", len));
616 
617  if (len < FDDI_MIN)
618  len = FDDI_MIN;
619  else if (len > FDDI_MAX)
620  len = FDDI_MAX;
621 
622  return pkt_send (buf, len);
623 }
624 
625 static int arcnet_mac_xmit (const void *buf, WORD len)
626 {
627  SIO_TRACE (("arcnet_mac_xmit, len %d", len));
628 
629  if (len < ARCNET_MIN)
630  len = ARCNET_MIN;
631  else if (len > ARCNET_MAX)
632  len = ARCNET_MAX;
633 
634  return pkt_send (buf, len);
635 }
636 
637 static int tok_mac_xmit (const void *buf, WORD len)
638 {
639  SIO_TRACE (("tok_mac_xmit, len %d", len));
640 
641  if (len > TOK_MAX) /* Token-Ring has no min. length */
642  len = TOK_MAX;
643  return pkt_send (buf, len);
644 }
645 
646 static int null_mac_xmit (const void *buf, WORD len)
647 {
648  SIO_TRACE (("null_mac_xmit, len %d", len));
649 
650  return pkt_send (buf, len);
651 }
652 
653 
659 int W32_CALL _eth_init (void)
660 {
661  int rc;
662 
663  SIO_TRACE (("_eth_init"));
664 
665  if (_eth_is_init)
666  return (0);
667 
668  rc = pkt_eth_init (&_eth_addr);
669  if (rc)
670  return (rc); /* error message already printed */
671 
672  /* Save our MAC-address incase we change it. Change back at exit.
673  */
674  memcpy (_eth_real_addr, _eth_addr, sizeof(_eth_real_addr));
675 
676  switch (_pktdevclass)
677  {
678  case PDCLASS_ETHER:
680  mac_transmit = eth_mac_xmit;
681  break;
682  case PDCLASS_TOKEN:
683  case PDCLASS_TOKEN_RIF:
685  mac_transmit = tok_mac_xmit;
686  break;
687  case PDCLASS_FDDI:
689  mac_transmit = fddi_mac_xmit;
690  break;
691  case PDCLASS_ARCNET:
693  mac_transmit = arcnet_mac_xmit;
694  break;
695  case PDCLASS_SLIP:
696  case PDCLASS_PPP:
697  case PDCLASS_AX25: /* !! for now */
699  mac_transmit = null_mac_xmit;
700  break;
701  default:
702  outsnl (_LANG("No supported driver class found"));
703  return (WERR_NO_DRIVER);
704  }
705 
706  memset (TX_BUF(), 0, sizeof(union link_Packet));
707  memset (&_eth_brdcast, 0xFF, sizeof(_eth_brdcast));
708  _eth_loop_addr[0] = 0xCF;
709  pkt_buf_wipe();
710 
711  if (!_eth_get_hwtype(NULL, &_eth_mac_len))
712  _eth_mac_len = sizeof(eth_address);
713 
714 #if defined(__MSDOS__)
715  if (!strcmp(_pktdrvrname,"NDIS3PKT"))
716  _eth_ndis3pkt = TRUE;
717 
718  else if (!strcmp(_pktdrvrname,"SwsVpkt"))
719  _eth_SwsVpkt = TRUE;
720 #endif
721 
722  _eth_is_init = TRUE;
723  RUNDOWN_ADD (__eth_release, 10);
724 
725  return (0); /* everything okay */
726 }
727 
731 int W32_CALL _eth_set_addr (const void *addr)
732 {
733  SIO_TRACE (("_eth_set_addr"));
734 
735  if (_pktserial || _pktdevclass == PDCLASS_ARCNET)
736  return (1);
737 
738  if (pkt_set_addr(addr))
739  {
740  memcpy (_eth_addr, addr, sizeof(_eth_addr));
741  return (1);
742  }
743  return (0);
744 }
745 
746 
751 BYTE W32_CALL _eth_get_hwtype (BYTE *hwtype, BYTE *hwlen)
752 {
753  SIO_TRACE (("_eth_get_hwtype"));
754 
755  if (_pktdevclass == PDCLASS_ETHER)
756  {
757  if (hwlen) *hwlen = sizeof (eth_address);
758  if (hwtype) *hwtype = HW_TYPE_ETHER;
759  return (HW_TYPE_ETHER);
760  }
761  if (_pktdevclass == PDCLASS_FDDI)
762  {
763  if (hwlen) *hwlen = sizeof (fddi_address);
764  if (hwtype) *hwtype = HW_TYPE_FDDI;
765  return (HW_TYPE_FDDI);
766  }
767  if (_pktdevclass == PDCLASS_TOKEN || _pktdevclass == PDCLASS_TOKEN_RIF)
768  {
769  if (hwlen) *hwlen = sizeof (tok_address);
770  if (hwtype) *hwtype = HW_TYPE_TOKEN;
771  return (HW_TYPE_TOKEN);
772  }
773  if (_pktdevclass == PDCLASS_AX25)
774  {
775  if (hwlen) *hwlen = sizeof (ax25_address);
776  if (hwtype) *hwtype = HW_TYPE_AX25;
777  return (HW_TYPE_AX25);
778  }
779  if (_pktdevclass == PDCLASS_ARCNET)
780  {
781  if (hwlen) *hwlen = sizeof (arcnet_address); /* 1 byte */
782  if (hwtype) *hwtype = HW_TYPE_ARCNET;
783  return (HW_TYPE_ARCNET);
784  }
785  return (0);
786 }
787 
788 
792 void W32_CALL _eth_free (const void *pkt)
793 {
794  SIO_TRACE (("_eth_free"));
795 
796  if (_eth_recv_hook) /* hook-function should free it's own packet */
797  return;
798 
799  if (!pkt)
800  pkt_buf_wipe(); /* restart the queue */
801  else pkt_free_pkt (pkt);
802 }
803 
804 
810 #define RCF DSAP /* Routing Control where DSAP is when no routing */
811 
812 #define TR_IS_SROUTED(th) ((th)->source[0] & 0x80)
813 #define TR_IS_BROADCAST(th) (((intel16((th)->RCF) & 0xE000) >> 13) >= 4)
814 #define TR_RIF_LENGTH(th) ((intel16((th)->RCF) & 0x1F00) >> 8)
815 
816 #define TR_MAC_SIZE (2+2+2*sizeof(mac_address)) /* AC,FC,src/dst */
817 
818 static void fix_tok_head (tok_Header **trp)
819 {
820  tok_Header *tr = *trp;
821 
822 #if defined(USE_DEBUG)
823  const BYTE *raw = (const BYTE*)tr;
824  int i;
825 
826  dbug_write ("TR raw: ");
827  for (i = 0; i < 50; i++)
828  dbug_printf ("%02X ", raw[i]);
829  dbug_write ("\n");
830 #endif
831 
832  SIO_TRACE (("fix_tok_head"));
833 
834  if (TR_IS_SROUTED(tr)) /* Source routed */
835  {
836  int rlen = TR_RIF_LENGTH (tr);
837 
838  tr->source[0] &= 0x7F; /* clear RII bit */
839 
840  /* Set our notion of link-layer broadcast
841  */
842  if (TR_IS_BROADCAST(tr))
843  tr->destination[0] |= 1;
844 
845  /* Copy MAC-header rlen bytes upwards
846  */
847  memmove ((BYTE*)tr + rlen, tr, TR_MAC_SIZE);
848  *trp = (tok_Header*) ((BYTE*)tr + rlen);
849  }
850 }
851 
852 /*
853  * Check (and fix?) the received ARCNET header.
854  * All frames must have a common layout with headlen ARC_HDRLEN.
855  */
856 static BOOL fix_arc_head (const arcnet_Header *head, WORD *type)
857 {
858 #if defined(USE_DEBUG)
859  const BYTE *raw = (const BYTE*)head;
860  int i;
861 
862  dbug_write ("ARC raw: ");
863  for (i = 0; i < 50; i++)
864  dbug_printf ("%02X ", raw[i]);
865  dbug_write ("\n");
866 #endif
867 
868  *type = head->type;
869 
870  /* Map to IANA numbers
871  */
872  if (*type == ARCNET_IP_1051 || *type == ARCNET_IP_1201)
873  *type = IP4_TYPE;
874  if (*type == ARCNET_ARP_1051 || *type == ARCNET_ARP_1201)
875  *type = ARP_TYPE;
876 
877  if (head->flags == 0xFF || /* Exception packet */
878  (*type != IP4_TYPE && /* Neither IP nor ARP */
879  *type != ARP_TYPE))
880  return (FALSE);
881  return (TRUE);
882 }
883 
895 static union link_Packet *poll_recv_queue (WORD *type)
896 {
897 #if defined(USE_FAST_PKT) || defined(WIN32)
898  struct pkt_rx_element *buf;
899 #endif
900  struct pkt_ringbuf *q = &_pkt_inf->pkt_queue;
901  union link_Packet *pkt;
902  struct in_Header *ip;
903 
904  SIO_TRACE (("poll_recv_queue"));
905 
906  ASSERT_PKT_INF (NULL);
907 
908 #if defined(USE_DEBUG)
909 #if defined(USE_FAST_PKT)
910  if (!pktq_far_check(q)) /* MSDOS only */
911 #else
912  if (!pktq_check(q))
913 #endif
914  {
915  fprintf (stderr, "%s: pkt-queue destroyed!\n", __FILE__);
916  exit (-1);
917  }
918 #endif /* USE_DEBUG */
919 
920 #if defined(WIN32)
921  buf = pkt_poll_recv();
922  if (!buf)
923  return (NULL);
924 
925  PROFILE_RECV (buf->tstamp_put, buf->tstamp_get);
926  _eth_last.rx.size = buf->rx_length;
927  memcpy (&_eth_last.rx.tstamp, &buf->tstamp_put, sizeof(_eth_last.rx.tstamp));
928  pkt = (link_Packet*) &buf->rx_buf[0];
929 
930 #elif defined(USE_FAST_PKT)
931  buf = pkt_poll_recv();
932  if (!buf)
933  return (NULL);
934 
935  PROFILE_RECV (*(uint64*)&buf->tstamp_put, *(uint64*)&buf->tstamp_get);
936  pkt = (link_Packet*) buf->rx_buf;
937  _eth_last.rx.size = buf->rx_length_1; /* length on 1st upcall */
938  _eth_last.rx.tstamp.lo = buf->tstamp_put[0]; /* TSC set in asmpkt */
939  _eth_last.rx.tstamp.hi = buf->tstamp_put[1];
940 
941 #else
942  if (!pktq_queued(q))
943  return (NULL);
944 
945  pkt = (link_Packet*) pktq_out_buf (q);
946  _eth_last.rx.size = ETH_MAX; /* !! wrong, but doesn't matter for pcap */
947  _eth_last.rx.tstamp.lo = 0UL; /* pcdbug.c writes rx-time == dbg-time */
948  _eth_last.rx.tstamp.hi = 0UL;
949 #endif
950 
951 
952  if (_pktserial)
953  {
954  ip = &pkt->ip.head; /* SLIP/PPP/AX25 */
955  *type = (ip->ver == 4) ? IP4_TYPE : IP6_TYPE;
956  return (pkt);
957  }
958 
959  if (_pktdevclass == PDCLASS_TOKEN || _pktdevclass == PDCLASS_TOKEN_RIF)
960  {
961  tok_Header *tr = &pkt->tok.head;
962 
963  fix_tok_head (&tr);
964  *type = tr->type;
965  return (union link_Packet*) tr;
966  }
967 
968  if (_pktdevclass == PDCLASS_ARCNET)
969  {
970  arcnet_Packet *arc = &pkt->arc;
971 
972  if (!fix_arc_head(&arc->head, type))
973  {
974  DEBUG_RX (NULL, &arc->data);
975  pkt_free_pkt (pkt);
976  pkt = NULL;
977  }
978  return (pkt);
979  }
980 
981  if (_pktdevclass == PDCLASS_FDDI)
982  {
983  fddi_Packet *fddi = &pkt->fddi;
984 
985  *type = fddi->head.type;
986  return (pkt);
987  }
988 
989  /* must be PDCLASS_ETHER */
990 
991  *type = pkt->eth.head.type;
992  ARGSUSED (q);
993  return (pkt);
994 }
995 
996 /*
997  * Fix the LLC header to look like ordinary Ethernet II
998  * !! not yet.
999  */
1000 static void fix_llc_head (void **mac)
1001 {
1002  SIO_TRACE (("fix_llc_head"));
1003 #if 1
1004  DEBUG_RX (NULL, *mac);
1005  _eth_free (*mac);
1006  *mac = NULL;
1007 #else
1008 
1010 #endif
1011 }
1012 
1013 
1026 void * W32_CALL _eth_arrived (WORD *type_ptr, BOOL *broadcast)
1027 {
1028  union link_Packet *pkt;
1029  mac_address *dst;
1030  void *ret = NULL;
1031  BOOL is_bcast = FALSE;
1032  WORD type = 0;
1033 
1034  SIO_TRACE (("_eth_arrived"));
1035 
1036  if (!_eth_is_init) /* GvB 2002-09, Lets us run without a working driver */
1037  return (NULL);
1038 
1039  if (_eth_recv_hook)
1040  pkt = (union link_Packet*) (*_eth_recv_hook) (&type);
1041  else pkt = poll_recv_queue (&type);
1042 
1043  if (!pkt)
1044  return (NULL);
1045 
1046  if (_eth_recv_peek && !(*_eth_recv_peek)(pkt))
1047  {
1048  _eth_free (pkt);
1049  return (NULL);
1050  }
1051 
1052  /* Hack: If _ip?_handler() can't be reentered, only accept
1053  * non-IP packets. Assume PPPoE session packets carries only IP.
1054  */
1055  if (_ip_recursion &&
1056  (type == IP4_TYPE || type == IP6_TYPE || type == PPPOE_SESS_TYPE))
1057  {
1059  STAT (macstats.num_ip_recurse++);
1060  _eth_free (pkt);
1061  return (NULL);
1062  }
1063 
1064  if (_pktserial)
1065  {
1066  dst = NULL;
1067  ret = (void*) &pkt->ip;
1068  }
1069  else if (_pktdevclass == PDCLASS_TOKEN || _pktdevclass == PDCLASS_TOKEN_RIF)
1070  {
1071  dst = &pkt->tok.head.destination;
1072  ret = (void*) &pkt->tok.data;
1073  }
1074  else if (_pktdevclass == PDCLASS_FDDI)
1075  {
1076  dst = &pkt->fddi.head.destination;
1077  ret = (void*) &pkt->fddi.data;
1078  }
1079  else if (_pktdevclass == PDCLASS_ARCNET)
1080  {
1081  dst = (mac_address*) &pkt->arc.head.destination;
1082  ret = (void*) ((BYTE*)pkt + ARC_HDRLEN);
1083  }
1084  else /* must be ether */
1085  {
1086  dst = &pkt->eth.head.destination;
1087  ret = (void*) &pkt->eth.data;
1088  }
1089 
1090 #if defined(NEED_PKT_SPLIT)
1091  pkt_split_mac_in (pkt);
1092 #endif
1093 
1094 #if defined(USE_STATISTICS)
1095  update_in_stat();
1096 #endif
1097 
1098 #if defined(NEED_PKT_SPLIT) && defined(USE_DEBUG) && 0 /* test */
1099  pkt_print_split_in();
1100 #endif
1101 
1102  /* ARCnet should never have LLC fields. So don't test for it
1103  */
1104  if (_pktdevclass != PDCLASS_ARCNET)
1105  {
1106  if (dst && !memcmp(dst, &_eth_brdcast, sizeof(_eth_brdcast)))
1107  is_bcast = TRUE;
1108 
1109  if (intel16(type) < 0x600) /* LLC length field */
1110  fix_llc_head (&ret);
1111  }
1112  else if (dst && *(BYTE*)dst == 0) /* ARCnet broadcast */
1113  {
1114  is_bcast = TRUE;
1115  }
1116 
1117  if (type_ptr)
1118  *type_ptr = type;
1119 
1120  if (broadcast)
1121  *broadcast = is_bcast;
1122 
1123  return (ret);
1124 }
1125 
1126 
1127 #if defined(NOT_USED)
1128 
1131 void *_eth_mac_hdr (const in_Header *ip)
1132 {
1133  SIO_TRACE (("_eth_mac_hdr"));
1134 
1135  if (!_pktserial)
1136  return (void*) ((BYTE*)ip - _pkt_ip_ofs);
1137 
1138  (*_printf) ("Illegal use of `_eth_mac_hdr()' for class %d\n",
1139  _pktdevclass);
1140  exit (-1);
1141  /*@-unreachable@*/
1142  return (NULL);
1143 }
1144 
1148 void *_eth_mac_dst (const in_Header *ip)
1149 {
1150  const union link_Packet *pkt;
1151 
1152  SIO_TRACE (("_eth_mac_dst"));
1153 
1154  pkt = (const union link_Packet*) ((BYTE*)ip - _pkt_ip_ofs);
1155 
1156  if (_pktdevclass == PDCLASS_ETHER)
1157  return (void*) &pkt->eth.head.destination;
1158 
1159  if (_pktdevclass == PDCLASS_TOKEN || _pktdevclass == PDCLASS_TOKEN_RIF)
1160  return (void*) &pkt->tok.head.destination;
1161 
1162  if (_pktdevclass == PDCLASS_FDDI)
1163  return (void*) &pkt->fddi.head.destination;
1164 
1165  if (_pktdevclass == PDCLASS_ARCNET)
1166  return (void*) &pkt->arc.head.destination;
1167 
1168  (*_printf) ("Illegal use of `_eth_mac_dst()' for class %d\n",
1169  _pktdevclass);
1170  exit (-1);
1171  /*@-unreachable@*/
1172  return (NULL);
1173 }
1174 
1178 void *_eth_mac_src (const in_Header *ip)
1179 {
1180  const union link_Packet *pkt;
1181 
1182  SIO_TRACE (("_eth_mac_src"));
1183 
1184  pkt = (const union link_Packet*) ((BYTE*)ip - _pkt_ip_ofs);
1185 
1186  if (_pktdevclass == PDCLASS_ETHER)
1187  return (void*) &pkt->eth.head.source;
1188 
1189  if (_pktdevclass == PDCLASS_TOKEN || _pktdevclass == PDCLASS_TOKEN_RIF)
1190  return (void*) &pkt->tok.head.source;
1191 
1192  if (_pktdevclass == PDCLASS_FDDI)
1193  return (void*) &pkt->fddi.head.source;
1194 
1195  if (_pktdevclass == PDCLASS_ARCNET)
1196  return (void*) &pkt->arc.head.source;
1197 
1198  (*_printf) ("Illegal use of `_eth_mac_src()' for class %d\n",
1199  _pktdevclass);
1200  exit (-1);
1201  /*@-unreachable@*/
1202  return (NULL);
1203 }
1204 
1209 {
1210  const union link_Packet *pkt;
1211 
1212  SIO_TRACE (("_eth_mac_typ"));
1213 
1214  pkt = (const union link_Packet*) ((BYTE*)ip - _pkt_ip_ofs);
1215 
1216  if (_pktdevclass == PDCLASS_ETHER)
1217  return (pkt->eth.head.type);
1218 
1219  if (_pktdevclass == PDCLASS_TOKEN || _pktdevclass == PDCLASS_TOKEN_RIF)
1220  return (pkt->tok.head.type);
1221 
1222  if (_pktdevclass == PDCLASS_FDDI)
1223  return (pkt->fddi.head.type);
1224 
1225  if (_pktdevclass == PDCLASS_ARCNET)
1226  return (pkt->arc.head.type);
1227 
1228  (*_printf) ("Illegal use of `_eth_mac_typ()' for class %d\n",
1229  _pktdevclass);
1230  exit (-1);
1231  /*@-unreachable@*/
1232  return (0);
1233 }
1234 #endif /* NOT_USED */
1235 
1236 
1237 /*
1238  * Jim Martin's Multicast extensions
1239  */
1240 
1241 #if defined(USE_MULTICAST)
1242 
1248 BOOL _eth_join_mcast_group (const struct MultiCast *mc)
1249 {
1250  eth_address list [IPMULTI_SIZE];
1251  int i, len, nextentry;
1252  BOOL is_mcast1, is_mcast2, is_promis;
1253 
1254  SIO_TRACE (("_eth_join_mcast_group"));
1255 
1256  /* Return if we're already receiving all multicasts or is in
1257  * promiscous mode.
1258  */
1259 #if defined(WIN32)
1260  is_mcast1 = (_pkt_rxmode & RXMODE_MULTICAST1);
1261  is_mcast2 = (_pkt_rxmode & RXMODE_MULTICAST2);
1262  is_promis = (_pkt_rxmode & RXMODE_PROMISCOUS);
1263 #else
1264  is_mcast1 = (_pkt_rxmode >= RXMODE_MULTICAST1);
1265  is_mcast2 = (_pkt_rxmode >= RXMODE_MULTICAST2);
1266  is_promis = (_pkt_rxmode >= RXMODE_PROMISCOUS);
1267 #endif
1268 
1269  if (is_mcast2 || is_promis)
1270  return (TRUE);
1271 
1272  if (!is_mcast1)
1273  {
1274  is_mcast1 = pkt_set_rcv_mode(RXMODE_MULTICAST1);
1275  if (!is_mcast1)
1276  is_promis = pkt_set_rcv_mode(RXMODE_PROMISCOUS);
1277  if (is_promis)
1278  return (TRUE);
1279  if (!is_mcast1 && !is_promis)
1280  return (FALSE); /* hopeless, give up */
1281  }
1282 
1283  len = sizeof(list);
1284  if (!pkt_get_multicast_list (list, &len))
1285  {
1286  /* If no MC support, switch to MC2 mode
1287  */
1288  if (_pkt_errno == PDERR_NO_MULTICAST)
1290  return (FALSE);
1291  }
1292 
1293  /* check to see if the address is already in the list
1294  */
1295  for (i = 0; i < len / SIZEOF(list[0]); i++)
1296  if (!memcmp(list[i], &mc->ethaddr, sizeof(list[0])))
1297  return (TRUE);
1298 
1299  if (len > 0)
1300  nextentry = len / sizeof(list[0]); /* append entry */
1301  else nextentry = 0;
1302 
1303  memcpy (&list[nextentry], &mc->ethaddr, sizeof(eth_address));
1304  len += sizeof (list[0]);
1305 
1306  if (!pkt_set_multicast_list((const eth_address*)&list,len))
1307  {
1308  /* If no space or no MC support, switch to MC2 mode
1309  */
1310  if (_pkt_errno == PDERR_NO_SPACE ||
1311  _pkt_errno == PDERR_NO_MULTICAST)
1313  return (FALSE);
1314  }
1315  return (TRUE);
1316 }
1317 
1324 BOOL _eth_leave_mcast_group (const struct MultiCast *mc)
1325 {
1326  eth_address list[IPMULTI_SIZE];
1327  int i, len, idx;
1328 
1329  SIO_TRACE (("_eth_leave_mcast_group"));
1330 
1331  /* \note This should be expanded to include switching back to
1332  * RXMODE_MULTCAST1 if the list of multicast addresses has
1333  * shrunk sufficiently.
1334  *
1335  * First check to see if we're in RXMODE_MULTICAST2. if so return
1336  */
1337 #if defined(WIN32)
1339  return (TRUE);
1340 #else
1341  if (_pkt_rxmode >= RXMODE_MULTICAST2)
1342  return (TRUE);
1343 #endif
1344 
1345  /* get the list of current multicast addresses
1346  */
1347  len = sizeof(list);
1348  if (!pkt_get_multicast_list (list, &len))
1349  return (FALSE);
1350 
1351  /* find the apropriate entry
1352  */
1353  for (i = 0, idx = -1; i < len/SIZEOF(list[0]); i++)
1354  if (!memcmp(list[i],&mc->ethaddr,sizeof(list[0])))
1355  idx = i;
1356 
1357  /* if it's not in the list, just return
1358  */
1359  if (idx == -1)
1360  return (TRUE);
1361 
1362  /* ahh, but it _is_ in the list. So shorten the list
1363  * and send it back to the PKTDRVR
1364  */
1365  if (idx+1 < len/SIZEOF(list[0]))
1366  memmove (&list[idx], &list[idx+1], len-(idx+1)*sizeof(list[0]));
1367 
1368  len -= sizeof(list[0]);
1369 
1370  if (!pkt_set_multicast_list((const eth_address*)&list, len))
1371  {
1372  /* If no space or no MC support, switch mode
1373  */
1374  if (_pkt_errno == PDERR_NO_SPACE ||
1375  _pkt_errno == PDERR_NO_MULTICAST)
1376  return pkt_set_rcv_mode (RXMODE_MULTICAST2);
1377  return (FALSE);
1378  }
1379  return (TRUE);
1380 }
1381 #endif /* USE_MULTICAST */
1382 
1387 #include "nochkstk.h"
1388 
1389 static void __eth_release (void)
1390 {
1391  _eth_release();
1392 }
1393 
1397 void W32_CALL _eth_release (void)
1398 {
1399  if (!_eth_is_init)
1400  return;
1401 
1402  /* Set original MAC address (if not fatal-error or serial-driver)
1403  */
1404  if (!_watt_fatal_error)
1405  {
1406  if (!_pktserial)
1407  {
1408  if (memcmp(&_eth_addr, &_eth_real_addr, sizeof(_eth_addr)))
1410 
1411 #if defined(USE_MULTICAST) || defined(USE_IPV6) /* restore startup Rx mode */
1412  if (_pkt_rxmode0 > -1 && _pkt_rxmode0 != _pkt_rxmode)
1414 #endif
1415  }
1416 
1417 #if defined(USE_DEBUG)
1418  if (debug_on > 0)
1419  {
1420  DWORD drops = pkt_dropped();
1421  if (drops)
1422  (*_printf) ("%lu packets dropped\n", drops);
1423  }
1424 #endif
1425  }
1426  _eth_is_init = FALSE; /* in case we crash in pkt_release() */
1427  pkt_release();
1428 }
1429 
mac_address _eth_brdcast
Link-layer broadcast address.
Definition: pcsed.c:51
static void *(* mac_tx_format)(void *mac_buf, const void *mac_dest, WORD type)
Pointer to functions that does the filling of correct MAC-header and sends the link-layer packet...
Definition: pcsed.c:99
void W32_CALL _eth_free(const void *pkt)
Free an input buffer once it is no longer needed.
Definition: pcsed.c:792
Multicast internal structure.
Definition: pcigmp.h:115
BOOL _eth_winpcap
for Win32 using an WinPcap adapter (default)
Definition: pcsed.c:61
static void * fddi_mac_format(void *mac_buf, const void *mac_dest, WORD type)
Format the MAC-header for FDDI.
Definition: pcsed.c:521
void update_out_stat(void)
Definition: pcstat.c:724
BOOL pppoe_is_up(const void *dest)
Determine if we have a PPPoE session with the machine given by 'dest'.
Definition: pppoe.c:287
BYTE W32_CALL _eth_get_hwtype(BYTE *hwtype, BYTE *hwlen)
Fill in hardware address type/length for BOOTP/DHCP packets.
Definition: pcsed.c:751
BOOL _eth_wanpacket
for Win32 using an WanPacket adapter
Definition: pcsed.c:60
int pkt_get_multicast_list(mac_address *listbuf, int *lenp)
Gets the current list of multicast addresses from the PKTDRVR.
Definition: pcpkt.c:2037
int pkt_set_rcv_mode(int mode)
Sets the receive mode of the interface.
Definition: pcpkt.c:1955
int W32_CALL _eth_send(WORD len, const void *sock, const char *file, unsigned line)
_eth_send() does the actual transmission once we are complete with filling the buffer.
Definition: pcsed.c:306
int pkt_buf_wipe(void)
Clear the receive queue.
Definition: pcpkt.c:1334
int pkt_eth_init(mac_address *addr)
Initialise Packet driver interface.
Definition: pcpkt.c:1449
BOOL _eth_ndis3pkt
for DOS-programs only
Definition: pcsed.c:57
static void __eth_release(void)
Turn off stack-checking because _eth_release() might be called from an exception handler.
Definition: pcsed.c:1389
BOOL has_rdtsc
Never set in Watt-32.
Definition: timer.c:52
int pkt_set_multicast_list(const void *listbuf, int len)
Sets the list of multicast addresses for which the PKTDRVR is responsible.
Definition: pcpkt.c:2084
mac_address _eth_real_addr
Our real MAC address.
Definition: pcsed.c:53
int pkt_set_addr(const void *addr)
Set a new MAC source address.
Definition: pcpkt.c:1198
int pkt_send(const void *tx, int length)
Send a link-layer frame.
Definition: pcpkt.c:1090
eth_address ethaddr
Ethernet address of group.
Definition: pcigmp.h:117
Core definitions.
DWORD pkt_dropped(void)
Return number of packets dropped.
Definition: pcpkt.c:1394
mac_address _eth_addr
Local link-layer source address.
Definition: pcsed.c:50
BOOL _eth_join_mcast_group(const struct MultiCast *mc)
Joins a multicast group (at the physical layer).
Definition: pcsed.c:1248
BOOL _ip_recursion
avoid recursion in arp_resolve()
Definition: pcsed.c:56
unsigned long long uint64
our unsigned "long long" type
Definition: wattcp.h:60
static union link_Packet * poll_recv_queue(WORD *type)
Poll the packet queue.
Definition: pcsed.c:895
static void * eth_mac_format(void *mac_buf, const void *mac_dest, WORD type)
Format the MAC-header for Ethernet.
Definition: pcsed.c:455
void *W32_CALL _eth_formatpacket(const void *mac_dest, WORD eth_type)
_eth_format_packet() places the next packet to be transmitted into the above link-layer output packet...
Definition: pcsed.c:135
void *W32_CALL * _eth_recv_hook(WORD *type)
Pointer to functions that when set changes the behaviour of polling and send functions _eth_arrived()...
BYTE _eth_mac_len
Size of a MAC address.
Definition: pcsed.c:54
Definition: ip.h:67
char _pktdrvrname[20]
Name of PKDRVR.
Definition: pcpkt.c:62
void * _eth_mac_src(const in_Header *ip)
Return pointer to MAC source address of an IP packet.
Definition: pcsed.c:1178
mac_address _eth_loop_addr
Link-layer loopback address.
Definition: pcsed.c:52
static int eth_mac_xmit(const void *buf, WORD len)
Functions called via function pointer `mac_transmit' to actually send the data.
Definition: pcsed.c:601
WORD _pktdevclass
Ethernet, Token, FDDI etc.
Definition: pcpkt.c:51
WORD _eth_mac_typ(const in_Header *ip)
Return value of protocol-type given an IP packet.
Definition: pcsed.c:1208
BOOL _pktserial
using serial driver, SLIP/PPP
Definition: pcpkt.c:54
BOOL _eth_leave_mcast_group(const struct MultiCast *mc)
Leaves a multicast group (at the physical layer)
Definition: pcsed.c:1324
void * pppoe_mac_format(union link_Packet *tx)
Build a PPPoE session packet header.
Definition: pppoe.c:377
BOOL _eth_SwsVpkt
for DOS and Win32 programs
Definition: pcsed.c:58
int _pkt_rxmode0
startup receive mode
Definition: pcpkt.c:57
struct pkt_info * _pkt_inf
module data that will be locked
Definition: pcpkt.c:64
int _pkt_errno
error code set in pcpkt.c API
Definition: pcpkt.c:58
int DTOR pkt_release(void)
Definition: pcpkt.c:838
BROADCAST + all multicast.
Definition: pcpkt.h:113
BOOL _eth_is_init
we are initialised
Definition: pcsed.c:55
receive all packets on network
Definition: pcpkt.h:114
BOOL _watt_fatal_error
Definition: misc.c:60
static void * tok_mac_format(void *mac_buf, const void *mac_dest, WORD type)
Format the MAC-header for Token-Ring.
Definition: pcsed.c:486
void pkt_free_pkt(const void *pkt)
Release a packet from the receive queue.
Definition: pcpkt.c:1349
int _pkt_rxmode
active receive mode
Definition: pcpkt.c:56
static void * arcnet_mac_format(void *mac_buf, const void *mac_dest, WORD type)
Format the MAC-header for ARCNET.
Definition: pcsed.c:547
int W32_CALL _eth_init(void)
Initialize the network driver interface.
Definition: pcsed.c:659
void update_in_stat(void)
Definition: pcstat.c:583
static int send_loopback(link_Packet pkt, BOOL is_ip6, unsigned *err_line)
Enqueue a link-layer frame (IPv4/v6 only) to the internal loopback device.
Definition: pcsed.c:154
struct _eth_last_info _eth_last
Sizes and timestamps of last packet recv/sent.
Definition: pcsed.c:68
void W32_CALL _eth_release(void)
Release the hardware driver.
Definition: pcsed.c:1397
BOOL _eth_airpcap
for Win32 using the AirPcap adapter
Definition: pcsed.c:59
int W32_CALL _eth_set_addr(const void *addr)
Sets a new MAC address for our interface.
Definition: pcsed.c:731
void *W32_CALL _eth_arrived(WORD *type_ptr, BOOL *broadcast)
Poll for arrival of new packets (IP/ARP/RARP/PPPoE protocol).
Definition: pcsed.c:1026
void * _eth_mac_dst(const in_Header *ip)
Return pointer to MAC destination address of an IP packet.
Definition: pcsed.c:1148
WORD _pkt_ip_ofs
ofs from link-layer head to ip
Definition: pcpkt.c:52
static void * null_mac_format(void *mac_buf, const void *mac_dest, WORD type)
Format MAC-header for protocols without MAC-headers.
Definition: pcsed.c:584
static void fix_llc_head(void **mac)
Definition: pcsed.c:1000
void * _eth_mac_hdr(const in_Header *ip)
Return pointer to MAC header start address of an IP packet.
Definition: pcsed.c:1131
BROADCAST + limited multicast.
Definition: pcpkt.h:112