home *** CD-ROM | disk | FTP | other *** search
/ Super Net 1 / SUPERNET_1.iso / PC / OTROS / MSDOS / WATTCP / MSWATTCP.ZIP / SRC / PCPKT.C < prev    next >
Encoding:
C/C++ Source or Header  |  1993-09-06  |  9.9 KB  |  388 lines

  1. /***
  2.  *
  3.  * File: pcpkt.c - packet driver interface for wattcp
  4.  *
  5.  * 27-Aug-93 fr    final cleanup
  6.  * 21-Sep-92 lr    cleanup
  7.  * 18-Jun-92 lr
  8.  *
  9.  * modified by Luigi Rizzo for use with Microsoft C 6.0
  10.  * Dec. 1991
  11.  *
  12.  * The packet driver invokes a routine in asmpkt.asm to load
  13.  * new packet into a circular buffer. pkt_received() returns
  14.  * a non-null pointer if a new packet is arrived.
  15.  *
  16.  */
  17.  
  18. #define WATTCP_KERNEL
  19. #define PCPKT
  20. #include <tcp.h>
  21.  
  22. #ifdef debug
  23.     void stampa_regs(char *s,struct REGPACK *r);
  24.     void print_pkt(byte *p);
  25. #else /* !debug */
  26. #define stampa_regs(x,y)
  27. #endif /* !debug */
  28.  
  29.  
  30. #define INT_FIRST    0x60
  31. #define INT_LAST    0x80
  32. #define PKT_LINE    "PKT DRVR"
  33. #define PD_DRIVER_INFO    0x1ff
  34. #define PD_ACCESS     0x200
  35. #define PD_RELEASE    0x300
  36. #define PD_SEND        0x400
  37. #define PD_GET_ADDRESS    0x600
  38. #define CARRY         1         /* carry bit in flags register */
  39.  
  40. #ifdef COMMENT
  41.  
  42. The structure of a buffer is as follows:
  43.  
  44. struct _pktbuf {
  45.     short busy;    /* 1 if busy, 0 if free */
  46.     char et_header[14];
  47.     char data[...];
  48. } _pktbuf[MAXBUFS];
  49.  
  50. #endif /* COMMENT */
  51.  
  52. int
  53. farcmp(char far *f, char *d, int len)
  54. {
  55.     while (len--)
  56.         if (*f++ != *d++) {
  57.             return(1);
  58.         }
  59.     return(0);
  60. }
  61.  
  62. int
  63. pkt_init(void)
  64. {
  65.     struct REGPACK regs, regs2;
  66.     char far *temp;
  67.     int pd_type;    /* packet driver type */
  68.     int class;
  69.  
  70.     _pktasminit( (char far *)pktbuf, MAXBUFS, BUFSIZE, &lost_packets);
  71.     for (pkt_interrupt=INT_FIRST;pkt_interrupt<=INT_LAST;++pkt_interrupt ) {
  72.     getvect( pkt_interrupt );
  73.     temp = (char far *)(interrupts[ pkt_interrupt ] +3);
  74.     
  75.     if ( !farcmp( temp, PKT_LINE, strlen( PKT_LINE ))) {
  76.         break; /* found */
  77.     }
  78.     }
  79.     if ( pkt_interrupt > INT_LAST ) {
  80.     outs("NO PACKET DRIVER FOUND");
  81.     return( 1 );
  82.     }
  83.     DB3((stderr,"packet driver found at interrupt 0x%2x\n",pkt_interrupt));
  84.     /* lets find out about the driver */
  85.     segread(&(regs.s));
  86.     regs.r_ax = PD_DRIVER_INFO;
  87.     stampa_regs("before driver_info",®s); 
  88.     intr( pkt_interrupt, ®s );
  89.     stampa_regs("after driver_info",®s); 
  90.  
  91.     /* handle old versions, assume a class and just keep trying */
  92.     if (regs.r_flags & CARRY ) { /* old version */
  93.     for ( class = 0; class < 2; ++class ) {
  94.         _pktdevclass = (class) ? PD_SLIP : PD_ETHER;
  95.  
  96.         for (pd_type = 1; pd_type < 128; ++pd_type ) {
  97.         regs.r_ax = PD_ACCESS | _pktdevclass;  /* ETH, SLIP */
  98.         regs.r_bx = pd_type;        /* type */
  99.         regs.r_dx = 0;            /* if number */
  100.         regs.r_cx = sizeof( pkt_ip_type );
  101.         {  word far *fp= &pkt_ip_type;
  102.            regs.r_ds = FP_SEG( fp );
  103.            regs.r_si = FP_OFF( fp );
  104.         }
  105.         {
  106.            void far *s= (char far *)_pktentry;
  107.                regs.r_es = FP_SEG( s );
  108.            regs.r_di = FP_OFF( s );
  109.         }
  110.         stampa_regs("before access (old) type",®s); 
  111.         intr( pkt_interrupt, ®s );
  112.         stampa_regs("after access (old) type",®s); 
  113.         if ( ! (regs.r_flags & CARRY) ) break;
  114.         }
  115.  
  116.         if (pd_type == 128 ) {
  117.         outs("ERROR initializing packet driver\n\r");
  118.         return( 1 );
  119.         }
  120.         /* we have found a working type, so kill it */
  121.         regs.r_bx = regs.r_ax;    /* handle */
  122.         regs.r_ax = PD_RELEASE;
  123.         stampa_regs("before release",®s); 
  124.         intr( pkt_interrupt, ®s );
  125.         stampa_regs("after release",®s); 
  126.     }
  127.     } else {
  128.     pd_type = regs.r_dx;
  129.     switch ( _pktdevclass = (regs.r_cx >> 8)) {
  130.         case PD_ETHER : _pktipofs = 14;
  131.  
  132.         case PD_SLIP  : break;
  133.         default       : outs("ERROR: only ethernet packet drivers allowed\n\r");
  134.                 return( 1 );
  135.     }
  136.     }
  137.     regs.r_ax = PD_ACCESS | _pktdevclass;
  138.     regs.r_bx = 0xffff;  /* any type - was pd_type  type */
  139.     regs.r_dx = 0;            /* if number */
  140.     regs.r_cx = sizeof( pkt_ip_type );
  141.     {    word far *fp= &pkt_ip_type;
  142.     regs.r_ds = FP_SEG( fp );
  143.     regs.r_si = FP_OFF( fp );
  144.     }
  145.     {
  146.     void far *s= (char far *)_pktentry;
  147.     regs.r_es = FP_SEG( s );
  148.     regs.r_di = FP_OFF( s );
  149.     }
  150.     memcpy( ®s2, ®s, sizeof( regs ));
  151.     {    word far *fp= &pkt_arp_type;
  152.     regs2.r_si = FP_OFF( fp );
  153.     regs2.r_ds = FP_SEG( fp );
  154.     }
  155.     stampa_regs("before access IP type",®s); 
  156.     intr( pkt_interrupt, ®s );
  157.     stampa_regs("after access IP type",®s); 
  158.     if ( regs.r_flags & CARRY ) {
  159.     outs("ERROR # 0x");
  160.     outhex( (unsigned char)(regs.r_dx >> 8) );
  161.     outs(" accessing IP type on packet driver\n\r" );
  162.     return( 1 );
  163.     }
  164.     pkt_ip_handle = regs.r_ax;
  165.  
  166.     if (_pktdevclass != PD_SLIP) {
  167.     stampa_regs("before access ARP type on regs2",®s2); 
  168.     intr( pkt_interrupt, ®s2 );
  169.     stampa_regs("after access ARP type on regs2",®s2); 
  170.     if ( regs2.r_flags & CARRY ) {
  171.         regs.r_ax = PD_RELEASE;
  172.         regs.r_bx = pkt_ip_handle;
  173.         stampa_regs("failed ARP - before release IP type",®s); 
  174.         intr( pkt_interrupt, ®s );
  175.         stampa_regs("failed ARP - after release IP type",®s); 
  176.  
  177.         outs("ERROR # 0x");
  178.         outhex( (unsigned char)(regs2.r_dx >> 8) );
  179.         outs(" accessing ARP type on packet driver\n\r" );
  180.         return( 1 );
  181.     }
  182.     pkt_arp_handle = regs2.r_ax;
  183.     }
  184.  
  185.     /* get ethernet address */
  186.     regs.r_ax = PD_GET_ADDRESS;
  187.     regs.r_bx = pkt_ip_handle;
  188.     {    char far *fp= eth_addr;
  189.     regs.r_es = FP_SEG( fp );
  190.     regs.r_di = FP_OFF( fp );
  191.     }
  192.     regs.r_cx = sizeof( eth_addr );
  193.     stampa_regs("before get_addr",®s); 
  194.     intr( pkt_interrupt, ®s );
  195.     stampa_regs("after get_addr",®s); 
  196.     if ( regs.r_flags & CARRY ) {
  197.     outs("ERROR # reading ethernet address\n\r" );
  198.     return( 1 );
  199.     }
  200.  
  201.     return( 0 );
  202. }
  203.  
  204. int
  205. pkt_release(void)
  206. {
  207.     struct REGPACK regs;
  208.     int error;
  209.  
  210.     error = 0;
  211.  
  212.     segread(&(regs.s));
  213.     if ( _pktdevclass != PD_SLIP ) {
  214.     regs.r_ax = PD_RELEASE;
  215.     regs.r_bx = pkt_arp_handle;
  216.     stampa_regs("before release ARP in pkt_release",®s); 
  217.     intr( pkt_interrupt, ®s );
  218.     stampa_regs("after release ARP in pkt_release",®s); 
  219.     if (regs.r_flags & CARRY ) {
  220.         outs("ERROR releasing packet driver for ARP\n\r");
  221.         error = 1;
  222.     }
  223.     }
  224.  
  225.     regs.r_ax = PD_RELEASE;
  226.     regs.r_bx = pkt_ip_handle;
  227.     stampa_regs("before release IP in pkt_release",®s); 
  228.     intr( pkt_interrupt, ®s );
  229.     stampa_regs("after release IP in pkt_release",®s); 
  230.     if (regs.r_flags & CARRY ) {
  231.     outs("ERROR releasing packet driver for IP\n\r");
  232.     error = 1;
  233.     }
  234.  
  235.     return( error );
  236. }
  237.  
  238. int
  239. pkt_send( char *buffer, int length )
  240. {
  241.     struct REGPACK regs;
  242.     int retries;
  243.  
  244.     segread(&(regs.s));
  245.     retries = 5;
  246.     while (retries--) {
  247.         regs.r_ax = PD_SEND;
  248.     {    char far *fp= buffer;
  249.             regs.r_ds = FP_SEG( fp );
  250.             regs.r_si = FP_OFF( fp );
  251.     }
  252.         regs.r_cx = length;
  253.     stampa_regs("before send in pkt_send",®s); 
  254.     DB2((stderr, "Sending PKT:\n"));
  255. #ifdef debug
  256.     print_pkt(buffer);
  257. #endif /* debug */
  258.         intr( pkt_interrupt, ®s );
  259.     stampa_regs("after send in pkt_send",®s); 
  260.         if ( regs.r_flags & CARRY )
  261.             continue;
  262.         return( 0 );
  263.     }
  264.     return( 1 );
  265. }
  266.  
  267. void
  268. pkt_buf_wipe(void )
  269. {
  270.     memset( pktbuf, 0, sizeof( pktbuf ));
  271. }
  272.  
  273. /* return a buffer to the pool */
  274. void
  275. pkt_buf_release( char *ptr )
  276. {
  277.     DB2((stderr,"called pkt_buf_release()\r\n"));
  278.     *(ptr - (2 + 14)) = 0; /* 14 is ip offset, 2 is busy word */
  279. }
  280.  
  281. void *
  282. pkt_received(void)
  283. {
  284.     static word i=0; /* index of the current free buffer */
  285.     word j;
  286.     if (pktbuf[i][0] != 1) return NULL; /* not found */
  287.         if (debug_on) {
  288.         DB2((stderr, "Received PKT:\n"));
  289.     #ifdef debug
  290.         print_pkt(pktbuf[i]+2);
  291.     #endif
  292.     }
  293.     j=i;    /* temporary */
  294.         if (++i == MAXBUFS ) i=0; /* update pointer */
  295.     return( &pktbuf[j][2] );
  296. }
  297.  
  298. void *
  299. _pkt_eth_init(void)
  300. {
  301.     if ( pkt_init() ) {
  302.     outs("Program halted");
  303.     exit( 1 );
  304.     }
  305.     return( eth_addr );
  306. }
  307. #ifdef debug
  308. void
  309. stampa_regs(char *s,struct REGPACK *r)
  310. {
  311.     DB2((stderr,"%s\n",s));
  312.     DB2((stderr,"AX: %4x, BX: %4x, CX: %4x, DX: %4x, SI: %4x, DI: %4x\n",
  313.     (*r).x.ax, (*r).x.bx, (*r).x.cx, (*r).x.dx, (*r).x.si, (*r).x.di));
  314.     DB2((stderr,"CS: %4x, SS: %4x, DS: %4x, ES: %4x, FLAGS: %4x\n",
  315.     (*r).s.cs, (*r).s.ss, (*r).s.ds, (*r).s.es, (*r).r_flags));
  316.     getch();
  317. }
  318.  
  319.  
  320. void
  321. print_ip(byte *p)
  322. {
  323.     in_Header *in= (in_Header *)p;
  324.     byte *s;
  325.     DB2((stderr,"Hdrlen: %2d  ver: %2d  tos: %3d len: %5d\n",
  326.         in->hdrlen, in->ver, in->tos, intel16(in->length)));
  327.     switch (in->proto) {
  328.     case 0x11:s="UDP"; break;
  329.     case 0x06:s="TCP"; break;
  330.     case 0x01:s="ICMP"; break;
  331.     default: s="unknown";
  332.     }
  333.     DB2((stderr,"id: %5d  frag: %5d  ttl: %3d  proto: %d (%s)\n",
  334.         intel16(in->identification), intel16(in->frag), in->ttl, in->proto,s));
  335.     s= (char *)(&in->source);
  336.     DB2((stderr,"chk: %4x, src: %d.%d.%d.%d",
  337.         intel16(in->checksum), s[0],s[1],s[2],s[3]));
  338.     s= (char *)(&in->destination);
  339.     DB2((stderr," dst: %d.%d.%d.%d\n", s[0],s[1],s[2],s[3]));
  340. }
  341.  
  342. void
  343. print_arp(byte *p)
  344. {
  345.     arp_Header *a= (arp_Header *)p;
  346.     byte *s;
  347.     DB2((stderr,"hwtype: %4x  protType: %4x hwProtAddrLen: %4x opcode: %4x\n",
  348.         intel16(a->hwType),intel16(a->protType),
  349.         intel16(a->hwProtAddrLen), intel16(a->opcode) ));
  350.     s= (byte *)(&a->srcEthAddr);
  351.     DB2((stderr,"src_eth: %2x %2x %2x %2x %2x %2x",
  352.         s[0],s[1],s[2],s[3],s[4],s[5]));
  353.     s= (byte *)(&a->srcIPAddr);
  354.     DB2((stderr," src_ip: %d.%d.%d.%d\n", s[0],s[1],s[2],s[3]));
  355.     s= (byte *)(&a->dstEthAddr);
  356.     DB2((stderr,"dst_eth: %2x %2x %2x %2x %2x %2x",
  357.         s[0],s[1],s[2],s[3],s[4],s[5]));
  358.     s= (byte *)(&a->dstIPAddr);
  359.     DB2((stderr," dst_ip: %d.%d.%d.%d\n", s[0],s[1],s[2],s[3]));
  360. }
  361.  
  362. void
  363. print_pkt(byte *p)
  364. {
  365.     DB2((stderr,"eth_dest: %2x %2x %2x %2x %2x %2x ",
  366.         p[0],p[1],p[2],p[3],p[4],p[5]));
  367.     p +=6;
  368.     DB2((stderr,"eth_src: %2x %2x %2x %2x %2x %2x ",
  369.         p[0],p[1],p[2],p[3],p[4],p[5]));
  370.     p +=6;
  371.     DB2((stderr,"mac_type: %2x %2x", p[0],p[1]));
  372.     switch ( *( (word *)p) ) { /* use intelled values */
  373.     case 0x08: /* IP */
  374.         DB2((stderr," IP\n"));
  375.         print_ip(p+2);
  376.         break;
  377.     case 0x608: /* ARP */
  378.         DB2((stderr," ARP\n"));
  379.         print_arp(p+2);
  380.         break;
  381.     default: /* unknown */
  382.         DB2((stderr," unknown\n"));
  383.         break;
  384.     }
  385.     getch();
  386. }
  387. #endif
  388.