PCPKT.C
资源名称:wattcp.rar [点击查看]
上传用户:better800
上传日期:2022-06-13
资源大小:1853k
文件大小:8k
源码类别:
TCP/IP协议栈
开发平台:
DOS
- // FRAGSUPPORT enables support for packet reassembly of fragmented packets
- #define FRAGSUPPORT
- #include <copyright.h>
- #include <wattcp.h>
- #include <elib.h>
- #include <dos.h>
- #ifdef __BORLANDC__
- #include <mem.h>
- #endif
- #include <string.h>
- #include <stdlib.h>
- #ifdef LARGE
- #define MAXBUFS 25 /* maximum number of Ethernet buffers */
- #else
- #define MAXBUFS 10
- #endif
- #define BUFSIZE 1600
- #define DOS 0x21
- #define GETVECT 0x35
- #define INT_FIRST 0x60
- #define INT_LAST 0x80
- #define PD_DRIVER_INFO 0x1ff
- #define PD_ACCESS 0x200
- #define PD_RELEASE 0x300
- #define PD_SEND 0x400
- #define PD_GET_ADDRESS 0x600
- #define CARRY 1 /* carry bit in flags register */
- word _pktipofs = 0; /* offset from header to start of pkt */
- word pkt_interrupt;
- word pkt_ip_type = 0x0008; /* these are intelled values */
- word pkt_arp_type = 0x608;
- #ifdef LARGE
- byte far pktbuf[MAXBUFS][ BUFSIZE + 2 ]; /* first byte is busy flag, 2nd spare */
- #else
- byte pktbuf[ MAXBUFS][ BUFSIZE + 2];
- #endif
- word pkt_ip_handle;
- word pkt_arp_handle;
- //byte eth_addr[ 6 ] ; // 94.11.19
- eth_address eth_addr;
- longword far *interrupts = 0L;
- char *pkt_line = "PKT DRVR";
- // fragfix -- just a note this is intel
- #define IP_DF 0x0040 // Don't fragment bit set for FRAG Flags
- // forwards and externs
- int pkt_init( void );
- extern void _pktentry(); /* see asmpkt.asm */
- extern void _pktasminit( void far *, int, int ); /* see asmpkt.asm */
- static int pkt_init( void ) /* 94.11.27 -- made static */
- {
- struct REGPACK regs, regs2;
- char far *temp;
- int pd_type; /* packet driver type */
- int class;
- _pktasminit( pktbuf, MAXBUFS, BUFSIZE );
- for (pkt_interrupt = INT_FIRST; pkt_interrupt <= INT_LAST; ++pkt_interrupt ) {
- temp = (char far *)getvect( pkt_interrupt );
- if ( ! _fmemcmp( &(temp[3]), pkt_line, strlen( pkt_line )))
- break;
- }
- if ( pkt_interrupt > INT_LAST ) {
- outs("NO PACKET DRIVER FOUNDrn");
- return( 1 );
- }
- /* lets find out about the driver */
- regs.r_ax = PD_DRIVER_INFO;
- intr( pkt_interrupt, ®s );
- /* handle old versions, assume a class and just keep trying */
- if (regs.r_flags & CARRY ) {
- for ( class = 0; class < 2; ++class ) {
- _pktdevclass = (class) ? PD_SLIP : PD_ETHER;
- for (pd_type = 1; pd_type < 128; ++pd_type ) {
- regs.r_ax = PD_ACCESS | _pktdevclass; /* ETH, SLIP */
- regs.r_bx = pd_type; /* type */
- regs.r_dx = 0; /* if number */
- regs.r_cx = (_pktdevclass == PD_SLIP ) ? 0 : sizeof( pkt_ip_type);
- regs.r_ds = FP_SEG( &pkt_ip_type );
- regs.r_si = FP_OFF( &pkt_ip_type );
- regs.r_es = FP_SEG( _pktentry);
- regs.r_di = FP_OFF( _pktentry);
- intr( pkt_interrupt, ®s );
- if ( ! (regs.r_flags & CARRY) ) break;
- }
- if (pd_type == 128 ) {
- outs("ERROR initializing packet drivernr");
- return( 1 );
- }
- /* we have found a working type, so kill it */
- regs.r_bx = regs.r_ax; /* handle */
- regs.r_ax = PD_RELEASE;
- intr( pkt_interrupt, ®s );
- }
- } else {
- pd_type = regs.r_dx;
- switch ( _pktdevclass = (regs.r_cx >> 8)) {
- case PD_ETHER : _pktipofs = 14;
- case PD_SLIP : break;
- default : outs("ERROR: only Ethernet or SLIP packet drivers allowednr");
- return( 1 );
- }
- }
- regs.r_ax = PD_ACCESS | _pktdevclass;
- regs.r_bx = 0xffff; /* any type */
- regs.r_dx = 0; /* if number */
- regs.r_cx = (_pktdevclass == PD_SLIP) ? 0 : sizeof( pkt_ip_type );
- regs.r_ds = FP_SEG( &pkt_ip_type );
- regs.r_si = FP_OFF( &pkt_ip_type );
- regs.r_es = FP_SEG( _pktentry);
- regs.r_di = FP_OFF( _pktentry);
- memcpy( ®s2, ®s, sizeof( regs ));
- regs2.r_si = FP_OFF( &pkt_arp_type );
- regs2.r_ds = FP_SEG( &pkt_arp_type );
- intr( pkt_interrupt, ®s );
- if ( regs.r_flags & CARRY ) {
- outs("ERROR # 0x");
- outhex( regs.r_dx >> 8 );
- outs(" accessing packet drivernr" );
- return( 1 );
- }
- pkt_ip_handle = regs.r_ax;
- if (_pktdevclass != PD_SLIP) {
- intr( pkt_interrupt, ®s2 );
- if ( regs2.r_flags & CARRY ) {
- regs.r_ax = PD_RELEASE;
- regs.r_bx = pkt_ip_handle;
- intr( pkt_interrupt, ®s );
- outs("ERROR # 0x");
- outhex( regs2.r_dx >> 8 );
- outs(" accessing packet drivernr" );
- return( 1 );
- }
- pkt_arp_handle = regs2.r_ax;
- }
- /* get ethernet address */
- regs.r_ax = PD_GET_ADDRESS;
- regs.r_bx = pkt_ip_handle;
- regs.r_es = FP_SEG( ð_addr );
- regs.r_di = FP_OFF( ð_addr );
- regs.r_cx = sizeof( eth_addr );
- intr( pkt_interrupt, ®s );
- if ( regs.r_flags & CARRY ) {
- outs("ERROR # reading ethernet addressnr" );
- return( 1 );
- }
- return( 0 );
- }
- void pkt_release( void )
- {
- struct REGPACK regs;
- // int error;
- if ( _pktdevclass != PD_SLIP ) {
- regs.r_ax = PD_RELEASE;
- regs.r_bx = pkt_arp_handle;
- intr( pkt_interrupt, ®s );
- if (regs.r_flags & CARRY ) {
- outs("ERROR releasing packet driver for ARPnr");
- }
- }
- regs.r_ax = PD_RELEASE;
- regs.r_bx = pkt_ip_handle;
- intr( pkt_interrupt, ®s );
- if (regs.r_flags & CARRY )
- outs("ERROR releasing packet driver for IPnr");
- return;
- }
- int pkt_send( char *buffer, int length )
- {
- struct REGPACK regs;
- int retries;
- retries = 5;
- while (retries--) {
- regs.r_ax = PD_SEND;
- regs.r_ds = FP_SEG( buffer );
- regs.r_si = FP_OFF( buffer );
- regs.r_cx = length;
- intr( pkt_interrupt, ®s );
- if ( regs.r_flags & CARRY )
- continue;
- return( 0 );
- }
- return( 1 );
- }
- /* return a buffer to the pool */
- void pkt_buf_wipe( void )
- {
- memset( pktbuf, 0, sizeof( byte ) * MAXBUFS * (BUFSIZE+ 2));
- }
- void pkt_buf_release( char *ptr )
- {
- *(ptr - (2 + _pktipofs)) = 0;
- }
- void * pkt_received( void )
- {
- word old;
- int i;
- word oldin, newin; /* ip sequence numbers */
- eth_Header * temp_e = NULL;
- in_Header * temp;
- byte * t_buf;
- extern int active_frags;
- /* check if there are any */
- old = oldin = 0xffff;
- // Do frag timeout bit sad if we got the bit of one we're about to kill
- #ifdef FRAGSUPPORT
- if ( active_frags ) timeout_frags();
- #endif // FRAGSUPPORT
- for ( i = 0 ; i < MAXBUFS; ++i ) {
- if ( *pktbuf[i] != 1 ) continue;
- // check if fragmented - SLIP supported
- temp = (in_Header *) &pktbuf[ i ][ 2 ];
- if ( _pktdevclass == PD_ETHER ) {
- temp_e = (eth_Header *) temp;
- // fragfix -- next line did pointer arith so incorrectly added
- // ... * sizeof(typeof(*temp)) instead of ... * 1
- // temp += sizeof( eth_Header );
- temp = (in_Header *)((byte*)temp + sizeof(eth_Header));
- }
- #ifdef FRAGSUPPORT
- if ((( _pktdevclass == PD_SLIP ) || ( temp_e->type == IP_TYPE ))
- // fragfix -- next line, need ~ to clear DF bit, not all others
- // ... check is either MF set or frag offset not 0
- && ( temp->frags & ~IP_DF )) {
- // && ( temp->frags & IP_DF )) {
- if ( ( t_buf = fragment( temp )) == NULL )
- // pass pointer to ip section of buffer
- continue;
- else
- return( t_buf );
- }
- #endif // FRAGSUPPORT
- newin = *(word *)( &pktbuf[i][ _pktipofs + 4 + 2 ]);
- if ( newin <= oldin ) {
- oldin = newin;
- old = i;
- }
- }
- return( (old == 0xffff) ? NULL : &pktbuf[old][2] );
- }
- eth_address *_pkt_eth_init( void )
- {
- if ( pkt_init() ) {
- return NULL; // S. Lawson
- // S. Lawson outs("Program haltedrn");
- // S. Lawson exit( 1 );
- }
- return( ð_addr );
- }