home *** CD-ROM | disk | FTP | other *** search
/ Collection of Internet / Collection of Internet.iso / msdos / lynx / source / wattcp / src / pcpkt.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-10-25  |  7.1 KB  |  277 lines

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