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

操作系统开发

开发平台:

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. #ifdef __BORLANDC__
  50. #if __BORLANDC__ < 0x0200
  51. static int fmemcmp( char far *x, char far *y, int len )
  52. {
  53.     while ( len-- > 0 )
  54.         if ( *x++ != *y++ ) return( 1 );
  55.     return( 0 );
  56. }
  57. #endif
  58. #endif
  59. static int pkt_init( void )       /* 94.11.27 -- made static */
  60. {
  61.     struct REGPACK regs, regs2;
  62.     char far *temp;
  63.     int pd_type; /* packet driver type */
  64.     int class;
  65.     _pktasminit( pktbuf, MAXBUFS, BUFSIZE );
  66.     for (pkt_interrupt = INT_FIRST; pkt_interrupt <= INT_LAST; ++pkt_interrupt ) {
  67.         temp = (char far *)getvect( pkt_interrupt );
  68.         if ( ! _fmemcmp( &(temp[3]), pkt_line, strlen( pkt_line )))
  69.             break;
  70.     }
  71.     if ( pkt_interrupt > INT_LAST ) {
  72.         outs("NO PACKET DRIVER FOUNDrn");
  73. return( 1 );
  74.     }
  75.     /* lets find out about the driver */
  76.     regs.r_ax = PD_DRIVER_INFO;
  77.     intr( pkt_interrupt, &regs );
  78.     /* handle old versions, assume a class and just keep trying */
  79.     if (regs.r_flags & CARRY ) {
  80. for ( class = 0; class < 2; ++class ) {
  81.     _pktdevclass = (class) ? PD_SLIP : PD_ETHER;
  82.     for (pd_type = 1; pd_type < 128; ++pd_type ) {
  83. regs.r_ax = PD_ACCESS | _pktdevclass;  /* ETH, SLIP */
  84. regs.r_bx = pd_type; /* type */
  85. regs.r_dx = 0; /* if number */
  86.                 regs.r_cx = (_pktdevclass == PD_SLIP ) ? 0 : sizeof( pkt_ip_type);
  87. regs.r_ds = FP_SEG( &pkt_ip_type );
  88. regs.r_si = FP_OFF( &pkt_ip_type );
  89.                 regs.r_es = FP_SEG( _pktentry);
  90. regs.r_di = FP_OFF( _pktentry);
  91. intr( pkt_interrupt, &regs );
  92. if ( ! (regs.r_flags & CARRY) ) break;
  93.     }
  94.     if (pd_type == 128 ) {
  95. outs("ERROR initializing packet drivernr");
  96. return( 1 );
  97.     }
  98.     /* we have found a working type, so kill it */
  99.     regs.r_bx = regs.r_ax; /* handle */
  100.     regs.r_ax = PD_RELEASE;
  101.     intr( pkt_interrupt, &regs );
  102. }
  103.     } else {
  104. pd_type = regs.r_dx;
  105. switch ( _pktdevclass = (regs.r_cx >> 8)) {
  106.     case PD_ETHER : _pktipofs = 14;
  107.             case PD_SLIP  : break;
  108.             default       : outs("ERROR: only Ethernet or SLIP packet drivers allowednr");
  109.     return( 1 );
  110. }
  111.     }
  112.     regs.r_ax = PD_ACCESS | _pktdevclass;
  113.     regs.r_bx = 0xffff;                 /* any type */
  114.     regs.r_dx = 0; /* if number */
  115.     regs.r_cx = (_pktdevclass == PD_SLIP) ? 0 : sizeof( pkt_ip_type );
  116.     regs.r_ds = FP_SEG( &pkt_ip_type );
  117.     regs.r_si = FP_OFF( &pkt_ip_type );
  118.     regs.r_es = FP_SEG( _pktentry);
  119.     regs.r_di = FP_OFF( _pktentry);
  120.     memcpy( &regs2, &regs, sizeof( regs ));
  121.     regs2.r_si = FP_OFF( &pkt_arp_type );
  122.     regs2.r_ds = FP_SEG( &pkt_arp_type );
  123.     intr( pkt_interrupt, &regs );
  124.     if ( regs.r_flags & CARRY ) {
  125. outs("ERROR # 0x");
  126. outhex( regs.r_dx >> 8 );
  127. outs(" accessing packet drivernr" );
  128. return( 1 );
  129.     }
  130.     pkt_ip_handle = regs.r_ax;
  131.     if (_pktdevclass != PD_SLIP) {
  132. intr( pkt_interrupt, &regs2 );
  133. if ( regs2.r_flags & CARRY ) {
  134.     regs.r_ax = PD_RELEASE;
  135.     regs.r_bx = pkt_ip_handle;
  136.     intr( pkt_interrupt, &regs );
  137.     outs("ERROR # 0x");
  138.     outhex( regs2.r_dx >> 8 );
  139.     outs(" accessing packet drivernr" );
  140.     return( 1 );
  141. }
  142. pkt_arp_handle = regs2.r_ax;
  143.     }
  144.     /* get ethernet address */
  145.     regs.r_ax = PD_GET_ADDRESS;
  146.     regs.r_bx = pkt_ip_handle;
  147.     regs.r_es = FP_SEG( &eth_addr );
  148.     regs.r_di = FP_OFF( &eth_addr );
  149.     regs.r_cx = sizeof( eth_addr );
  150.     intr( pkt_interrupt, &regs );
  151.     if ( regs.r_flags & CARRY ) {
  152. outs("ERROR # reading ethernet addressnr" );
  153. return( 1 );
  154.     }
  155.     return( 0 );
  156. }
  157. void pkt_release( void )
  158. {
  159.     struct REGPACK regs;
  160. //    int error;
  161.     if ( _pktdevclass != PD_SLIP ) {
  162. regs.r_ax = PD_RELEASE;
  163. regs.r_bx = pkt_arp_handle;
  164. intr( pkt_interrupt, &regs );
  165. if (regs.r_flags & CARRY ) {
  166.     outs("ERROR releasing packet driver for ARPnr");
  167. }
  168.     }
  169.     regs.r_ax = PD_RELEASE;
  170.     regs.r_bx = pkt_ip_handle;
  171.     intr( pkt_interrupt, &regs );
  172.     if (regs.r_flags & CARRY )
  173. outs("ERROR releasing packet driver for IPnr");
  174.     return;
  175. }
  176. int pkt_send( char *buffer, int length )
  177. {
  178.     struct REGPACK regs;
  179.     int retries;
  180.     retries = 5;
  181.     while (retries--) {
  182.         regs.r_ax = PD_SEND;
  183.         regs.r_ds = FP_SEG( buffer );
  184.         regs.r_si = FP_OFF( buffer );
  185.         regs.r_cx = length;
  186.         intr( pkt_interrupt, &regs );
  187.         if ( regs.r_flags & CARRY )
  188.             continue;
  189.         return( 0 );
  190.     }
  191.     return( 1 );
  192. }
  193. /* return a buffer to the pool */
  194. void pkt_buf_wipe( void )
  195. {
  196.     memset( pktbuf, 0, sizeof( byte ) * MAXBUFS * (BUFSIZE+ 2));
  197. }
  198. void pkt_buf_release( char *ptr )
  199. {
  200.     *(ptr - (2 + _pktipofs)) = 0;
  201. }
  202. void * pkt_received( void )
  203. {
  204.     word old;
  205.     int i;
  206.     word oldin, newin; /* ip sequence numbers */
  207.     eth_Header  * temp_e = NULL;
  208.     in_Header   * temp;
  209.     byte        * t_buf;
  210.     extern int active_frags;
  211.     /* check if there are any */
  212.     old = oldin = 0xffff;
  213.     // Do frag timeout bit sad if we got the bit of one we're about to kill
  214. #ifdef FRAGSUPPORT
  215.     if ( active_frags ) timeout_frags();
  216. #endif // FRAGSUPPORT
  217.     for ( i = 0 ; i < MAXBUFS; ++i ) {
  218. if ( *pktbuf[i] != 1 ) continue;
  219.         // check if fragmented - SLIP supported
  220. temp = (in_Header *) &pktbuf[ i ][ 2 ];
  221.         if ( _pktdevclass == PD_ETHER ) {
  222.             temp_e = (eth_Header *) temp;
  223. // fragfix -- next line did pointer arith so incorrectly added
  224. //               ... * sizeof(typeof(*temp)) instead of ... * 1
  225. //            temp += sizeof( eth_Header );
  226.             temp = (in_Header *)((byte*)temp + sizeof(eth_Header));
  227.         }
  228. #ifdef FRAGSUPPORT
  229.         if ((( _pktdevclass == PD_SLIP ) || ( temp_e->type == IP_TYPE ))
  230. // fragfix -- next line, need ~ to clear DF bit, not all others
  231. //              ... check is either MF set or frag offset not 0
  232.                 && ( temp->frags & ~IP_DF )) {
  233. //            && ( temp->frags & IP_DF )) {
  234.             if ( ( t_buf = fragment( temp )) == NULL )
  235.                 // pass pointer to ip section of buffer
  236.                 continue;
  237.             else
  238.                 return( t_buf );
  239.         }
  240. #endif // FRAGSUPPORT
  241.         newin = *(word *)( &pktbuf[i][ _pktipofs + 4 + 2 ]);
  242.         if ( newin <= oldin ) {
  243.             oldin = newin;
  244.             old = i;
  245.         }
  246.     }
  247.     return( (old == 0xffff) ? NULL : &pktbuf[old][2] );
  248. }
  249. eth_address *_pkt_eth_init( void )
  250. {
  251.     if ( pkt_init() ) {
  252.        return NULL; // S. Lawson
  253. // S. Lawson        outs("Program haltedrn");
  254. // S. Lawson exit( 1 );
  255.     }
  256.     return( &eth_addr );
  257. }