#ifndef _wattcp_wattcp_h #define _wattcp_wattcp_h /* * Are we compiling the kernel? * or an application using the kernel? */ #if !defined(__WATTCP_USER__) #define __WATTCP_KERNEL__ #endif /* * Note that some stuff is not available to user applications. * This is generally detail you shouldn't need to worry about, * and best stay away from to preserve the kernel integrity. * Note also that there is a lot of other stuff that should probably * be protected but isn't. */ #define WATTCPH /* these are visible for select.c routine return values */ #define SOCKESTABLISHED 1 #define SOCKDATAREADY 2 #define SOCKCLOSED 4 #if defined(__WATTCP_KERNEL__) #define IP_TYPE 0x0008 /* #define DEBUG */ #include #include #define MAX_GATE_DATA 12 #define MAX_STRING 50 /* most strings are limited */ #endif /* defined(__WATTCP_KERNEL__) */ #define MAX_NAMESERVERS 10 #define MAX_COOKIES 10 #if defined(__WATTCP_KERNEL__) #define MAXVJSA 1440 /* 10 s */ #define MAXVJSD 360 /* 10 s */ #define SAFETYTCP 0x538f25a3L #define SAFETYUDP 0x3e45e154L #define TRUE 1 #define true TRUE #define FALSE 0 #define false FALSE #define EL_INUSE 0x0001 #define EL_DELAY 0x0002 #define EL_TCP 0x0004 #define EL_SERVER 0x0008 #define EL_ASCII 0x0010 #define EL_NEVER 0x0020 /* These are Ethernet protocol numbers but I use them for other things too */ #define UDP_PROTO 0x11 #define TCP_PROTO 0x06 #define ICMP_PROTO 0x01 #endif /* defined(__WATTCP_KERNEL__) */ #define TCP_MODE_BINARY 0 /* default mode */ #define TCP_MODE_ASCII 1 #define UDP_MODE_CHK 0 /* default to having checksums */ #define UDP_MODE_NOCHK 2 /* turn off checksums */ #define TCP_MODE_NAGLE 0 /* Nagle algorithm */ #define TCP_MODE_NONAGLE 4 typedef unsigned long longword; /* 32 bits */ typedef unsigned short word; /* 16 bits */ typedef unsigned char byte; /* 8 bits */ typedef struct { byte eaddr[6]; } eth_address; // 94.11.19 -- made an array #if defined(__WATTCP_KERNEL__) /* undesirable */ extern longword MsecClock(); #define clock_ValueRough() MsecClock() #define TICKS_SEC 18 #define checksum( p, len) inchksum( p, len ) #define PD_ETHER 1 #define PD_SLIP 6 extern word sock_inactive; /* in pcbootp.c */ extern word _pktdevclass; extern word _mss; extern word _bootptimeout; /* in pcbootp.c */ extern longword _bootphost; /* in pcbootp.c */ extern word _bootpon; /* The Ethernet header */ typedef struct { eth_address destination; eth_address source; word type; } eth_Header; /* The Internet Header: */ typedef struct { unsigned hdrlen : 4; unsigned ver : 4; byte tos; word length; word identification; word frags; byte ttl; byte proto; word checksum; longword source; longword destination; } in_Header; #define in_GetVersion(ip) ( (ip)->ver ) #define in_GetHdrlen(ip) ( (ip)->hdrlen ) /* 32 bit word size */ #define in_GetHdrlenBytes(ip) ( in_GetHdrlen(ip) << 2 ) /* 8 bit byte size */ #define in_GetTos(ip) ( (ip)->tos) #define in_GetTTL(ip) ((ip)->ttl) #define in_GetProtocol(ip) ((ip)->proto ) typedef struct { word srcPort; word dstPort; word length; word checksum; } udp_Header; #define UDP_LENGTH ( sizeof( udp_Header )) typedef struct { word srcPort; word dstPort; longword seqnum; longword acknum; word flags; word window; word checksum; word urgentPointer; } tcp_Header; #define tcp_FlagFIN 0x0001 #define tcp_FlagSYN 0x0002 #define tcp_FlagRST 0x0004 #define tcp_FlagPUSH 0x0008 #define tcp_FlagACK 0x0010 #define tcp_FlagURG 0x0020 #define tcp_FlagDO 0xF000 #define tcp_GetDataOffset(tp) (intel16((tp)->flags) >> 12) #endif /* defined(__WATTCP_KERNEL__) /* The TCP/UDP Pseudo Header */ typedef struct { longword src; longword dst; byte mbz; byte protocol; word length; word checksum; } tcp_PseudoHeader; /* A datahandler for tcp or udp sockets */ typedef int (*dataHandler_t)( void *s, byte *data, int len, tcp_PseudoHeader *pseudohdr, void *protohdr ); /* A socket function for delay routines */ typedef int (*sockfunct_t)( void *s ); #if defined(__WATTCP_KERNEL__) /* * TCP states, from tcp manual. * Note: close-wait state is bypassed by automatically closing a connection * when a FIN is received. This is easy to undo. */ #define tcp_StateLISTEN 0 /* listening for connection */ #define tcp_StateSYNSENT 1 /* syn sent, active open */ #define tcp_StateSYNREC 2 /* syn received, synack+syn sent. */ #define tcp_StateESTAB 3 /* established */ #define tcp_StateESTCL 4 /* established, but will FIN */ #define tcp_StateFINWT1 5 /* sent FIN */ #define tcp_StateFINWT2 6 /* sent FIN, received FINACK */ #define tcp_StateCLOSWT 7 /* received FIN waiting for close */ #define tcp_StateCLOSING 8 /* sent FIN, received FIN (waiting for FINACK) */ #define tcp_StateLASTACK 9 /* fin received, finack+fin sent */ #define tcp_StateTIMEWT 10 /* dally after sending final FINACK */ #define tcp_StateCLOSEMSL 11 #define tcp_StateCLOSED 12 /* finack received */ #endif #define tcp_MaxBufSize 4096 // was 2048 and inside the __WATTCP_KERNEL__ ifdef /* maximum bytes to buffer on input */ #if defined(__WATTCP_KERNEL__) /* * UDP socket definition */ typedef struct _udp_socket { struct _udp_socket *next; word ip_type; /* always set to UDP_PROTO */ char *err_msg; /* null when all is ok */ char *usr_name; void (*usr_yield)( void ); byte rigid; byte stress; word sock_mode; /* a logical OR of bits */ longword usertimer; /* ip_timer_set, ip_timer_timeout */ dataHandler_t dataHandler; eth_address hisethaddr; /* peer's ethernet address */ longword hisaddr; /* peer's internet address */ word hisport; /* peer's UDP port */ longword myaddr; word myport; word locflags; int queuelen; byte *queue; int rdatalen; /* must be signed */ word maxrdatalen; byte *rdata; byte rddata[ tcp_MaxBufSize + 1]; /* if dataHandler = 0, len == 512 */ longword safetysig; } udp_Socket; #else /* __WATTCP_USER */ /* * Don't give users access to the fields. */ typedef struct { byte undoc[ tcp_MaxBufSize + 152]; // was [2200]; } udp_Socket; #endif /* __WATTCP_USER__ */ #if defined(__WATTCP_KERNEL__) /* * TCP Socket definition */ typedef struct _tcp_socket { struct _tcp_socket *next; word ip_type; /* always set to TCP_PROTO */ char *err_msg; char *usr_name; void (*usr_yield)(void); byte rigid; byte stress; word sock_mode; /* a logical OR of bits */ longword usertimer; /* ip_timer_set, ip_timer_timeout */ dataHandler_t dataHandler; /* called with incoming data */ eth_address hisethaddr; /* ethernet address of peer */ longword hisaddr; /* internet address of peer */ word hisport; /* tcp ports for this connection */ longword myaddr; word myport; word locflags; int queuelen; byte *queue; int rdatalen; /* must be signed */ word maxrdatalen; byte *rdata; byte rddata[tcp_MaxBufSize+1]; /* received data */ longword safetysig; word state; /* connection state */ longword acknum; longword seqnum; /* data ack'd and sequence num */ long timeout; /* timeout, in milliseconds */ byte unhappy; /* flag, indicates retransmitting segt's */ byte recent; /* 1 if recently transmitted */ word flags; /* tcp flags word for last packet sent */ word window; /* other guy's window */ int datalen; /* number of bytes of data to send */ /* must be signed */ int unacked; /* unacked data */ byte cwindow; /* Van Jacobson's algorithm */ byte wwindow; word vj_sa; /* VJ's alg, standard average */ word vj_sd; /* VJ's alg, standard deviation */ longword vj_last; /* last transmit time */ word rto; byte karn_count; /* count of packets */ byte tos; /* priority */ /* retransmission timeout proceedure */ /* these are in clock ticks */ longword rtt_lasttran; /* last transmission time */ longword rtt_smooth; /* smoothed round trip time */ longword rtt_delay; /* delay for next transmission */ longword rtt_time; /* time of next transmission */ word mss; longword inactive_to; /* for the inactive flag */ int sock_delay; byte data[tcp_MaxBufSize+1]; /* data to send */ } tcp_Socket; #else /* __WATTCP_USER */ /* * Don't give users access to the fields. */ typedef struct { byte undoc[((tcp_MaxBufSize*2)+204)]; // WAS [ 4300 ]; } tcp_Socket; #endif /* __WATTCP_USER__ */ #if defined(__WATTCP_KERNEL__) /* sock_type used for socket io */ typedef union { udp_Socket udp; tcp_Socket tcp; } sock_type; #else /* __WATTCP_USER__ */ typedef void sock_type; #endif /* __WATTCP_USER__ */ /* similar to UNIX */ struct sockaddr { word s_type; word s_port; longword s_ip; byte s_spares[6]; /* unused in TCP realm */ }; #define sockaddr_in sockaddr /* * TCP/IP system variables - do not change these since they * are not necessarily the source variables, instead use * ip_Init function */ extern longword my_ip_addr; extern longword sin_mask; /* eg. 0xfffffe00L */ extern word sock_delay; #if defined(__WATTCP_KERNEL__) extern eth_address _eth_addr; extern eth_address _eth_brdcast; #endif #if defined(__WATTCP_KERNEL__) /* * ARP definitions */ #define arp_TypeEther 0x100 /* ARP type of Ethernet address */ /* arp op codes */ #define ARP_REQUEST 0x0100 #define ARP_REPLY 0x0200 /* * Arp header */ typedef struct { word hwType; word protType; word hwProtAddrLen; // hw and prot addr len word opcode; eth_address srcEthAddr; longword srcIPAddr; eth_address dstEthAddr; longword dstIPAddr; } arp_Header; #define ETH_MSS 1400 // MSS for Ethernet byte *fragment( in_Header * ip ); void timeout_frags( void ); #endif /* * Ethernet interface -- pcsed.c */ void _eth_init( void ); byte *_eth_formatpacket( eth_address *eth_dest, word eth_type ); int _eth_send( word len ); void _eth_free( void *buf ); byte *_eth_arrived( word *type_ptr ); void _eth_release( void ); #if defined(__WATTCP_KERNEL__) extern void *_eth_hardware( byte *p ); #endif /* * timers -- pctcp.c */ void ip_timer_init( sock_type *s, int delayseconds ); int ip_timer_expired( sock_type *s ); longword MsecClock( void ); /* * sock_init() -- initialize wattcp libraries -- sock_ini.c */ void sock_init(void); void sock_exit( void ); /* normally called via atexit() in sock_init() */ /* * tcp_init/tcp_shutdown -- pctcp.c * - init/kill all tcp and lower services * - only call if you do not use sock_init * (NOT RECOMMENDED) */ void tcp_shutdown(void); void tcp_init(void); /* * things you probably won't need to know about */ /* * sock_debugdump -- sock_dbu.c * - dump some socket control block parameters * used for testing the kernal, not recommended */ void sock_debugdump( sock_type *s ); /* * tcp_config - read a configuration file * - if special path desired, call after sock_init() * - null reads path from executable * see sock_init(); */ int tcp_config( char *path ); /* * tcp_tick - called periodically by user application in sock_wait_... * - returns 1 when our socket closes */ int tcp_tick( sock_type *s ); /* * Retransmitter - called periodically to perform tcp retransmissions * - normally called from tcp_tick, you have to be pretty * low down to use this one */ void tcp_Retransmitter(void); /* * tcp_set_debug_state - set 1 or reset 0 - depends on what I have done */ void tcp_set_debug_state( int x ); /* * check for bugs -- pctcp.c */ int tcp_checkfor( sock_type *t ); /* * Timeout routines. */ unsigned long set_timeout( unsigned int seconds ); unsigned long set_ttimeout( unsigned int ticks ); int chk_timeout( unsigned long timeout ); /* * socket macros */ /* * sock_wait_established() * - waits then aborts if timeout on s connection * sock_wait_input() * - waits for received input on s * - may not be valid input for sock_gets... check returned length * sock_tick() * - do tick and jump on abort * sock_wait_closed(); * - discards all received data * * jump to sock_err with contents of *statusptr set to * 1 on closed * -1 on timeout * */ int _ip_delay0( sock_type *s, int timeoutseconds, sockfunct_t fn, int *statusptr ); int _ip_delay1( sock_type *s, int timeoutseconds, sockfunct_t fn, int *statusptr); int _ip_delay2( sock_type *s, int timeoutseconds, sockfunct_t fn, int *statusptr); #if defined(__WATTCP_KERNEL__) #define set_mstimeout( x ) (set_timeout(0)+ (x / 55)) #endif /* defined(__WATTCP_KERNEL__) */ #define sock_wait_established( s, seconds, fn, statusptr ) \ if (_ip_delay0( s, seconds, fn, statusptr )) goto sock_err; #define sock_wait_input( s, seconds, fn , statusptr ) \ if (_ip_delay1( s, seconds, fn, statusptr )) goto sock_err; #define sock_tick( s, statusptr ) \ if ( !tcp_tick(s)) { *statusptr = 1 ; goto sock_err; } #define sock_wait_closed(s, seconds, fn, statusptr )\ if (_ip_delay2( s, seconds, fn, statusptr )) goto sock_err; /* * TCP or UDP specific stuff, must be used for open's and listens, but * sock stuff is used for everything else -- pctcp.c */ int tcp_open( tcp_Socket *s, word lport, longword ina, word port, dataHandler_t datahandler ); int udp_open( udp_Socket *s, word lport, longword ina, word port, dataHandler_t datahandler ); int tcp_listen( tcp_Socket *s, word lport, longword ina, word port, dataHandler_t datahandler, word timeout ); int tcp_established( tcp_Socket *s ); /* * Clean up a string -- pctcp.c */ char *rip( char *s); /* * Name service / name lookup routines -- udp_dom.c */ longword resolve( char *name ); int reverse_addr_lookup( longword ipaddr, char *name ); /* * less general functions */ longword intel( longword x ); word intel16( word x ); longword MsecClock( void ); /* * Ctrl-break handling -- pc_cbrk.c */ void tcp_cbrk( int mode ); void outs( char far * string ); #if defined(__WATTCP_KERNEL__) /* icmp handler -- pcicmp.c */ int icmp_handler( in_Header *ip ); #endif /* * ARP -- pcarp.c */ #if defined(__WATTCP_KERNEL__) void _arp_add_gateway( char *data, longword ip ); int _arp_handler( arp_Header *in ); #endif void _arp_register( longword use, longword instead_of ); void _arp_tick( longword ip ); /* kernel only? */ int _arp_resolve( longword ina, eth_address *ethap, int nowait ); /* * Packet -- pcpkt.c * * These probably shouldn't be visible to user app code. */ eth_address *_pkt_eth_init( void ); int pkt_send( char *buffer, int length ); void pkt_buf_wipe( void ); void pkt_buf_release( char *ptr ); void * pkt_received( void ); void pkt_release( void ); #if defined(__WATTCP_KERNEL__) void _add_server( int *counter, int max, longword *array, longword value ); extern word debug_on; #endif /* * pcbsd.c */ int _chk_socket( sock_type *s ); char *inet_ntoa( char *s, longword x ); longword inet_addr( char *s ); char *sockerr( sock_type *s ); char *sockstate( sock_type *s ); longword gethostid( void ); longword sethostid( longword ip ); word ntohs( word a ); word htons( word a ); longword ntohl( longword x ); longword htonl( longword x ); #if defined(__WATTCP_KERNEL__) void *_tcp_lookup( longword hisip, word hisport, word myport ); void _tcp_cancel( in_Header *ip, int code, char *msg, longword dummyip ); void _udp_cancel( in_Header *ip ); int _dobootp(void); #endif /* * General socket I/O -- pctcp.c */ word sock_mode( sock_type *, word); /* see TCP_MODE_... */ void sock_abort( sock_type *); void tcp_sendsoon( tcp_Socket *s ); int sock_fastwrite( sock_type *, byte *, int ); int sock_write( sock_type *, byte *, int ); int sock_read( sock_type *, byte *, int ); int sock_fastread( sock_type *, byte *, int ); int sock_gets( sock_type *, byte *, int ); void sock_close( sock_type *s ); byte sock_putc( sock_type *s, byte c ); int sock_getc( sock_type *s ); int sock_puts( sock_type *s, byte *dp ); int sock_gets(sock_type *, byte *, int ); int sock_setbuf( sock_type *s, byte *dp, int len ); int sock_yield( tcp_Socket *s, void (*fn)( void ) ); /* * s is the pointer to a udp or tcp socket */ /* * Socket text output/input routines -- sock_prn.c */ int sock_printf( sock_type *s, char *format, ... ); int sock_scanf( sock_type *s, char *format, ... ); /* * Misc. socket I/O -- pctcp.c */ int sock_setbuf( sock_type *s, byte *dp, int len ); int sock_enqueue( sock_type *s, byte *dp, int len ); void sock_noflush( sock_type *s ); void sock_flush( sock_type *s ); void sock_flushnext( sock_type *s); int sock_dataready( sock_type *s ); int sock_established( sock_type *s ); void sock_sturdy( sock_type *s, int level ); /* * Debug output -- pcdbug.c */ void db_write( char *msg ); void db_open( void ); void db_close( void ); void dbug_printf( char *, ... ); void dbug_init( void ); void dbug_init( void ); /* * Socket Select -- select.c */ int sock_sselect( sock_type *s, int waitstate ); /* * recv routines -- pcrecv.c */ int sock_recv_init( sock_type *s, void *space, word len ); int sock_recv_from( sock_type *s, long *hisip, word *hisport, char *buffer, int len, word flags ); int sock_recv( sock_type *s, char *buffer, int len, word flags ); /* * bsd-similar stuff -- pcbuf.c */ int sock_rbsize( sock_type *s ); int sock_rbused( sock_type *s ); int sock_rbleft( sock_type *s ); int sock_tbsize( sock_type *s ); int sock_tbused( sock_type *s ); int sock_tbleft( sock_type *s ); int sock_preread( sock_type *s, byte *dp, int len ); /* * Name conversion stuff -- udp_nds.c */ longword aton( char *text ); int isaddr( char *text ); /* * Configuration -- pcconfig.c */ char *_inet_atoeth( char *src, byte *eth ); void _add_server( int *counter, int max, longword *array, longword value ); int tcp_config( char *path ); /* * name domain constants */ extern char *def_domain; extern longword def_nameservers[ MAX_NAMESERVERS ]; extern word wathndlcbrk; extern word watcbroke; /* user initialization file */ extern void (*usr_init)(char *name, char *value); extern int _survivebootp; extern int _last_cookie; extern longword _cookie[MAX_COOKIES]; extern int _last_nameserver; extern char *_hostname; /* * Elib stuff */ int isstring( char *string, unsigned stringlen ); /* isstring.c */ #endif /* ndef _wattcp_wattcp_h */