PCPKT.C
上传用户:better800
上传日期:2022-06-13
资源大小:1853k
文件大小:8k
源码类别:

TCP/IP协议栈

开发平台:

DOS

  1. // FRAGSUPPORT enables support for packet reassembly of fragmented packets
  2. #define FRAGSUPPORT
  3. #include <copyright.h>
  4. #include <wattcp.h>
  5. #include <elib.h>
  6. #include <dos.h>
  7. #ifdef __BORLANDC__
  8. #include <mem.h>
  9. #endif
  10. #include <string.h>
  11. #include <stdlib.h>
  12. #ifdef LARGE
  13. #define MAXBUFS        25       /* maximum number of Ethernet buffers */
  14. #else
  15. #define MAXBUFS        10
  16. #endif
  17. #define BUFSIZE     1600
  18. #define DOS         0x21
  19. #define GETVECT     0x35
  20. #define INT_FIRST 0x60
  21. #define INT_LAST  0x80
  22. #define PD_DRIVER_INFO 0x1ff
  23. #define PD_ACCESS  0x200
  24. #define PD_RELEASE 0x300
  25. #define PD_SEND 0x400
  26. #define PD_GET_ADDRESS 0x600
  27. #define  CARRY  1      /* carry bit in flags register */
  28. word _pktipofs = 0; /* offset from header to start of pkt */
  29. word pkt_interrupt;
  30. word pkt_ip_type = 0x0008; /* these are intelled values */
  31. word pkt_arp_type = 0x608;
  32. #ifdef LARGE
  33. byte far pktbuf[MAXBUFS][ BUFSIZE + 2 ];    /* first byte is busy flag, 2nd spare */
  34. #else
  35. byte pktbuf[ MAXBUFS][ BUFSIZE + 2];
  36. #endif
  37. word  pkt_ip_handle;
  38. word  pkt_arp_handle;
  39. //byte eth_addr[ 6 ] ;     // 94.11.19
  40. eth_address eth_addr;
  41. longword far *interrupts = 0L;
  42. char *pkt_line = "PKT DRVR";
  43. // fragfix -- just a note this is intel
  44. #define IP_DF       0x0040      // Don't fragment bit set for FRAG Flags
  45. // forwards and externs
  46. int pkt_init( void );
  47. extern void _pktentry();                          /* see asmpkt.asm */
  48. extern void _pktasminit( void far *, int, int );  /* see asmpkt.asm */
  49. static int pkt_init( void )       /* 94.11.27 -- made static */
  50. {
  51.     struct REGPACK regs, regs2;
  52.     char far *temp;
  53.     int pd_type; /* packet driver type */
  54.     int class;
  55.     _pktasminit( pktbuf, MAXBUFS, BUFSIZE );
  56.     for (pkt_interrupt = INT_FIRST; pkt_interrupt <= INT_LAST; ++pkt_interrupt ) {
  57.         temp = (char far *)getvect( pkt_interrupt );
  58.         if ( ! _fmemcmp( &(temp[3]), pkt_line, strlen( pkt_line )))
  59.             break;
  60.     }
  61.     if ( pkt_interrupt > INT_LAST ) {
  62.         outs("NO PACKET DRIVER FOUNDrn");
  63. return( 1 );
  64.     }
  65.     /* lets find out about the driver */
  66.     regs.r_ax = PD_DRIVER_INFO;
  67.     intr( pkt_interrupt, &regs );
  68.     /* handle old versions, assume a class and just keep trying */
  69.     if (regs.r_flags & CARRY ) {
  70. for ( class = 0; class < 2; ++class ) {
  71.     _pktdevclass = (class) ? PD_SLIP : PD_ETHER;
  72.     for (pd_type = 1; pd_type < 128; ++pd_type ) {
  73. regs.r_ax = PD_ACCESS | _pktdevclass;  /* ETH, SLIP */
  74. regs.r_bx = pd_type; /* type */
  75. regs.r_dx = 0; /* if number */
  76.                 regs.r_cx = (_pktdevclass == PD_SLIP ) ? 0 : sizeof( pkt_ip_type);
  77. regs.r_ds = FP_SEG( &pkt_ip_type );
  78. regs.r_si = FP_OFF( &pkt_ip_type );
  79.                 regs.r_es = FP_SEG( _pktentry);
  80. regs.r_di = FP_OFF( _pktentry);
  81. intr( pkt_interrupt, &regs );
  82. if ( ! (regs.r_flags & CARRY) ) break;
  83.     }
  84.     if (pd_type == 128 ) {
  85. outs("ERROR initializing packet drivernr");
  86. return( 1 );
  87.     }
  88.     /* we have found a working type, so kill it */
  89.     regs.r_bx = regs.r_ax; /* handle */
  90.     regs.r_ax = PD_RELEASE;
  91.     intr( pkt_interrupt, &regs );
  92. }
  93.     } else {
  94. pd_type = regs.r_dx;
  95. switch ( _pktdevclass = (regs.r_cx >> 8)) {
  96.     case PD_ETHER : _pktipofs = 14;
  97.             case PD_SLIP  : break;
  98.             default       : outs("ERROR: only Ethernet or SLIP packet drivers allowednr");
  99.     return( 1 );
  100. }
  101.     }
  102.     regs.r_ax = PD_ACCESS | _pktdevclass;
  103.     regs.r_bx = 0xffff;                 /* any type */
  104.     regs.r_dx = 0; /* if number */
  105.     regs.r_cx = (_pktdevclass == PD_SLIP) ? 0 : sizeof( pkt_ip_type );
  106.     regs.r_ds = FP_SEG( &pkt_ip_type );
  107.     regs.r_si = FP_OFF( &pkt_ip_type );
  108.     regs.r_es = FP_SEG( _pktentry);
  109.     regs.r_di = FP_OFF( _pktentry);
  110.     memcpy( &regs2, &regs, sizeof( regs ));
  111.     regs2.r_si = FP_OFF( &pkt_arp_type );
  112.     regs2.r_ds = FP_SEG( &pkt_arp_type );
  113.     intr( pkt_interrupt, &regs );
  114.     if ( regs.r_flags & CARRY ) {
  115. outs("ERROR # 0x");
  116. outhex( regs.r_dx >> 8 );
  117. outs(" accessing packet drivernr" );
  118. return( 1 );
  119.     }
  120.     pkt_ip_handle = regs.r_ax;
  121.     if (_pktdevclass != PD_SLIP) {
  122. intr( pkt_interrupt, &regs2 );
  123. if ( regs2.r_flags & CARRY ) {
  124.     regs.r_ax = PD_RELEASE;
  125.     regs.r_bx = pkt_ip_handle;
  126.     intr( pkt_interrupt, &regs );
  127.     outs("ERROR # 0x");
  128.     outhex( regs2.r_dx >> 8 );
  129.     outs(" accessing packet drivernr" );
  130.     return( 1 );
  131. }
  132. pkt_arp_handle = regs2.r_ax;
  133.     }
  134.     /* get ethernet address */
  135.     regs.r_ax = PD_GET_ADDRESS;
  136.     regs.r_bx = pkt_ip_handle;
  137.     regs.r_es = FP_SEG( &eth_addr );
  138.     regs.r_di = FP_OFF( &eth_addr );
  139.     regs.r_cx = sizeof( eth_addr );
  140.     intr( pkt_interrupt, &regs );
  141.     if ( regs.r_flags & CARRY ) {
  142. outs("ERROR # reading ethernet addressnr" );
  143. return( 1 );
  144.     }
  145.     return( 0 );
  146. }
  147. void pkt_release( void )
  148. {
  149.     struct REGPACK regs;
  150. //    int error;
  151.     if ( _pktdevclass != PD_SLIP ) {
  152. regs.r_ax = PD_RELEASE;
  153. regs.r_bx = pkt_arp_handle;
  154. intr( pkt_interrupt, &regs );
  155. if (regs.r_flags & CARRY ) {
  156.     outs("ERROR releasing packet driver for ARPnr");
  157. }
  158.     }
  159.     regs.r_ax = PD_RELEASE;
  160.     regs.r_bx = pkt_ip_handle;
  161.     intr( pkt_interrupt, &regs );
  162.     if (regs.r_flags & CARRY )
  163. outs("ERROR releasing packet driver for IPnr");
  164.     return;
  165. }
  166. int pkt_send( char *buffer, int length )
  167. {
  168.     struct REGPACK regs;
  169.     int retries;
  170.     retries = 5;
  171.     while (retries--) {
  172.         regs.r_ax = PD_SEND;
  173.         regs.r_ds = FP_SEG( buffer );
  174.         regs.r_si = FP_OFF( buffer );
  175.         regs.r_cx = length;
  176.         intr( pkt_interrupt, &regs );
  177.         if ( regs.r_flags & CARRY )
  178.             continue;
  179.         return( 0 );
  180.     }
  181.     return( 1 );
  182. }
  183. /* return a buffer to the pool */
  184. void pkt_buf_wipe( void )
  185. {
  186.     memset( pktbuf, 0, sizeof( byte ) * MAXBUFS * (BUFSIZE+ 2));
  187. }
  188. void pkt_buf_release( char *ptr )
  189. {
  190.     *(ptr - (2 + _pktipofs)) = 0;
  191. }
  192. void * pkt_received( void )
  193. {
  194.     word old;
  195.     int i;
  196.     word oldin, newin; /* ip sequence numbers */
  197.     eth_Header  * temp_e = NULL;
  198.     in_Header   * temp;
  199.     byte        * t_buf;
  200.     extern int active_frags;
  201.     /* check if there are any */
  202.     old = oldin = 0xffff;
  203.     // Do frag timeout bit sad if we got the bit of one we're about to kill
  204. #ifdef FRAGSUPPORT
  205.     if ( active_frags ) timeout_frags();
  206. #endif // FRAGSUPPORT
  207.     for ( i = 0 ; i < MAXBUFS; ++i ) {
  208. if ( *pktbuf[i] != 1 ) continue;
  209.         // check if fragmented - SLIP supported
  210. temp = (in_Header *) &pktbuf[ i ][ 2 ];
  211.         if ( _pktdevclass == PD_ETHER ) {
  212.             temp_e = (eth_Header *) temp;
  213. // fragfix -- next line did pointer arith so incorrectly added
  214. //               ... * sizeof(typeof(*temp)) instead of ... * 1
  215. //            temp += sizeof( eth_Header );
  216.             temp = (in_Header *)((byte*)temp + sizeof(eth_Header));
  217.         }
  218. #ifdef FRAGSUPPORT
  219.         if ((( _pktdevclass == PD_SLIP ) || ( temp_e->type == IP_TYPE ))
  220. // fragfix -- next line, need ~ to clear DF bit, not all others
  221. //              ... check is either MF set or frag offset not 0
  222.                 && ( temp->frags & ~IP_DF )) {
  223. //            && ( temp->frags & IP_DF )) {
  224.             if ( ( t_buf = fragment( temp )) == NULL )
  225.                 // pass pointer to ip section of buffer
  226.                 continue;
  227.             else
  228.                 return( t_buf );
  229.         }
  230. #endif // FRAGSUPPORT
  231.         newin = *(word *)( &pktbuf[i][ _pktipofs + 4 + 2 ]);
  232.         if ( newin <= oldin ) {
  233.             oldin = newin;
  234.             old = i;
  235.         }
  236.     }
  237.     return( (old == 0xffff) ? NULL : &pktbuf[old][2] );
  238. }
  239. eth_address *_pkt_eth_init( void )
  240. {
  241.     if ( pkt_init() ) {
  242.        return NULL; // S. Lawson
  243. // S. Lawson        outs("Program haltedrn");
  244. // S. Lawson exit( 1 );
  245.     }
  246.     return( &eth_addr );
  247. }