Watt-32 tcp/ip: Main Page

Watt-32 tcp/ip Documentation

2.2 dev-rel.10

Generated on Wed Jan 25 15:42:32 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/ERR.H File Reference

inc/ERR.H File Reference

Detailed Description

Compatibility header (for Net/FreeBSD programs)

Definition in file ERR.H.

Go to the source code of this file.

Generated on Wed Jan 25 15:42:40 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/NETDB.H File Reference

inc/NETDB.H File Reference

Detailed Description

BSD netdb functions.

Definition in file NETDB.H.

Go to the source code of this file.

Data Structures

struct | hostent
struct | netent
struct | servent
struct | protoent
struct | addrinfo

Functions

__BEGIN_DECLS W32_FUNC void
W32_CALL 		endhostent (void)
W32_FUNC void W32_CALL | endnetent (void)
W32_FUNC void W32_CALL | endprotoent (void)
W32_FUNC void W32_CALL | endservent (void)
W32_FUNC struct hostent *W32_CALL | gethostbyaddr (const char *, int, int)
W32_FUNC struct hostent *W32_CALL | gethostbyname (const char *)
W32_FUNC struct hostent *W32_CALL | gethostbyname2 (const char *, int af)
W32_FUNC struct hostent *W32_CALL | gethostent (void)
Return the next (non-commented) line from the host-file.
W32_FUNC struct hostent *W32_CALL | getipnodebyaddr (const void *, size_t, int, int *)
W32_FUNC struct hostent *W32_CALL | getipnodebyname (const char *, int, int, int *)
W32_FUNC struct netent *W32_CALL | getnetbyaddr (long, int)
W32_FUNC struct netent *W32_CALL | getnetbyname (const char *)
W32_FUNC struct netent *W32_CALL | getnetent (void)
W32_FUNC struct protoent
*W32_CALL 		getprotobyname (const char *)
W32_FUNC struct protoent
*W32_CALL 		getprotobynumber (int)
W32_FUNC struct protoent
*W32_CALL 		getprotoent (void)
W32_FUNC struct servent *W32_CALL | getservbyname (const char *, const char *)
W32_FUNC struct servent *W32_CALL | getservbyport (int, const char *)
W32_FUNC struct servent *W32_CALL | getservent (void)
W32_FUNC void W32_CALL | herror (const char *)
W32_FUNC const char *W32_CALL | hstrerror (int)
W32_FUNC void W32_CALL | sethostent (int)
W32_FUNC void W32_CALL | setnetent (int)
W32_FUNC void W32_CALL | setprotoent (int)
W32_FUNC void W32_CALL | setservent (int)
W32_FUNC int W32_CALL | getnameinfo (const struct sockaddr *sa, int salen, char *host, int hostlen, char *serv, int servlen, int flags)
W32_FUNC int W32_CALL | getaddrinfo (const char *hostname, const char *servname, const struct addrinfo *hints, struct addrinfo **res)
W32_FUNC void W32_CALL | freeaddrinfo (struct addrinfo *ai)
W32_FUNC void W32_CALL | freehostent (struct hostent *)
W32_FUNC char *W32_CALL | gai_strerror (int ecode)
W32_FUNC int W32_CALL | if_nametoindex (const char *)
W32_FUNC char *W32_CALL | if_indextoname (int, char *)
W32_FUNC int *W32_CALL | __h_errno_location (void)
W32_FUNC struct hostent *W32_CALL | gethostbyaddr_r (const char *addr, int len, int type, struct hostent *result, char *buffer, int buflen, int *h_errnop)
W32_FUNC struct hostent *W32_CALL | gethostbyname_r (const char *name, struct hostent *result, char *buffer, int buflen, int *h_errnop)
W32_FUNC struct hostent *W32_CALL | gethostent_r (struct hostent *result, char *buffer, int buflen, int *h_errnop)
W32_FUNC struct netent *W32_CALL | getnetbyaddr_r (long net, int type, struct netent *result, char *buffer, int buflen)
W32_FUNC struct netent *W32_CALL | getnetbyname_r (const char *name, struct netent *result, char *buffer, int buflen)
W32_FUNC struct netent *W32_CALL | getnetent_r (struct netent *result, char *buffer, int buflen)
W32_FUNC struct protoent
*W32_CALL 		getprotobyname_r (const char *name, struct protoent *result, char *buffer, int buflen)
W32_FUNC struct protoent
*W32_CALL 		getprotobynumber_r (int proto, struct protoent *result, char *buffer, int buflen)
W32_FUNC struct protoent
*W32_CALL 		getprotoent_r (struct protoent *result, char *buffer, int buflen)
W32_FUNC struct servent *W32_CALL | getservbyname_r (const char *name, const char *proto, struct servent *result, char *buffer, int buflen)
W32_FUNC struct servent *W32_CALL | getservbyport_r (int port, const char *proto, struct servent *result, char *buffer, int buflen)
W32_FUNC struct servent *W32_CALL | getservent_r (struct servent *result, char *buffer, int buflen)

Variables

W32_DATA int | h_errno

Function Documentation

W32_FUNC struct hostent* W32_CALL gethostent ( void )

Return the next (non-commented) line from the host-file.

Format is: ip-address host-name [alias..] {
| # ..} Definition at line 210 of file GETHOST.C.

References isaddr(), netdb_init(), StrLcpy(), and strltrim().

Generated on Wed Jan 25 15:42:40 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/RESOLV.H File Reference

inc/RESOLV.H File Reference

Detailed Description

Resolver API.

Definition in file RESOLV.H.

Go to the source code of this file.

Data Structures

struct | __res_state

Typedefs

typedef res_sendhookact(* | res_send_qhook )(struct sockaddr_in *const *ns, const u_char **query, int *querylen, u_char *ans, int anssiz, int *resplen)
typedef res_sendhookact(* | res_send_rhook )(const struct sockaddr_in *ns, const u_char *query, int querylen, u_char *ans, int anssiz, int *resplen)

Enumerations

enum res_sendhookact {
res_goahead,
res_nextns,
res_modified,
res_done,
res_error
}

Functions

__BEGIN_DECLS W32_FUNC int | __res_hnok (const char *)
W32_FUNC int | __res_ownok (const char *)
W32_FUNC int | __res_mailok (const char *)
W32_FUNC int | __res_dnok (const char *)
W32_FUNC int | __loc_aton (const char *ascii, u_char *binary)
W32_FUNC char * | __loc_ntoa (const u_char *binary, char *ascii)
W32_FUNC int | __dn_skipname (const u_char *, const u_char *)
W32_FUNC void | __fp_resstat (struct __res_state *, FILE *)
W32_FUNC void | __fp_query (const u_char *, FILE *)
W32_FUNC void | __fp_nquery (const u_char *, int, FILE *)
W32_FUNC char * | __hostalias (const char *)
W32_FUNC void | __putlong (u_long, u_char *)
W32_FUNC void | __putshort (u_short, u_char *)
W32_FUNC char * | __p_time (u_long)
W32_FUNC void | __p_query (const u_char *)
W32_FUNC const u_char * | __p_cdnname (const u_char *, const u_char *, int, FILE *)
W32_FUNC const u_char * | __p_cdname (const u_char *, const u_char *, FILE *)
W32_FUNC const u_char * | __p_fqname (const u_char *, const u_char *, FILE *)
W32_FUNC const u_char * | __p_rr (const u_char *, const u_char *, FILE *)
W32_FUNC const char * | __p_type (int)
W32_FUNC const char * | __p_class (int)
W32_FUNC const char * | __p_option (u_long option)
W32_FUNC int | dn_comp (const char *, u_char *, int, u_char **, u_char **)
W32_FUNC int | dn_expand (const u_char *, const u_char *, const u_char *, char *, int)
W32_FUNC int | res_init (void)
W32_FUNC u_short | res_randomid (void)
W32_FUNC int | res_query (const char *, int, int, u_char *, int)
W32_FUNC int | res_search (const char *, int, int, u_char *, int)
W32_FUNC int | res_querydomain (const char *, const char *, int, int, u_char *, int)
W32_FUNC int | res_mkquery (int, const char *, int, int, const u_char *, int, const u_char *, u_char *, int)
W32_FUNC int | res_send (const u_char *, int, u_char *, int)
W32_FUNC int | res_isourserver (const struct sockaddr_in *)
W32_FUNC int | res_nameinquery (const char *, int, int, const u_char *, const u_char *)
W32_FUNC int | res_queriesmatch (const u_char *, const u_char *, const u_char *, const u_char *)
W32_FUNC void | res_send_setqhook (res_send_qhook hook)
W32_FUNC void | res_send_setrhook (res_send_rhook hook)

Variables

W32_DATA struct __res_state | _res
W32_DATA int | h_errno

Function Documentation

W32_FUNC int res_mkquery | ( | int | op,
 |  | const char * | dname,
 |  | int | Class,
 |  | int | type,
 |  | const u_char * | data,
 |  | int | datalen,
 |  | const u_char * | newrr_in,
 |  | u_char * | buf,
 |  | int | buflen
 | ) |

Todo:
Handle STATUS case
Definition at line 67 of file RES_MKQU.C.

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/SYSLOG.H File Reference

inc/SYSLOG.H File Reference

Detailed Description

syslog header.

Definition in file SYSLOG.H.

Go to the source code of this file.

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/TCP.H File Reference

inc/TCP.H File Reference

Detailed Description

Watt-32 public API.

Definition in file TCP.H.

Go to the source code of this file.

Data Structures

struct | tcp_Socket
struct | udp_Socket
struct | config_table
struct | DHCP_config
struct | watt_sockaddr

Typedefs

typedef BYTE | eth_address [6]
typedef BYTE | ip6_address [16]
typedef int(* | ProtoHandler )(void *sock, const BYTE *data, unsigned len, const void *tcp_phdr, const void *udp_hdr)
typedef int(* | UserHandler )(void *sock)
typedef void(* | VoidProc )(void)
typedef long(* | WattUserConfigFunc )(int pass, const struct config_table *cfg)
typedef int(* | WattDHCPConfigFunc )(enum DHCP_config_op op, struct DHCP_config *cfg)

Enumerations

enum config_tab_types {
ARG_ATOI,
ARG_ATOB,
ARG_ATOW,
ARG_ATOIP,
ARG_ATOX_B,
ARG_ATOX_W,
ARG_ATOX_D,
ARG_STRDUP,
ARG_STRCPY,
ARG_RESOLVE,
ARG_FUNC
}
enum DHCP_config_op {
DHCP_OP_READ = 0,
DHCP_OP_WRITE = 1,
DHCP_OP_ERASE = 2
}
enum TCP_SIMPLE_STATE {
TCP_CLOSED,
TCP_LISTENING,
TCP_OPENING,
TCP_OPEN,
TCP_CLOSING
}
enum _optmode {
GETOPT_UNIX,
GETOPT_ANY,
GETOPT_KEEP
}

Functions

W32_FUNC const char * | wattcpVersion (void)
W32_FUNC const char * | wattcpCapabilities (void)
W32_FUNC int | watt_sock_init (size_t, size_t)
W32_FUNC const char * | sock_init_err (int rc)
W32_FUNC void | sock_exit (void)
Our only atexit() handler.
W32_FUNC void | dbug_init (void)
W32_FUNC void | init_misc (void)
Initialise various stuff.
W32_FUNC void | sock_sig_exit (const char *msg, int sigint)
Exit handler for unhandled signals.
W32_FUNC int | sock_read (void *s, char *dp, int len)
W32_FUNC int | sock_preread (void *s, char *dp, int len)
W32_FUNC int | sock_fastread (void *s, char *dp, int len)
W32_FUNC int | sock_write (void *s, const char *dp, int len)
W32_FUNC int | sock_enqueue (void *s, const char *dp, int len)
W32_FUNC int | sock_fastwrite (void *s, const char *dp, int len)
W32_FUNC size_t | sock_setbuf (void *s, char *buf, size_t len)
W32_FUNC void | sock_flush (void *s)
W32_FUNC void | sock_noflush (void *s)
W32_FUNC void | sock_flushnext (void *s)
W32_FUNC int | sock_puts (void *s, const char *dp)
W32_FUNC WORD | sock_gets (void *s, char *dp, int n)
W32_FUNC BYTE | sock_putc (void *s, char c)
W32_FUNC int | sock_getc (void *s)
W32_FUNC WORD | sock_dataready (void *s)
W32_FUNC int | sock_established (void *s)
W32_FUNC int | sock_close (void *s)
W32_FUNC int | sock_abort (void *s)
W32_FUNC int | sock_mode (void *s, WORD mode)
W32_FUNC int | sock_sselect (void *s, int waitstate)
W32_FUNC int | sock_timeout (void *s, int seconds)
W32_FUNC int | sock_recv (void *s, char *buf, unsigned len)
W32_FUNC int | sock_recv_init (void *s, char *buf, unsigned len)
W32_FUNC int | sock_recv_from (void *s, DWORD *ip, WORD *port, char *buf, unsigned len, int peek)
W32_FUNC int | sock_recv_used (void *s)
W32_FUNC int | sock_keepalive (void *s)
W32_FUNC size_t | sock_rbsize (const void *s)
W32_FUNC size_t | sock_rbused (const void *s)
W32_FUNC size_t | sock_rbleft (const void *s)
W32_FUNC size_t | sock_tbsize (const void *s)
W32_FUNC size_t | sock_tbused (const void *s)
W32_FUNC size_t | sock_tbleft (const void *s)
W32_FUNC int MS_CDECL | sock_printf (void *s, const char *fmt,...) __attribute__((format(printf
W32_FUNC int MS_CDECL | sock_scanf (void *s, const char *fmt,...) __attribute__((format(scanf
W32_FUNC int | udp_open (void *s, WORD lport, DWORD ina, WORD port, ProtoHandler handler)
W32_FUNC int | tcp_open (void *s, WORD lport, DWORD ina, WORD port, ProtoHandler handler)
W32_FUNC int | udp_listen (void *s, WORD lport, DWORD ina, WORD port, ProtoHandler handler)
W32_FUNC int | tcp_listen (void *s, WORD lport, DWORD ina, WORD port, ProtoHandler handler, WORD timeout)
W32_FUNC int | tcp_established (const void *s)
W32_FUNC DWORD | resolve (const char *name)
Convert host name to an address.
W32_FUNC int | resolve_ip (DWORD ip, char *name, int len)
W32_FUNC DWORD | lookup_host (const char *host, char *ip_str)
W32_FUNC const char * | dom_strerror (int err)
Return text for error code (dom_errno).
W32_FUNC int | tcp_cbreak (int mode)
Sets our break mode.
W32_FUNC DWORD | aton (const char *name)
Converts [a.b.c.d] or a.b.c.d to 32 bit IPv4 address.
W32_FUNC int | isaddr (const char *name)
Check if 'str' is simply an ip address.
W32_FUNC char * | rip (char *s)
Removes end-of-line termination from a string.
W32_FUNC int | watt_kbhit (void)
A less CPU hogging kbhit().
W32_FUNC const char * | tcp_md5_secret (void *s, const char *secret)
W32_FUNC DWORD | set_timeout (DWORD msec)
Return time for when given timeout (msec) expires.
W32_FUNC int | chk_timeout (DWORD value)
Check if milli-sec value has expired:.
W32_FUNC int | cmp_timers (DWORD t1, DWORD t2)
Compare two timers with expirary at 't1' and 't2'.
W32_FUNC int | set_timediff (long msec)
Must be called by user right before or after a time change occurs.
W32_FUNC long | get_timediff (DWORD now, DWORD t)
Return time difference between timers 'now' and 'tim'.
W32_FUNC int | hires_timer (int on)
Control use of high-resolution timer.
W32_FUNC double | timeval_diff (const struct timeval *a, const struct timeval *b)
W32_FUNC void | init_timer_isr (void)
W32_FUNC void | exit_timer_isr (void)
W32_FUNC void | init_userSuppliedTimerTick (void)
init_userSuppliedTimerTick() - setup timer handling for programs that are already running a periodic interrupt or whatever (i.e.
W32_FUNC void | userTimerTick (DWORD)
Provide timer-ticks from an application.
W32_FUNC void | ip_timer_init (sock_type *s, unsigned delayseconds)
W32_FUNC int | ip_timer_expired (const sock_type *s)
W32_FUNC void | sock_debugdump (const sock_type *s)
W32_FUNC long | tcp_config (const char *path)
W32_FUNC WORD | tcp_tick (sock_type *s)
Must be called periodically by user application (or BSD socket API).
W32_FUNC void | tcp_set_debug_state (WORD x)
Used when DEBUG=x is defined in the config file Moved from pctcp.c.
W32_FUNC int | _ip_delay0 (void *s, int sec, UserHandler fn, void *statusptr)
W32_FUNC int | _ip_delay1 (void *s, int sec, UserHandler fn, void *statusptr)
W32_FUNC int | _ip_delay2 (void *s, int sec, UserHandler fn, void *statusptr)
W32_FUNC int | parse_config_table (const struct config_table *tab, const char *section, const char *name, const char *value)
Parse the config-table and if a match is found for ('section'+'.'+)'name' either store variable to 'value' or call function with 'value'.
W32_FUNC void | tcp_inject_config (const struct config_table *cfg, const char *key, const char *value)
Callable from a user application to inject config values before the normal WATTCP.CFG is loaded and parsed.
W32_FUNC WattUserConfigFunc | _watt_user_config (WattUserConfigFunc fn)
A user application may call the `_watt_user_config()' function prior to calling sock_init() to inject its own configuration values into the tcp_config() parser.
W32_FUNC WattDHCPConfigFunc | dhcp_set_config_func (WattDHCPConfigFunc fn)
Sets up an application hook for doing DHCP operations (DHCP_config_op).
W32_DATA | int (MS_CDECL *_printf)(const char *
W32_FUNC void | outs (const char *s)
W32_FUNC void | outsnl (const char *s)
W32_FUNC void | outsn (const char *s, int n)
W32_FUNC void | outhexes (const char *s, int n)
W32_FUNC void | outhex (char ch)
W32_FUNC int | wintr_enable (void)
W32_FUNC void | wintr_disable (void)
W32_FUNC void | wintr_shutdown (void)
W32_FUNC void | wintr_init (void)
W32_FUNC int | _ping (DWORD host, DWORD num, const BYTE *pattern, long len)
W32_FUNC DWORD | _chk_ping (DWORD host, DWORD *ping_num)
Check for ICMP echo reply in ping-cache.
W32_FUNC int | _eth_init (void)
Initialize the network driver interface.
W32_FUNC void | _eth_release (void)
Release the hardware driver.
W32_FUNC void * | _eth_formatpacket (const void *eth_dest, WORD eth_type)
_eth_format_packet() places the next packet to be transmitted into the above link-layer output packet.
W32_FUNC void | _eth_free (const void *buf)
Free an input buffer once it is no longer needed.
W32_FUNC void * | _eth_arrived (WORD *type, BOOL *brdcast)
Poll for arrival of new packets (IP/ARP/RARP/PPPoE protocol).
W32_FUNC int | _eth_send (WORD len, const void *sock, const char *file, unsigned line)
_eth_send() does the actual transmission once we are complete with filling the buffer.
W32_FUNC int | _eth_set_addr (const void *addr)
Sets a new MAC address for our interface.
W32_FUNC BYTE | _eth_get_hwtype (BYTE *hwtype, BYTE *hwlen)
Fill in hardware address type/length for BOOTP/DHCP packets.
W32_FUNC WORD | in_checksum (const void *buf, unsigned len)
This checksum routine is only used by 16-bit targets (and files outside the library).
W32_FUNC DWORD | _gethostid (void)
Core style: Returns local IPv4-address.
W32_FUNC DWORD | _sethostid (DWORD ip)
Core-style: Sets local IPv4-address.
W32_FUNC int | _getsockname (const void *s, void *dest, int *len)
W32_FUNC int | _getpeername (const void *s, void *dest, int *len)
W32_FUNC int | _chk_socket (const void *s)
W32_FUNC void | psocket (const void *s)
W32_FUNC char * | _inet_ntoa (char *s, DWORD x)
Convert an IP-address 'ip' into a string.
W32_FUNC DWORD | _inet_addr (const char *name)
Convert a string into an IP-address.
W32_FUNC BOOL | _arp_register (DWORD use, DWORD instead_of)
ICMP redirection.
W32_FUNC BOOL | _arp_resolve (DWORD ina, eth_address *res)
Blocking ARP resolve functions.
W32_FUNC int | addwattcpd (VoidProc p)
W32_FUNC int | delwattcpd (VoidProc p)
W32_FUNC void | _sock_debug_on (void)
W32_FUNC void | _sock_debug_off (void)
W32_FUNC const char * | sockerr (const void *s)
W32_FUNC void | sockerr_clear (void *s)
W32_FUNC const char * | sockstate (const void *s)
W32_FUNC enum TCP_SIMPLE_STATE | tcp_simple_state (const tcp_Socket *s)
W32_FUNC int | close_s (int s)
W32_FUNC int | write_s (int s, const char *buf, int nbyte)
W32_FUNC int | read_s (int s, char *buf, int nbyte)
W32_FUNC int | writev_s (int s, const struct iovec *vector, size_t count)
W32_FUNC int | readv_s (int s, const struct iovec *vector, size_t count)
W32_FUNC const sock_type * | __get_sock_from_s (int s, int proto)
Hack function if user app needs to use Wattcp core functions for BSD sockets.
W32_FUNC int | select_s (int num_sockets, fd_set *read_events, fd_set *write_events, fd_set *except_events, struct timeval *timeout)
The select_s() function.
W32_FUNC int W32_CALL | select (int num_sockets, fd_set *read_events, fd_set *write_events, fd_set *except_events, struct timeval *timeout)
W32_FUNC int W32_CALL | gethostname (char *name, int len)
W32_FUNC int | join_mcast_group (DWORD ip)
W32_FUNC int | leave_mcast_group (DWORD ip)
W32_FUNC int | _ip4_is_multicast (DWORD ip)
W32_FUNC int | multi_to_eth (DWORD ip, eth_address *eth)
W32_FUNC int | udp_SetTTL (udp_Socket *s, BYTE ttl)
W32_FUNC int | getopt (int argc, char *const *argv, const char *opt_str)
W32_FUNC void | print_mac_stats (void)
W32_FUNC void | print_pkt_stats (void)
W32_FUNC void | print_vjc_stats (void)
W32_FUNC void | print_arp_stats (void)
W32_FUNC void | print_pppoe_stats (void)
W32_FUNC void | print_ip4_stats (void)
W32_FUNC void | print_ip6_stats (void)
W32_FUNC void | print_icmp_stats (void)
W32_FUNC void | print_igmp_stats (void)
W32_FUNC void | print_udp_stats (void)
W32_FUNC void | print_tcp_stats (void)
W32_FUNC void | print_all_stats (void)
W32_FUNC void | reset_stats (void)
W32_FUNC int | sock_stats (void *s, DWORD *days, WORD *inactive, WORD *cwindow, DWORD *avg, DWORD *sd)
W32_FUNC void | backgroundon (void)
W32_FUNC void | backgroundoff (void)
W32_FUNC void | backgroundfn (VoidProc func)
W32_FUNC int | ffs (int mask)
W32_FUNC int | system (const char *cmd)
pragma | Alias (system,"_mw_watt_system")
W32_FUNC unsigned | Random (unsigned a, unsigned b)
Returns a random integer in range [a..b].
W32_FUNC int | trace2com_init (WORD portAddress, DWORD baudRate)
W32_FUNC int MS_CDECL | __trace2com (const char *fmt,...) __attribute__((format(printf

Variables

W32_FUNC void(*)(void) | sock_yield (void *s, VoidProc fn)
W32_DATA DWORD | my_ip_addr
W32_DATA DWORD | sin_mask
W32_DATA int | sock_delay
W32_DATA int | sock_inactive
W32_DATA int | sock_data_timeout
W32_DATA WORD | multihomes
W32_DATA int | block_tcp
W32_DATA int | block_udp
W32_DATA int | block_icmp
W32_DATA int | block_ip
W32_DATA WORD | last_cookie
W32_DATA DWORD | cookies [MAX_COOKIES]
W32_DATA BOOL | survive_eth
W32_DATA BOOL | survive_bootp
W32_DATA BOOL | survive_dhcp
W32_DATA BOOL | survive_rarp
W32_DATA void(* | loopback_handler )(void *ip)
W32_DATA char * | def_domain
W32_DATA int | dom_errno
W32_DATA DWORD | def_nameservers [MAX_NAMESERVERS]
W32_DATA WORD | dns_timeout
W32_DATA WORD | last_nameserver
W32_DATA WORD | _watt_handle_cbreak
W32_DATA volatile int | _watt_cbroke
W32_DATA unsigned | _mtu
W32_DATA unsigned | _mss
W32_DATA int | ctrace_on
W32_DATA int | has_rdtsc
W32_DATA DWORD | clocks_per_usec
W32_DATA void(* | usr_init )(const char *keyword, const char *value)
W32_DATA void(* | usr_post_init )(void)
W32_DATA int | _watt_no_config
W32_DATA void(* | _outch )(char c)
W32_DATA int(* | _resolve_hook )(void)
W32_DATA void(* | wintr_chain )(void)
W32_DATA int(* | tftp_writer )(const void *buf, unsigned length)
W32_DATA int(* | tftp_terminator )(void)
W32_DATA void *(* | _eth_recv_hook )(WORD *type)
W32_DATA int(* | _eth_recv_peek )(void *mac_buf)
W32_DATA int(* | _eth_xmit_hook )(const void *buf, unsigned len)
W32_DATA int | _multicast_on
W32_DATA char * | optarg
W32_DATA int | optind
W32_DATA int | opterr
W32_DATA int | optopt
W32_DATA char * | optswchar
W32_DATA enum _optmode | optmode

Function Documentation

W32_FUNC const sock_type* __get_sock_from_s | ( | int | s,
 |  | int | proto
 | ) |

Hack function if user app needs to use Wattcp core functions for BSD sockets.

Must *not* modify return value in any way. Definition at line 293 of file SOCKET.C.

References _socklist_find().

W32_FUNC BOOL _arp_register | ( | DWORD | use_this_gateway_ip,
 |  | DWORD | for_this_host_ip
 | ) |

ICMP redirection.

Called on ICMP-redirects.

Redirects are sent from a gateway/router, telling us that a different gateway is better suited to connect to the specified host than the one we were using. Definition at line 727 of file PCARP.C.

References route_entry::gate_ip, is_on_LAN(), LAN_lookup(), and LAN_start_lookup().

W32_FUNC BOOL _arp_resolve | ( | DWORD | ina,
 |  | eth_address * | res
 | ) |

Blocking ARP resolve functions.

Doesn't return until success or time-out. Definition at line 1117 of file PCARP.C.

References _eth_addr, _pktserial, arp_daemon(), DWORD, eth_address, is_on_LAN(), LAN_lookup(), LAN_lookup_pending(), LAN_start_lookup(), route_lookup(), route_lookup_pending(), route_start_lookup(), tcp_tick(), and WORD.

W32_FUNC DWORD _chk_ping | ( | DWORD | host,
 |  | DWORD * | number
 | ) |

Check for ICMP echo reply in ping-cache.

Return values:
reply | time in system ticks.
(DWORD)-1 | on failure
Definition at line 172 of file PCPING.C.

References DWORD, ping_cache::host, ping_cache::number, and ping_cache::time.

W32_FUNC void* _eth_arrived | ( | WORD * | type_ptr,
 |  | BOOL * | broadcast
 | ) |

Poll for arrival of new packets (IP/ARP/RARP/PPPoE protocol).

Sets protocol-type of packet received in 'type'.

For Ethernet/TokenRing-type drivers:

Return values:
Pointer past the MAC-header to the IP/ARP/RARP protocol header. Also check for link-layer broadcast.
For PPP/SLIP-type drivers (no MAC-headers):
Return values:
Pointer to the IP-packet itself. IP-protocol is assumed. Can never be link-layer broadcast.

<

Todo:
push back packet, else it's lost
Definition at line 1009 of file PCSED.C.

References _eth_brdcast, _eth_free(), _eth_is_init, _eth_recv_hook, _ip_recursion, _pktdevclass, _pktserial, BYTE, fix_llc_head(), macstat::num_ip_recurse, poll_recv_queue(), update_in_stat(), and WORD.

W32_FUNC void* _eth_formatpacket | ( | const void * | mac_dest,
 |  | WORD | eth_type
 | ) |

_eth_format_packet() places the next packet to be transmitted into the above link-layer output packet.

Returns:
address of higher-level protocol (IP/RARP/RARP) header.
Definition at line 129 of file PCSED.C.

References WORD.

W32_FUNC BYTE _eth_get_hwtype | ( | BYTE * | hwtype,
 |  | BYTE * | hwlen
 | ) |

Fill in hardware address type/length for BOOTP/DHCP packets.

Also used for ARP/RARP packets. Should never be called for PPP/SLIP. Definition at line 735 of file PCSED.C.

References _pktdevclass, arcnet_address, ax25_address, BYTE, eth_address, fddi_address, and tok_address.

W32_FUNC int _eth_init ( void )

Initialize the network driver interface.

Returns:
0 okay.

error-code otherwise.

Definition at line 645 of file PCSED.C.

References _eth_addr, _eth_brdcast, _eth_get_hwtype(), _eth_is_init, _eth_loop_addr, _eth_mac_len, _eth_real_addr, _eth_release(), _pktdevclass, arcnet_mac_format(), eth_address, eth_mac_format(), eth_mac_xmit(), fddi_mac_format(), mac_tx_format, null_mac_format(), pkt_buf_wipe(), pkt_eth_init(), and tok_mac_format().

W32_FUNC int _eth_send | ( | WORD | len,
 |  | const void * | sock,
 |  | const char * | file,
 |  | unsigned | line
 | ) |

_eth_send() does the actual transmission once we are complete with filling the buffer.

Do any last minute patches here, like fix the size. Send to "loopback" device if it's IP and destination matches loopback network (127.x.x.x.).

Return length of network-layer packet (not length of link-layer packet). Definition at line 300 of file PCSED.C.

References _eth_is_init, _eth_last, _pkt_ip_ofs, _pktdevclass, in6_Header::destination, in_Header::destination, has_rdtsc, send_loopback(), update_out_stat(), and WORD.

W32_FUNC DWORD _gethostid ( void )

Core style: Returns local IPv4-address.

Return values:
address on host order.
Definition at line 32 of file BSDNAME.C.

References DWORD, and my_ip_addr.

W32_FUNC DWORD _inet_addr ( const char * s )

Convert a string into an IP-address.

Return values:
address | on host order.
0 | string isn't a (dotless) address.
Definition at line 65 of file NETADDR.C.

References aton(), DWORD, isaddr(), and isaddr_dotless().

W32_FUNC char* _inet_ntoa | ( | char * | s,
 |  | DWORD | ip
 | ) |

Convert an IP-address 'ip' into a string.

Return values:
's'.
Note:
'ip' is on host order.
Definition at line 40 of file NETADDR.C.

W32_FUNC DWORD _sethostid ( DWORD ip )

Core-style: Sets local IPv4-address.

Return values:
address on host order.
Definition at line 41 of file BSDNAME.C.

References DWORD, and my_ip_addr.

W32_FUNC WattUserConfigFunc _watt_user_config ( WattUserConfigFunc fn )

A user application may call the `_watt_user_config()' function prior to calling sock_init() to inject its own configuration values into the tcp_config() parser.

Useful when running diskless and setting `_watt_no_config = 0'.

Example:

  • 'pass' is 1 for first pass (PKTDRVR/WinPcap configuration), 2 for second pass.
  • 'cfg' is a pointer to the configuration table and must be passed to tcp_inject_config() as-is.

In most cases 'pass' can probably be ignored.

static long my_config_fn (int pass, const struct config_table *cfg) { // Keyword case is not significant (tcp_inject_config will convert // all keys to uppercase)

tcp_inject_config (cfg, "My_IP", "192.168.0.98"); tcp_inject_config (cfg, "NetMask", "255.255.255.0"); tcp_inject_config (cfg, "Gateway", "192.168.0.1"); (void)pass; return (1); // Returning 0 would make tcp_config() return 0 too, // as if the config file was not found }

int main (void) { _watt_no_config = 1; _watt_user_config (my_config_fn); if (sock_init()) return (-1); ... }

Never called inside Watt-32. Definition at line 184 of file SOCK_INI.C.

W32_FUNC DWORD aton ( const char * str )

Converts [a.b.c.d] or a.b.c.d to 32 bit IPv4 address.

Return values:
0 | on error (safer than -1)
IPv4 | address (host order)
Definition at line 82 of file NETADDR.C.

References DWORD.

W32_FUNC int chk_timeout ( DWORD value )

Check if milli-sec value has expired:.

Return values:
\li TRUE timer expired
  • FALSE not expired (or value not set)
Definition at line 528 of file TIMER.C.

References DWORD, has_8254, and set_timeout().

W32_FUNC int cmp_timers | ( | DWORD | t1,
 |  | DWORD | t2
 | ) |

Compare two timers with expirary at 't1' and 't2'.

Return values:
\li -1 if t1 expires before t2
  • 0 if t1 == t2
  • +1 if t1 expires after t2
Note:
This logic fails when timers approaches ULONG_MAX after approx. 50 days.
Definition at line 347 of file TIMER.C.

W32_FUNC long get_timediff | ( | DWORD | now,
 |  | DWORD | tim
 | ) |

Return time difference between timers 'now' and 'tim'.

Check for day rollover. Max timer distance is 24 hours. This function should be called immediately after chk_timeout() is called. Definition at line 598 of file TIMER.C.

References has_8254.

W32_FUNC int hires_timer ( int on )

Control use of high-resolution timer.

When using Watt-32 together with programs that reprogram the PIT (8254 timer chip), the millisec_clock() function may return wrong values. In such cases it's best to use old-style 55ms timers. Using Watt-32 with Allegro graphics library is one such case where application program should call `ÿhires_timer(0)' after `sock_init()' has been called. Definition at line 363 of file TIMER.C.

References chk_timeout(), and has_8254.

W32_FUNC WORD in_checksum | ( | const void * | ptr,
 |  | unsigned | len
 | ) |

This checksum routine is only used by 16-bit targets (and files outside the library).

32-bit targets use in_checksum_fast() in chksum0.s + chksum0.asm.

Note:
`in_check_sum()' and `in_checksum_fast()' are equally fast on a Pentium 4 CPU. But on a Pentium 2 the ASM version is approx. 10 times faster.
Definition at line 29 of file CHKSUM.C.

References BYTE, and WORD.

W32_FUNC void init_misc ( void )

Initialise various stuff.

Todo:
Definition at line 318 of file MISC.C.

References _watt_assert_buf, _watt_dosFp, _watt_os_ver, DWORD, has_rdtsc, init_timers(), and win32_dos_box.

W32_FUNC void init_userSuppliedTimerTick ( void )

init_userSuppliedTimerTick() - setup timer handling for programs that are already running a periodic interrupt or whatever (i.e.

ALLEGRO & more). This is called to signify that the 'user task' will periodically call userTimerTick() to supply the elapsed time since the last call. Best called once before sock_init(). There is no way to revert to original timer handling once this is called. By GvB 2002-09 Definition at line 148 of file TIMER.C.

References has_8254.

W32_FUNC int isaddr ( const char * str )

Check if 'str' is simply an ip address.

Accepts 'a.b.c.d' or '[a.b.c.d]' forms.

Return values:
TRUE if 'str' is an IPv4 address.
Definition at line 124 of file NETADDR.C.

W32_FUNC DWORD resolve ( const char * name )

Convert host name to an address.

Returns 0 if name is unresolvable right now. Return value is host-order. Definition at line 756 of file UDP_DOM.C.

References aton(), called_from_resolve, dom_strerror(), DWORD, isaddr(), lookup_domain(), my_ip_addr, next_domain(), query_init(), rip(), set_timeout(), UINT, and WORD.

W32_FUNC char* rip ( char * s )

Removes end-of-line termination from a string.

Removes "\n" (Unix), "\r" (MacOS) or "\r\n" (DOS/net-ascii) terminations, but not single "\n\r" (who uses that?). Definition at line 176 of file STRINGS.C.

W32_FUNC int select_s | ( | int | nfds,
 |  | fd_set * | readfds,
 |  | fd_set * | writefds,
 |  | fd_set * | exceptfds,
 |  | struct timeval * | timeout
 | ) |

The select_s() function.

Note:
It supports more sockets than would fit in a fd_set. I.e. it handles an array of 'fd_set's on input/output. Thus it is the user's responsibilty to not use a too high 'nfds' value. I.e. If nfs > 512*8 and user fd_set's on input is smaller than 512*, select_s() could trash the fd_set's on output.

Clear our "working" fd_sets.

Note:
Don't use FD_ZERO() since our working fd_sets contain more than FD_SETSIZE sockets.
Definition at line 112 of file SELECT.C.

References _sock_crit_start(), _sock_crit_stop(), DWORD, exc_select(), sel_min_block, socket(), and tcp_tick().

W32_FUNC int set_timediff ( long msec )

Must be called by user right before or after a time change occurs.

Not used in Watt-32. Definition at line 585 of file TIMER.C.

W32_FUNC DWORD set_timeout ( DWORD msec )

Return time for when given timeout (msec) expires.

Make sure it never returns 0 (it will confuse chk_timeout). Definition at line 487 of file TIMER.C.

References DWORD, and has_8254.

W32_FUNC void sock_exit ( void )

Our only atexit() handler.

Called only once during normal program shutdown. Exception handlers exit differently (see except_handler() above) Definition at line 985 of file SOCK_INI.C.

References _watt_fatal_error, _watt_is_init, rundown_run(), sock_init_called, and tcp_shutdown().

W32_FUNC int tcp_cbreak ( int mode )

Sets our break mode.

  • `mode' is composed of the following flags
    • 0x01: disallow breakouts
    • 0x10: display a message upon ^C/^BREAK (default)
Definition at line 172 of file PC_CBRK.C.

References set_cbreak(), sig_handler_watt(), sock_sig_exit(), and win32_dos_box.

W32_FUNC void tcp_inject_config | ( | const struct config_table * | cfg,
 |  | const char * | key,
 |  | const char * | value
 | ) |

Callable from a user application to inject config values before the normal WATTCP.CFG is loaded and parsed.

See '_watt_user_config' in sock_ini.c. Definition at line 848 of file PCCONFIG.C.

References strntrimcpy(), tcp_inject_config_direct(), and UINT.

W32_FUNC WORD tcp_tick ( sock_type * s )

Must be called periodically by user application (or BSD socket API).

  • if 's != NULL', check this socket for timeout.
  • if 's == NULL', check all sockets in list.
Return values:
0 | if 's' is non-NULL and 's' closes.
!0 | if 's' is NULL or 's' is still open.

Don't enter this loop if reentered. That could return the same packet twice (before we call _eth_free() on the 1st packet).

Todo:
Limit the time spent here (clamp # of loops)
Definition at line 1397 of file PCTCP.C.

References _arp_handler(), _eth_arrived(), _eth_free(), _ip4_handler(), _rarp_handler(), _tcp_unthread(), chk_timeout(), daemon_timer, pppoe_handler(), run_daemons(), set_timeout(), _tcp_Socket::state, sock_type::tcp, tcp_Retransmitter(), and WORD.

W32_FUNC void userTimerTick ( DWORD elapsed_time_msec )

Provide timer-ticks from an application.

This should be periodically called from user code to increment the timer count once activated via init_userSuppliedTimerTick(). Best called from a periodic interrupt handler (int 8/1Ch/70h) which is the case now with init_timer_isr(). GvB 2002-09 Definition at line 175 of file TIMER.C.

W32_FUNC int watt_sock_init | ( | size_t | tcp_Sock_size,
 |  | size_t | udp_Sock_size
 | ) |

Todo:
Use auto-configuration and set 'my_ip_addr' to 169.254/16
Definition at line 697 of file SOCK_INI.C.

References _arp_check_gateways(), _arp_init(), _bootp_on, _dhcp_on, _do_mask_req, _inet_ntoa(), _pkt_inf, _rarp_on, _watt_is_init, _watt_no_config, addwattcpd(), DHCP_init(), DHCP_read_config(), do_exit(), echo_discard_init(), echo_discard_start(), get_day_num(), init_misc(), my_ip_addr, old_break, pppoe_init(), pppoe_start(), reverse_lookup_myip(), set_timeout(), setup_sig_handlers(), sin_mask, sock_exit(), sock_init_called, start_day, start_time, survive_eth, tcp_cbreak(), tcp_do_boot(), tcp_init(), tcp_post_init(), and tftp_init().

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/arpa/FTP.H File Reference

inc/arpa/FTP.H File Reference

Detailed Description

FTP definitions.

Definition in file FTP.H.

Go to the source code of this file.

Variables

const char * | typenames [] = {"0", "ASCII", "EBCDIC", "Image", "Local" }
const char * | formnames [] = {"0", "Nonprint", "Telnet", "Carriage-control" }
const char * | strunames [] = {"0", "File", "Record", "Page" }
const char * | modenames [] = {"0", "Stream", "Block", "Compressed" }
const char * | levelnames [] = {"0", "Clear", "Safe", "Private", "Confidential" }

Generated on Wed Jan 25 15:42:40 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/arpa/INET.H File Reference

inc/arpa/INET.H File Reference

Detailed Description

Address conversions.

Definition in file INET.H.

Go to the source code of this file.

Functions

__BEGIN_DECLS W32_FUNC int | ascii2addr (int, const char *, void *)
W32_FUNC char * | addr2ascii (int, const void *, int, char *)
W32_FUNC struct in_addr W32_CALL | inet_makeaddr (u_long, u_long)
Formulate an Internet address from network + host (with subnet address).
W32_FUNC u_long W32_CALL | inet_addr (const char *)
W32_FUNC u_long W32_CALL | inet_lnaof (struct in_addr)
Return the local network address portion of an internet address; handles class A/B/C network number formats only.
W32_FUNC u_long W32_CALL | inet_netof (struct in_addr)
Return the network number from an internet address; handles class A/B/C network #'s.
W32_FUNC u_long W32_CALL | inet_network (const char *)
W32_FUNC int W32_CALL | inet_aton (const char *s, struct in_addr *adr)
W32_FUNC char *W32_CALL | inet_ntoa (struct in_addr)
W32_FUNC char *W32_CALL | inet_ntoa_r (struct in_addr adr, char *buf, int buflen)
W32_FUNC char *W32_CALL | inet_nsap_ntoa (int binlen, const u_char *binary, char *ascii)
W32_FUNC u_int W32_CALL | inet_nsap_addr (const char *ascii, u_char *binary, int maxlen)
W32_FUNC const char *W32_CALL | inet_ntop (int af, const void *src, char *dst, size_t size)
Convert a network format address to presentation format.
W32_FUNC int W32_CALL | inet_pton (int af, const char *src, void *dst)
Convert from presentation format (which usually means ASCII printable) to network format (which is usually some kind of binary format).

Function Documentation

W32_FUNC u_long W32_CALL inet_lnaof ( struct in_addr addr )

Return the local network address portion of an internet address; handles class A/B/C network number formats only.

Note:
return value is host-order.
Definition at line 351 of file NETADDR.C.

W32_FUNC struct in_addr W32_CALL inet_makeaddr | ( | u_long | net,
 |  | u_long | host
 | ) |

Formulate an Internet address from network + host (with subnet address).

Note:
'net' is on host-order.
Definition at line 368 of file NETADDR.C.

References inet_makeaddr().

W32_FUNC const char* W32_CALL inet_ntop | ( | int | af,
 |  | const void * | src,
 |  | char * | dst,
 |  | size_t | size
 | ) |

Convert a network format address to presentation format.

Return values:
pointer | to presentation format address (`dst'),
NULL | on error (see errno).
Author:
Paul Vixie, 1996.
Definition at line 40 of file PRESADDR.C.

References inet_ntop4(), and inet_ntop6().

W32_FUNC int W32_CALL inet_pton | ( | int | af,
 |  | const char * | src,
 |  | void * | dst
 | ) |

Convert from presentation format (which usually means ASCII printable) to network format (which is usually some kind of binary format).

Return values:
1 | the address was valid for the specified address family.
0 | the address wasn't valid (`dst' is untouched in this case).
-1 | some other error occurred (`dst' is untouched in this case, too).
Author:
Paul Vixie, 1996.
Definition at line 66 of file PRESADDR.C.

References inet_pton4(), and inet_pton6().

Generated on Wed Jan 25 15:42:40 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/arpa/NAMESER.H File Reference

inc/arpa/NAMESER.H File Reference

Detailed Description

Nameserver API.

Definition in file NAMESER.H.

Go to the source code of this file.

Data Structures

struct | HEADER
struct | rrec

Functions

__BEGIN_DECLS W32_FUNC u_short | _getshort (const u_char *)
W32_FUNC u_long | _getlong (const u_char *)

Generated on Wed Jan 25 15:42:40 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/arpa/TELNET.H File Reference

inc/arpa/TELNET.H File Reference

Detailed Description

Telnet definitions.

Definition in file TELNET.H.

Go to the source code of this file.

Variables

const char * | telcmds []
const char * | telopts [NTELOPTS+1]
const char * | slc_names [] = { SLC_NAMELIST }
const char * | authtype_names []
const char * | encrypt_names []
const char * | enctype_names []

Variable Documentation

W32_DATA const char * authtype_names

Initial value:

 {
             "NULL", "KERBEROS_V4", "KERBEROS_V5", "SPX", "MINK", "SRP", 0
           }
Definition at line 295 of file TELNET.H.

W32_DATA const char * encrypt_names

Initial value:

 {
        "IS", "SUPPORT", "REPLY", "START", "END",
        "REQUEST-START", "REQUEST-END", "ENC-KEYID", "DEC-KEYID",
        0
  }
Definition at line 336 of file TELNET.H.

W32_DATA const char * enctype_names

Initial value:

 {
        "ANY", "DES_CFB64",  "DES_OFB64",  "UNKNOWN",  "UNKNOWN",  "UNKNOWN",
        "UNKNOWN",  "UNKNOWN",  "CAST5_40_CFB64",  "CAST5_40_OFB64",
        "CAST128_CFB64",  "CAST128_OFB64",  0,
  }
Definition at line 337 of file TELNET.H.

W32_DATA const char * telcmds

Initial value:

 {
             "EOF", "SUSP", "ABORT", "EOR",
             "SE", "NOP", "DMARK", "BRK", "IP", "AO", "AYT", "EC",
             "EL", "GA", "SB", "WILL", "WONT", "DO", "DONT", "IAC", 0
           }
Definition at line 80 of file TELNET.H.

const char* telopts[NTELOPTS+1]

Initial value:

 {
        "BINARY", "ECHO", "RCP", "SUPPRESS GO AHEAD", "NAME",
        "STATUS", "TIMING MARK", "RCTE", "NAOL", "NAOP",
        "NAOCRD", "NAOHTS", "NAOHTD", "NAOFFD", "NAOVTS",
        "NAOVTD", "NAOLFD", "EXTEND ASCII", "LOGOUT", "BYTE MACRO",
        "DATA ENTRY TERMINAL", "SUPDUP", "SUPDUP OUTPUT",
        "SEND LOCATION", "TERMINAL TYPE", "END OF RECORD",
        "TACACS UID", "OUTPUT MARKING", "TTYLOC",
        "3270 REGIME", "X.3 PAD", "NAWS", "TSPEED", "LFLOW",
        "LINEMODE", "XDISPLOC", "OLD-ENVIRON", "AUTHENTICATION",
        "ENCRYPT", "NEW-ENVIRON", 0
      }
Definition at line 136 of file TELNET.H.

Generated on Wed Jan 25 15:42:40 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/arpa/TFTP.H File Reference

inc/arpa/TFTP.H File Reference

Detailed Description

TFTP definitions.

Definition in file TFTP.H.

Go to the source code of this file.

Data Structures

struct tftphdr

Generated on Wed Jan 25 15:42:43 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/net/BPF.H File Reference

inc/net/BPF.H File Reference

Detailed Description

Berkeley Packet Filter.

Definition in file BPF.H.

Go to the source code of this file.

Data Structures

struct | bpf_program
struct | bpf_stat
struct | bpf_version
struct | bpf_hdr
Berkeley Packet Filter header. More...
struct | bpf_insn

Typedefs

typedef long | bpf_int32
typedef u_int32_t | bpf_u_int32

Functions

u_int | bpf_filter (struct bpf_insn *, u_char *, u_int, u_int)

Generated on Wed Jan 25 15:42:40 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/net/BPFDESC.H File Reference

inc/net/BPFDESC.H File Reference

Detailed Description

Berkeley Packet Filter definitions.

Definition in file BPFDESC.H.

Go to the source code of this file.

Data Structures

struct | bpf_d
struct | bpf_if

Generated on Wed Jan 25 15:42:40 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/net/ETHERTYP.H File Reference

inc/net/ETHERTYP.H File Reference

Detailed Description

Ethernet protocol types.

Definition in file ETHERTYP.H.

Go to the source code of this file.

Generated on Wed Jan 25 15:42:40 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/net/IF.H File Reference

inc/net/IF.H File Reference

Detailed Description

Network interface data.

Definition in file IF.H.

Go to the source code of this file.

Data Structures

struct | proc
struct | socket
struct | if_data
struct | ifnet
struct | ifnet::ifqueue
struct | ifaddr
struct | if_msghdr
struct | ifa_msghdr
struct | ifreq
struct | ifaliasreq
struct | ifmediareq
struct | ifconf

Functions

TAILQ_HEAD (ifnet_head, ifnet)

Generated on Wed Jan 25 15:42:40 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/net/IF_ARC.H File Reference

inc/net/IF_ARC.H File Reference

Detailed Description

ARC-net definitions.

Definition in file IF_ARC.H.

Go to the source code of this file.

Data Structures

struct | arc_addr
struct | arc_header
struct | arccom
struct | arccom::ac_frag

Generated on Wed Jan 25 15:42:40 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/net/IF_ARP.H File Reference

inc/net/IF_ARP.H File Reference

Detailed Description

ARP definitions.

Definition in file IF_ARP.H.

Go to the source code of this file.

Data Structures

struct | arphdr
struct | arpreq

Generated on Wed Jan 25 15:42:40 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/net/IF_ATM.H File Reference

inc/net/IF_ATM.H File Reference

Detailed Description

ATM definitions.

Definition in file IF_ATM.H.

Go to the source code of this file.

Data Structures

struct | atm_pseudohdr
struct | atm_pseudoioctl
struct | atmllc

Generated on Wed Jan 25 15:42:40 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/net/IF_DL.H File Reference

inc/net/IF_DL.H File Reference

Detailed Description

Link-level sockaddr_dl definition.

Definition in file IF_DL.H.

Go to the source code of this file.

Data Structures

struct | sockaddr_dl

Functions

__BEGIN_DECLS W32_FUNC void | link_addr (const char *, struct sockaddr_dl *)
W32_FUNC char * | link_ntoa (const struct sockaddr_dl *)

Generated on Wed Jan 25 15:42:40 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/net/IF_FDDI.H File Reference

inc/net/IF_FDDI.H File Reference

Detailed Description

Compatability header.

Definition in file IF_FDDI.H.

Go to the source code of this file.

Generated on Wed Jan 25 15:42:40 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/net/IF_LLC.H File Reference

inc/net/IF_LLC.H File Reference

Detailed Description

IEEE 802.2 Link Level Control.

Definition in file IF_LLC.H.

Go to the source code of this file.

Data Structures

struct | llc
struct | frmrinfo

Generated on Wed Jan 25 15:42:40 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/net/IF_MEDIA.H File Reference

inc/net/IF_MEDIA.H File Reference

Detailed Description

Network interface media selection.

Definition in file IF_MEDIA.H.

Go to the source code of this file.

Data Structures

struct ifmedia_description

Generated on Wed Jan 25 15:42:40 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/net/IF_PACKE.H File Reference

inc/net/IF_PACKE.H File Reference

Detailed Description

Linux compatability header.

Definition in file IF_PACKE.H.

Go to the source code of this file.

Data Structures

struct | sockaddr_pkt
struct | sockaddr_ll
struct | tpacket_stats
struct | tpacket_hdr
struct | tpacket_req
struct | packet_mreq

Generated on Wed Jan 25 15:42:40 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/net/IF_PPP.H File Reference

inc/net/IF_PPP.H File Reference

Detailed Description

PPP definitions.

Definition in file IF_PPP.H.

Go to the source code of this file.

Data Structures

struct | npioctl
struct | ppp_option_data
struct | ifpppstatsreq
struct | ifpppcstatsreq

Generated on Wed Jan 25 15:42:40 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/net/IF_PPPVA.H File Reference

inc/net/IF_PPPVA.H File Reference

Detailed Description

PPP structures and declarations.

Definition in file IF_PPPVA.H.

Go to the source code of this file.

Data Structures

struct ppp_softc

Generated on Wed Jan 25 15:42:40 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/net/IF_SLVAR.H File Reference

inc/net/IF_SLVAR.H File Reference

Detailed Description

SLIP interface structures.

Definition in file IF_SLVAR.H.

Go to the source code of this file.

Data Structures

struct sl_softc

Generated on Wed Jan 25 15:42:40 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/net/IF_STRIP.H File Reference

inc/net/IF_STRIP.H File Reference

Detailed Description

SLIP interface structures.

Definition in file IF_STRIP.H.

Go to the source code of this file.

Data Structures

struct strip_softc

Generated on Wed Jan 25 15:42:40 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/net/IF_TUN.H File Reference

inc/net/IF_TUN.H File Reference

Detailed Description

Interface tunneling.

Definition in file IF_TUN.H.

Go to the source code of this file.

Data Structures

struct tun_softc

Generated on Wed Jan 25 15:42:40 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/net/IF_TYPES.H File Reference

inc/net/IF_TYPES.H File Reference

Detailed Description

Network interface types.

Definition in file IF_TYPES.H.

Go to the source code of this file.

Generated on Wed Jan 25 15:42:40 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/net/NETISR.H File Reference

inc/net/NETISR.H File Reference

Detailed Description

Definition in file NETISR.H.

Go to the source code of this file.

Variables

int netisr

Generated on Wed Jan 25 15:42:40 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/net/PFIL.H File Reference

inc/net/PFIL.H File Reference

Detailed Description

Definition in file PFIL.H.

Go to the source code of this file.

Generated on Wed Jan 25 15:42:40 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/net/PPP-COMP.H File Reference

inc/net/PPP-COMP.H File Reference

Detailed Description

PPP compression.

Definition in file PPP-COMP.H.

Go to the source code of this file.

Data Structures

struct compressor

Generated on Wed Jan 25 15:42:40 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/net/PPP_DEFS.H File Reference

inc/net/PPP_DEFS.H File Reference

Detailed Description

PPP definitions.

Definition in file PPP_DEFS.H.

Go to the source code of this file.

Data Structures

struct | pppstat
struct | vjstat
struct | ppp_stats
struct | compstat
struct | ppp_comp_stats
struct | ppp_idle

Typedefs

typedef UINT32_T | u_int32_t
typedef u_int32_t | ext_accm [8]

Enumerations

enum NPmode {
NPMODE_PASS,
NPMODE_DROP,
NPMODE_ERROR,
NPMODE_QUEUE
}

Generated on Wed Jan 25 15:42:40 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/net/RADIX.H File Reference

inc/net/RADIX.H File Reference

Detailed Description

Radix search trees.

Definition in file RADIX.H.

Go to the source code of this file.

Data Structures

struct | radix_node
struct | radix_mask
struct | radix_node_head

Functions

__BEGIN_DECLS void | rn_init (void)
int | rn_inithead (void **, int)
int | rn_refines (void *, void *)
int | rn_walktree (struct radix_node_head *, int(*)(struct radix_node *, void *), void *)
radix_node * | rn_addroute (void *, void *, struct radix_node_head *, struct radix_node[2])
radix_node * | rn_insert (void *, struct radix_node_head *, int *, struct radix_node[2])
radix_node * | rn_newpair (void *, int, struct radix_node[2])
radix_node * | rn_addmask (void *, int, int)
radix_node * | rn_delete (void *, void *, struct radix_node_head *)
radix_node * | rn_lookup (void *, void *, struct radix_node_head *)
radix_node * | rn_match (void *, struct radix_node_head *)
radix_node * | rn_search (void *, struct radix_node *)
radix_node * | rn_search_m (void *, struct radix_node *, void *)

Variables

radix_mask * | rn_mkfreelist

Generated on Wed Jan 25 15:42:40 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/net/RAW_CB.H File Reference

inc/net/RAW_CB.H File Reference

Detailed Description

Definition in file RAW_CB.H.

Go to the source code of this file.

Data Structures

struct rawcb

Generated on Wed Jan 25 15:42:40 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/net/ROUTE.H File Reference

inc/net/ROUTE.H File Reference

Detailed Description

Route handling.

Definition in file ROUTE.H.

Go to the source code of this file.

Data Structures

struct | route
struct | rt_metrics
struct | rtentry
struct | ortentry
struct | rtstat
struct | rt_msghdr
struct | rt_addrinfo
struct | route_cb

Generated on Wed Jan 25 15:42:40 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/net/SLCOMPRE.H File Reference

inc/net/SLCOMPRE.H File Reference

Detailed Description

SLIP/PPP compression.

Definition in file SLCOMPRE.H.

Go to the source code of this file.

Data Structures

struct | cstate
struct | slcompress

Functions

void | sl_compress_init (struct slcompress *)
void | sl_compress_setup (struct slcompress *, int)
u_int | sl_compress_tcp (struct mbuf *, struct ip *, struct slcompress *, int)
int | sl_uncompress_tcp (u_char **, int, u_int, struct slcompress *)
int | sl_uncompress_tcp_core (u_char *, int, int, u_int, struct slcompress *, u_char **, u_int *)

Generated on Wed Jan 25 15:42:40 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/net/SLIP.H File Reference

inc/net/SLIP.H File Reference

Detailed Description

BPF SLIP definitions.

Definition in file SLIP.H.

Go to the source code of this file.

Generated on Wed Jan 25 15:42:40 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/netinet/ICMP6.H File Reference

inc/netinet/ICMP6.H File Reference

Detailed Description

ICMP for IPv6.

Definition in file ICMP6.H.

Go to the source code of this file.

Data Structures

struct | icmp6_hdr
struct | mld_hdr
struct | nd_router_solicit
struct | nd_router_advert
struct | nd_neighbor_solicit
struct | nd_neighbor_advert
struct | nd_redirect
struct | nd_opt_hdr
struct | nd_opt_prefix_info
struct | nd_opt_rd_hdr
struct | nd_opt_mtu
struct | nd_opt_route_info
struct | icmp6_namelookup
struct | icmp6_nodeinfo
struct | ni_reply_fqdn
struct | icmp6_router_renum
struct | rr_pco_match
struct | rr_pco_use
struct | rr_result
struct | icmp6_filter
struct | icmp6errstat
struct | icmp6stat

Functions

void | icmp6_init (void)
void | icmp6_paramerror (struct mbuf *, int)
void | icmp6_error (struct mbuf *, int, int, int)
int | icmp6_input (struct mbuf **, int *, int)
void | icmp6_fasttimo (void)
void | icmp6_reflect (struct mbuf *, size_t)
void | icmp6_prepare (struct mbuf *)
void | icmp6_redirect_input (struct mbuf *, int)
void | icmp6_redirect_output (struct mbuf *, struct rtentry *)
void | icmp6_mtudisc_update (struct ip6ctlparam *, int)

Variables

int | icmp6_rediraccept
int | icmp6_redirtimeout

Generated on Wed Jan 25 15:42:40 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/netinet/ICMP_VAR.H File Reference

inc/netinet/ICMP_VAR.H File Reference

Detailed Description

Internal ICMP statistics.

Definition in file ICMP_VAR.H.

Go to the source code of this file.

Data Structures

struct icmpstat

Generated on Wed Jan 25 15:42:40 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/netinet/IF_ETHER.H File Reference

inc/netinet/IF_ETHER.H File Reference

Detailed Description

Ethernet definitions.

Definition in file IF_ETHER.H.

Go to the source code of this file.

Data Structures

struct | ether_addr
struct | ether_header
struct | ether_arp
struct | arpcom
struct | arptab
struct | ether_multi
struct | ether_multistep

Variables

u_char | etherbroadcastaddr [6]
u_char | ether_ipmulticast_min [6]
u_char | ether_ipmulticast_max [6]

Generated on Wed Jan 25 15:42:40 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/netinet/IF_FDDI.H File Reference

inc/netinet/IF_FDDI.H File Reference

Detailed Description

FDDI header definition.

Definition in file IF_FDDI.H.

Go to the source code of this file.

Data Structures

struct fddi_header

Generated on Wed Jan 25 15:42:40 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/netinet/IGMP.H File Reference

inc/netinet/IGMP.H File Reference

Detailed Description

Internet Group Managment Protocol.

Definition in file IGMP.H.

Go to the source code of this file.

Data Structures

struct igmp

Generated on Wed Jan 25 15:42:40 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/netinet/IGMP_VAR.H File Reference

inc/netinet/IGMP_VAR.H File Reference

Detailed Description

Internal IGMP statistics.

Definition in file IGMP_VAR.H.

Go to the source code of this file.

Data Structures

struct igmpstat

Generated on Wed Jan 25 15:42:40 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/netinet/IN.H File Reference

inc/netinet/IN.H File Reference

Detailed Description

IP address, options and definitions.

Definition in file IN.H.

Go to the source code of this file.

Data Structures

struct | in_addr
struct | in6_addr
struct | sockaddr_in
struct | sockaddr_in6
struct | sockaddr_storage
struct | ipv6_mreq
struct | ip_opts
struct | ip_mreq

Variables

W32_DATA const struct in6_addr | in6addr_any
W32_DATA const struct in6_addr | in6addr_loopback

Generated on Wed Jan 25 15:42:40 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/netinet/IN_PCB.H File Reference

inc/netinet/IN_PCB.H File Reference

Detailed Description

Internal IP structures.

Definition in file IN_PCB.H.

Go to the source code of this file.

Data Structures

struct | inpcb
struct | inpcbinfo

Functions

LIST_HEAD (inpcbhead, inpcb)

Generated on Wed Jan 25 15:42:40 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/netinet/IN_SYSTM.H File Reference

inc/netinet/IN_SYSTM.H File Reference

Detailed Description

Various typedefs.

Definition in file IN_SYSTM.H.

Go to the source code of this file.

Typedefs

typedef u_short | n_short
typedef u_long | n_long
typedef u_long | n_time

Generated on Wed Jan 25 15:42:40 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/netinet/IN_VAR.H File Reference

inc/netinet/IN_VAR.H File Reference

Detailed Description

IP interface address.

Definition in file IN_VAR.H.

Go to the source code of this file.

Data Structures

struct | in_ifaddr
struct | in_aliasreq
struct | router_info
struct | in_multi

Generated on Wed Jan 25 15:42:40 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/netinet/IP.H File Reference

inc/netinet/IP.H File Reference

Detailed Description

IPv4 header and options.

Definition in file IP.H.

Go to the source code of this file.

Data Structures

struct | ip
struct | ip_timestamp
union | ip_timestamp::ipt_timestamp
struct | ip_timestamp::ipt_timestamp::ipt_ta

Generated on Wed Jan 25 15:42:40 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/netinet/IP6.H File Reference

inc/netinet/IP6.H File Reference

Detailed Description

IPv6 definitions.

Definition in file IP6.H.

Go to the source code of this file.

Data Structures

struct | ip6_hdr
struct | ip6_ext
struct | ip6_hbh
struct | ip6_dest
struct | ip6_rthdr
struct | ip6_rthdr0
struct | ip6_frag

Generated on Wed Jan 25 15:42:40 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/netinet/IP_FW.H File Reference

inc/netinet/IP_FW.H File Reference

Detailed Description

IP firewall definitions.

Definition in file IP_FW.H.

Go to the source code of this file.

Data Structures

struct | ip_fw
struct | ip_fw_chain

Generated on Wed Jan 25 15:42:40 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/netinet/IP_ICMP.H File Reference

inc/netinet/IP_ICMP.H File Reference

Detailed Description

ICMP definitions.

Definition in file IP_ICMP.H.

Go to the source code of this file.

Data Structures

struct | icmp_ra_addr
struct | icmp

Generated on Wed Jan 25 15:42:40 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/netinet/IP_MROUT.H File Reference

inc/netinet/IP_MROUT.H File Reference

Detailed Description

IP multicast forwarding.

Definition in file IP_MROUT.H.

Go to the source code of this file.

Data Structures

struct | vifctl
struct | mfcctl
struct | mrtstat
struct | sioc_sg_req
struct | sioc_vif_req
struct | vif
struct | mfc
struct | igmpmsg
struct | rtdetq
struct | tbf

Typedefs

typedef u_long | vifbitmap_t
typedef u_short | vifi_t

Generated on Wed Jan 25 15:42:40 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/netinet/IP_VAR.H File Reference

inc/netinet/IP_VAR.H File Reference

Detailed Description

Internal IP definitions and statistics.

Definition in file IP_VAR.H.

Go to the source code of this file.

Data Structures

struct | ipovly
struct | ipasfrag
struct | ipq
struct | ipoption
struct | ip_moptions
struct | ipstat

Generated on Wed Jan 25 15:42:40 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/netinet/IPV6.H File Reference

inc/netinet/IPV6.H File Reference

Detailed Description

Linux IPv6 definitions.

Definition in file IPV6.H.

Go to the source code of this file.

Data Structures

struct | ipv6hdr
struct | ipv6_options
struct | in6_pktinfo
struct | in6_ifreq
struct | ipv6_rt_hdr
struct | ipv6_rt0_hdr
struct | ipv6_fraghdr

Generated on Wed Jan 25 15:42:40 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/netinet/TCP.H File Reference

inc/netinet/TCP.H File Reference

Detailed Description

TCP header and options.

Definition in file TCP.H.

Go to the source code of this file.

Data Structures

struct | tcphdr

Typedefs

typedef u_long | tcp_seq
typedef u_long | tcp_cc

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/netinet/TCP_DEBU.H File Reference

inc/netinet/TCP_DEBU.H File Reference

Detailed Description

TCP debugging.

Definition in file TCP_DEBU.H.

Go to the source code of this file.

Data Structures

struct | tcp_debug
struct | tad_entry

Variables

char * | tanames []
tad_entry | tad_table [TAD_ENTRIES]
tad_entry * | tad_index
u_long | tad_seq
u_long | tad_debug

Variable Documentation

char* tanames[] [static]

Initial value:

 {
            "input", "output", "user", "respond", "drop"
          }
Definition at line 61 of file TCP_DEBU.H.

Generated on Wed Jan 25 15:42:40 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/netinet/TCP_FSM.H File Reference

inc/netinet/TCP_FSM.H File Reference

Detailed Description

TCP Finite State Machine.

Definition in file TCP_FSM.H.

Go to the source code of this file.

Variables

u_char | tcp_outflags [TCP_NSTATES]
int | tcp_acounts [TCP_NSTATES][PRU_NREQ]
char * | tcpstates []

Variable Documentation

u_char tcp_outflags[TCP_NSTATES] [static]

Initial value:

 {
    TH_RST|TH_ACK, 0, TH_SYN, TH_SYN|TH_ACK,
    TH_ACK, TH_ACK,
    TH_FIN|TH_ACK, TH_FIN|TH_ACK, TH_FIN|TH_ACK, TH_ACK, TH_ACK,
}
Definition at line 77 of file TCP_FSM.H.

char* tcpstates[]

Initial value:

 {
        "CLOSED",       "LISTEN",       "SYN_SENT",     "SYN_RCVD",
        "ESTABLISHED",  "CLOSE_WAIT",   "FIN_WAIT_1",   "CLOSING",
        "LAST_ACK",     "FIN_WAIT_2",   "TIME_WAIT",
}
Definition at line 89 of file TCP_FSM.H.

Generated on Wed Jan 25 15:42:40 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/netinet/TCP_SCOR.H File Reference

inc/netinet/TCP_SCOR.H File Reference

Detailed Description

TCP scoreboard definitions (SACK).

Definition in file TCP_SCOR.H.

Go to the source code of this file.

Data Structures

struct | scrb_entry
struct | scoreboard

Generated on Wed Jan 25 15:42:40 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/netinet/TCP_SEQ.H File Reference

inc/netinet/TCP_SEQ.H File Reference

Detailed Description

TCP serquence number handling.

Definition in file TCP_SEQ.H.

Go to the source code of this file.

Variables

tcp_seq tcp_iss

Generated on Wed Jan 25 15:42:40 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/netinet/TCP_TIME.H File Reference

inc/netinet/TCP_TIME.H File Reference

Detailed Description

TCP timer definitions.

Definition in file TCP_TIME.H.

Go to the source code of this file.

Variables

char * tcptimers []

Variable Documentation

char* tcptimers[] [static]

Initial value:

    { "REXMT", "PERSIST", "KEEP", "2MSL" }
Definition at line 118 of file TCP_TIME.H.

Generated on Wed Jan 25 15:42:40 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/netinet/TCP_VAR.H File Reference

inc/netinet/TCP_VAR.H File Reference

Detailed Description

Internal TCP structures and statistics.

Definition in file TCP_VAR.H.

Go to the source code of this file.

Data Structures

struct | sackblock
struct | tcpcb
struct | tcpopt
struct | rmxp_tao
struct | tcpstat

Generated on Wed Jan 25 15:42:40 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/netinet/TCPIP.H File Reference

inc/netinet/TCPIP.H File Reference

Detailed Description

TCP header definitions.

Definition in file TCPIP.H.

Go to the source code of this file.

Data Structures

struct | tcpiphdr
struct | full_tcpiphdr

Generated on Wed Jan 25 15:42:40 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/netinet/UDP.H File Reference

inc/netinet/UDP.H File Reference

Detailed Description

UDP header.

Definition in file UDP.H.

Go to the source code of this file.

Data Structures

struct udphdr

Generated on Wed Jan 25 15:42:40 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/netinet/UDP_VAR.H File Reference

inc/netinet/UDP_VAR.H File Reference

Detailed Description

Internal UDP statistics.

Definition in file UDP_VAR.H.

Go to the source code of this file.

Data Structures

struct | udpiphdr
struct | udpstat

Generated on Wed Jan 25 15:42:40 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/netinet6/AH.H File Reference

inc/netinet6/AH.H File Reference

Detailed Description

Authentication Header.

Definition in file AH.H.

Go to the source code of this file.

Data Structures

struct | ah
struct | newah
struct | ah_algorithm_state
struct | ah_algorithm

Functions

const struct ah_algorithm
*ah_algorithm_lookup 		__P ((int))
int ah_hdrlen | __P ((struct secasvar *))
size_t ah_hdrsiz | __P ((struct ipsecrequest *))
void ah4_input | __P ((struct mbuf *, int))
int ah4_output | __P ((struct mbuf *, struct ipsecrequest *))
int ah4_calccksum | __P ((struct mbuf *, caddr_t, size_t, const struct ah_algorithm *, struct secasvar *))

Generated on Wed Jan 25 15:42:40 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/netinet6/AH6.H File Reference

inc/netinet6/AH6.H File Reference

Detailed Description

IPv6 Authentication header.

Definition in file AH6.H.

Go to the source code of this file.

Functions

int | ah6_input (struct mbuf **, int *, int))
int | ah6_output (struct mbuf *, u_char *, struct mbuf *, struct ipsecrequest *)
int | ah6_calccksum (struct mbuf *, caddr_t, size_t, const struct ah_algorithm *, struct secasvar *)
void | ah6_ctlinput (int, struct sockaddr *, void *)

Generated on Wed Jan 25 15:42:40 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/netinet6/ESP.H File Reference

inc/netinet6/ESP.H File Reference

Detailed Description

Definition in file ESP.H.

Go to the source code of this file.

Data Structures

struct | esp
struct | newesp
struct | esptail
struct | esp_algorithm

Functions

const struct esp_algorithm * | esp_algorithm_lookup (int)
int | esp_max_ivlen (void)
int | esp4_output (struct mbuf *, struct ipsecrequest *)
void | esp4_input (struct mbuf *, int)
size_t | esp_hdrsiz (struct ipsecrequest *)
int | esp_schedule (const struct esp_algorithm *, struct secasvar *)
int | esp_auth (struct mbuf *, size_t, size_t, struct secasvar *, u_char *)

Generated on Wed Jan 25 15:42:40 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/netinet6/ESP6.H File Reference

inc/netinet6/ESP6.H File Reference

Detailed Description

Definition in file ESP6.H.

Go to the source code of this file.

Functions

int esp6_output | __P ((struct mbuf *, u_char *, struct mbuf *, struct ipsecrequest *))
int esp6_input | __P ((struct mbuf **, int *, int))
void esp6_ctlinput | __P ((int, struct sockaddr *, void *))

Generated on Wed Jan 25 15:42:40 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/netinet6/ESP_RIJN.H File Reference

inc/netinet6/ESP_RIJN.H File Reference

Detailed Description

Definition in file ESP_RIJN.H.

Go to the source code of this file.

Functions

int esp_rijndael_schedlen | __P ((const struct esp_algorithm *))
int esp_rijndael_schedule | __P ((const struct esp_algorithm *, struct secasvar *))
int esp_rijndael_blockdecrypt | __P ((const struct esp_algorithm *, struct secasvar *, u_int8_t *, u_int8_t *))

Generated on Wed Jan 25 15:42:40 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/netinet6/IN6.H File Reference

inc/netinet6/IN6.H File Reference

Detailed Description

Definition in file IN6.H.

Go to the source code of this file.

Data Structures

struct | in6_addr
struct | sockaddr_in6
struct | route_in6
struct | ipv6_mreq
struct | in6_pktinfo

Typedefs

typedef _BSD_SIZE_T_ | size_t

Functions

int in6_cksum | __P ((struct mbuf *, u_int8_t, u_int32_t, u_int32_t))
int in6_localaddr | __P ((struct in6_addr *))
in6_ifaddr *in6_ifawithscope | __P ((struct ifnet *, struct in6_addr *))
void in6_if_up | __P ((struct ifnet *))
void in6_sin6_2_sin | __P ((struct sockaddr_in *sin, struct sockaddr_in6 *sin6))
void in6_sin6_2_sin_in_sock | __P ((struct sockaddr *nam))
void in6_sin_2_v4mapsin6_in_sock | __P ((struct sockaddr **nam))
int inet6_option_space | __P ((int))
int inet6_option_init | __P ((void *, struct cmsghdr **, int))
int inet6_option_append | __P ((struct cmsghdr *, const uint8_t *, int, int))
uint8_t *inet6_option_alloc | __P ((struct cmsghdr *, int, int, int))
int inet6_option_next | __P ((const struct cmsghdr *, uint8_t **))
int inet6_option_find | __P ((const struct cmsghdr *, uint8_t **, int))
size_t inet6_rthdr_space | __P ((int, int))
cmsghdr *inet6_rthdr_init | __P ((void *, int))
int inet6_rthdr_add | __P ((struct cmsghdr *, const struct in6_addr *, unsigned int))
int inet6_rthdr_lasthop | __P ((struct cmsghdr *, unsigned int))
int inet6_rthdr_reverse | __P ((const struct cmsghdr *, struct cmsghdr *))
int inet6_rthdr_segments | __P ((const struct cmsghdr *))
in6_addr *inet6_rthdr_getaddr | __P ((struct cmsghdr *, int))
int inet6_rthdr_getflags | __P ((const struct cmsghdr *, int))
int inet6_opt_init | __P ((void *, size_t))
int inet6_opt_append | __P ((void *, size_t, int, uint8_t, size_t, uint8_t, void **))
int inet6_opt_finish | __P ((void *, size_t, int))
int inet6_opt_set_val | __P ((void *, size_t, void *, int))
int inet6_opt_next | __P ((void *, size_t, int, uint8_t *, size_t *, void **))
int inet6_opt_find | __P ((void *, size_t, int, uint8_t, size_t *, void **))
void *inet6_rth_init | __P ((void *, int, int, int))
int inet6_rth_add | __P ((void *, const struct in6_addr *))
int inet6_rth_reverse | __P ((const void *, void *))
int inet6_rth_segments | __P ((const void *))
in6_addr *inet6_rth_getaddr | __P ((const void *, int))

Variables

const struct sockaddr_in6 | sa6_any
const struct in6_addr | in6mask0
const struct in6_addr | in6mask32
const struct in6_addr | in6mask64
const struct in6_addr | in6mask96
const struct in6_addr | in6mask128
const struct in6_addr | in6addr_any
const struct in6_addr | in6addr_loopback
const struct in6_addr | in6addr_nodelocal_allnodes
const struct in6_addr | in6addr_linklocal_allnodes
const struct in6_addr | in6addr_linklocal_allrouters
u_char | ip6_protox []
int(* | faithprefix_p )(struct in6_addr *)

Generated on Wed Jan 25 15:42:40 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/netinet6/IN6_GIF.H File Reference

inc/netinet6/IN6_GIF.H File Reference

Detailed Description

Definition in file IN6_GIF.H.

Go to the source code of this file.

Functions

int in6_gif_input | __P ((struct mbuf **, int *, int))
int in6_gif_output | __P ((struct ifnet *, int, struct mbuf *, struct rtentry *))
int gif_encapcheck6 | __P ((const struct mbuf *, int, int, void *))

Generated on Wed Jan 25 15:42:40 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/netinet6/IN6_IFAT.H File Reference

inc/netinet6/IN6_IFAT.H File Reference

Detailed Description

Definition in file IN6_IFAT.H.

Go to the source code of this file.

Functions

void in6_nigroup_attach | __P ((const char *, int))
void in6_ifattach | __P ((struct ifnet *, struct ifnet *))
void in6_ifdetach | __P ((struct ifnet *))
void in6_get_tmpifid | __P ((struct ifnet *, u_int8_t *, const u_int8_t *, int))
void in6_tmpaddrtimer | __P ((void *))
int in6_nigroup | __P ((struct ifnet *, const char *, int, struct in6_addr *))

Generated on Wed Jan 25 15:42:40 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/netinet6/IN6_PCB.H File Reference

inc/netinet6/IN6_PCB.H File Reference

Detailed Description

Definition in file IN6_PCB.H.

Go to the source code of this file.

Functions

void in6_pcbpurgeif0 | __P ((struct in6pcb *, struct ifnet *))
void in6_losing | __P ((struct inpcb *))
int in6_pcballoc | __P ((struct socket *, struct inpcbinfo *, struct thread *))
int in6_pcbbind | __P ((struct inpcb *, struct sockaddr *, struct thread *))
int in6_pcbladdr | __P ((struct inpcb *, struct sockaddr *, struct in6_addr **))
inpcb *in6_pcblookup_local | __P ((struct inpcbinfo *, struct in6_addr *, u_int, int))
inpcb *in6_pcblookup_hash | __P ((struct inpcbinfo *, struct in6_addr *, u_int, struct in6_addr *, u_int, int, struct ifnet *))
void in6_pcbnotify | __P ((struct inpcbhead *, struct sockaddr *, u_int, const struct sockaddr *, u_int, int, struct inpcb *(*)(struct inpcb *, int)))
inpcb *in6_rtchange | __P ((struct inpcb *, int))
int in6_setpeeraddr | __P ((struct socket *so, struct sockaddr **nam))
in6_addr *in6_selectsrc | __P ((struct sockaddr_in6 *, struct ip6_pktopts *, struct ip6_moptions *, struct route_in6 *, struct in6_addr *, int *))
int in6_pcbsetport | __P ((struct in6_addr *, struct inpcb *, struct thread *))
void init_sin6 | __P ((struct sockaddr_in6 *sin6, struct mbuf *m))

Generated on Wed Jan 25 15:42:40 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/netinet6/IN6_PREF.H File Reference

inc/netinet6/IN6_PREF.H File Reference

Detailed Description

Definition in file IN6_PREF.H.

Go to the source code of this file.

Data Structures

struct | rr_prefix
struct | rr_prefix::rp_stateflags
struct | rp_addr
struct | rp_addr::ra_flags

Functions

LIST_HEAD (rr_prhead, rr_prefix)
void in6_rr_timer | __P ((void *))
int delete_each_prefix | __P ((struct rr_prefix *rpp, u_char origin))

Variables

rr_prhead | rr_prefix
callout | in6_rr_timer_ch

Generated on Wed Jan 25 15:42:40 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/netinet6/IN6_VAR.H File Reference

inc/netinet6/IN6_VAR.H File Reference

Detailed Description

Definition in file IN6_VAR.H.

Go to the source code of this file.

Data Structures

struct | in6_addrlifetime
struct | in6_ifaddr
struct | in6_ifstat
struct | icmp6_ifstat
struct | in6_ifreq
struct | in6_aliasreq
struct | in6_prflags
struct | in6_prflags::prf_ra
struct | in6_prflags::prf_rr
struct | in6_prefixreq
struct | in6_rrenumreq
struct | in6_rrenumreq::irr_raflagmask
struct | in6_multi_mship
struct | in6_multi
struct | in6_multistep

Functions

MALLOC_DECLARE (M_IPMADDR)
LIST_HEAD (in6_multihead, in6_multi) in6_multihead
in6_multi *in6_addmulti | __P ((struct in6_addr *, struct ifnet *, int *))
void in6_delmulti | __P ((struct in6_multi *))
int in6_ifindex2scopeid | __P ((int))
int in6_mask2len | __P ((struct in6_addr *, u_char *))
void in6_len2mask | __P ((struct in6_addr *, int))
int in6_control | __P ((struct socket *, u_long, caddr_t, struct ifnet *, struct thread *))
int in6_update_ifa | __P ((struct ifnet *, struct in6_aliasreq *, struct in6_ifaddr *))
void in6_purgeaddr | __P ((struct ifaddr *))
int in6if_do_dad | __P ((struct ifnet *))
void in6_savemkludge | __P ((struct in6_ifaddr *))
void in6_setmaxmtu | __P ((void))
void in6_restoremkludge | __P ((struct in6_ifaddr *, struct ifnet *))
in6_ifaddr *in6ifa_ifpforlinklocal | __P ((struct ifnet *, int))
in6_ifaddr *in6ifa_ifpwithaddr | __P ((struct ifnet *, struct in6_addr *))
char *ip6_sprintf | __P ((const struct in6_addr *))
int in6_matchlen | __P ((struct in6_addr *, struct in6_addr *))
int in6_are_prefix_equal | __P ((struct in6_addr *p1, struct in6_addr *p2, int len))
void in6_prefixlen2mask | __P ((struct in6_addr *maskp, int len))
int in6_prefix_ioctl | __P ((struct socket *so, u_long cmd, caddr_t data, struct ifnet *ifp))
int in6_prefix_add_ifid | __P ((int iilen, struct in6_ifaddr *ia))
int in6_is_addr_deprecated | __P ((struct sockaddr_in6 *))
int in6_embedscope | __P ((struct in6_addr *, const struct sockaddr_in6 *, struct inpcb *, struct ifnet **))
int in6_recoverscope | __P ((struct sockaddr_in6 *, const struct in6_addr *, struct ifnet *))
void in6_clearscope | __P ((struct in6_addr *))

Variables

in6_ifaddr * | in6_ifaddr
in6_ifstat ** | in6_ifstat
size_t | in6_ifstatmax
icmp6stat | icmp6stat
icmp6_ifstat ** | icmp6_ifstat
size_t | icmp6_ifstatmax
ifqueue | ip6intrq
in6_addr | zeroin6_addr
u_char | inet6ctlerrmap []
unsigned long | in6_maxmtu

Generated on Wed Jan 25 15:42:40 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/netinet6/IP6_ECN.H File Reference

inc/netinet6/IP6_ECN.H File Reference

Detailed Description

Definition in file IP6_ECN.H.

Go to the source code of this file.

Functions

void ip6_ecn_ingress __P ((int, u_int32_t *, const u_int32_t *))

Generated on Wed Jan 25 15:42:40 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/netinet6/IP6_FW.H File Reference

inc/netinet6/IP6_FW.H File Reference

Detailed Description

Definition in file IP6_FW.H.

Go to the source code of this file.

Data Structures

union | ip6_fw_if
struct | ip6_fw
struct | ip6_fw_chain

Typedefs

typedef int ip6_fw_chk_t | __P ((struct ip6_hdr **, struct ifnet *, u_short *, struct mbuf **))

Functions

void | ip6_fw_init (void)

Variables

ip6_fw_chk_t * | ip6_fw_chk_ptr
ip6_fw_ctl_t * | ip6_fw_ctl_ptr
int | ip6_fw_enable

Generated on Wed Jan 25 15:42:40 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/netinet6/IP6_MROU.H File Reference

inc/netinet6/IP6_MROU.H File Reference

Detailed Description

Definition in file IP6_MROU.H.

Go to the source code of this file.

Data Structures

struct | if_set
struct | mif6ctl
struct | mf6cctl
struct | mrt6stat
struct | omrt6msg
struct | mrt6msg
struct | sioc_sg_req6
struct | sioc_mif_req6
struct | mif6
struct | mf6c
struct | rtdetq

Typedefs

typedef u_short | mifi_t
typedef u_int32_t | if_mask
typedef if_set | if_set

Functions

int ip6_mrouter_set | __P ((struct socket *so, struct sockopt *sopt))
int ip6_mrouter_done | __P ((void))
int mrt6_ioctl | __P ((int, caddr_t))

Generated on Wed Jan 25 15:42:40 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/netinet6/IP6_VAR.H File Reference

inc/netinet6/IP6_VAR.H File Reference

Detailed Description

Definition in file IP6_VAR.H.

Go to the source code of this file.

Data Structures

struct | ip6q
struct | ip6asfrag
struct | ip6_moptions
struct | route_in6
struct | ip6po_rhinfo
struct | ip6_pktopts
struct | ip6stat
struct | ip6aux

Functions

int icmp6_ctloutput | __P ((struct socket *, struct sockopt *sopt))
void ip6_init | __P ((void))
void ip6_input | __P ((struct mbuf *))
void ip6_freepcbopts | __P ((struct ip6_pktopts *))
void ip6_freemoptions | __P ((struct ip6_moptions *))
int ip6_unknown_opt | __P ((u_int8_t *, struct mbuf *, int))
char *ip6_get_prevhdr | __P ((struct mbuf *, int))
int ip6_nexthdr | __P ((struct mbuf *, int, int, int *))
int ip6_mforward | __P ((struct ip6_hdr *, struct ifnet *, struct mbuf *))
int ip6_process_hopopts | __P ((struct mbuf *, u_int8_t *, int, u_int32_t *, u_int32_t *))
void ip6_savecontrol | __P ((struct inpcb *, struct mbuf **, struct ip6_hdr *, struct mbuf *))
void ip6_notify_pmtu | __P ((struct inpcb *, struct sockaddr_in6 *, u_int32_t *))
int ip6_sysctl | __P ((int *, u_int, void *, size_t *, void *, size_t))
void ip6_mloopback | __P ((struct ifnet *, struct mbuf *, struct sockaddr_in6 *))
int ip6_output | __P ((struct mbuf *, struct ip6_pktopts *, struct route_in6 *, int, struct ip6_moptions *, struct ifnet **))
int ip6_setpktoptions | __P ((struct mbuf *, struct ip6_pktopts *, int, int))
void ip6_clearpktopts | __P ((struct ip6_pktopts *, int, int))
ip6_pktopts *ip6_copypktopts | __P ((struct ip6_pktopts *, int))
int ip6_optlen | __P ((struct inpcb *))
int route6_input | __P ((struct mbuf **, int *, int))
int rip6_input | __P ((struct mbuf **mp, int *offp, int proto))
void rip6_ctlinput | __P ((int, struct sockaddr *, void *))
int rip6_ctloutput | __P ((struct socket *so, struct sockopt *sopt))
int rip6_output | __P ((struct mbuf *,...))
int rip6_usrreq | __P ((struct socket *, int, struct mbuf *, struct mbuf *, struct mbuf *, struct thread *))

Variables

ip6stat | ip6stat
u_int32_t | ip6_id
int | ip6_defhlim
int | ip6_defmcasthlim
int | ip6_forwarding
int | ip6_forward_srcrt
int | ip6_gif_hlim
int | ip6_use_deprecated
int | ip6_rr_prune
int | ip6_v6only
socket * | ip6_mrouter
int | ip6_sendredirects
int | ip6_maxfragpackets
int | ip6_sourcecheck
int | ip6_sourcecheck_interval
int | ip6_accept_rtadv
int | ip6_keepfaith
int | ip6_log_interval
time_t | ip6_log_time
int | ip6_hdrnestlimit
int | ip6_dad_count
u_int32_t | ip6_flow_seq
int | ip6_auto_flowlabel
int | ip6_auto_linklocal
int | ip6_anonportmin
int | ip6_anonportmax
int | ip6_lowportmin
int | ip6_lowportmax
int | ip6_use_tempaddr
pr_usrreqs | rip6_usrreqs

Generated on Wed Jan 25 15:42:40 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/netinet6/IP6PROTO.H File Reference

inc/netinet6/IP6PROTO.H File Reference

Detailed Description

Definition in file IP6PROTO.H.

Go to the source code of this file.

Data Structures

struct | ip6ctlparam
struct | ip6protosw

Variables

ip6protosw | inet6sw []

Generated on Wed Jan 25 15:42:40 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/netinet6/IPCOMP.H File Reference

inc/netinet6/IPCOMP.H File Reference

Detailed Description

Definition in file IPCOMP.H.

Go to the source code of this file.

Data Structures

struct | ipcomp
struct | ipcomp_algorithm

Functions

const struct ipcomp_algorithm
*ipcomp_algorithm_lookup 		__P ((int))
void ipcomp4_input | __P ((struct mbuf *, int))
int ipcomp4_output | __P ((struct mbuf *, struct ipsecrequest *))

Generated on Wed Jan 25 15:42:40 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/netinet6/IPCOMP6.H File Reference

inc/netinet6/IPCOMP6.H File Reference

Detailed Description

Definition in file IPCOMP6.H.

Go to the source code of this file.

Functions

int ipcomp6_input | __P ((struct mbuf **, int *, int))
int ipcomp6_output | __P ((struct mbuf *, u_char *, struct mbuf *, struct ipsecrequest *))

Generated on Wed Jan 25 15:42:40 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/netinet6/IPSEC.H File Reference

inc/netinet6/IPSEC.H File Reference

Detailed Description

Definition in file IPSEC.H.

Go to the source code of this file.

Data Structures

struct | secpolicyindex
struct | secpolicy
struct | ipsecrequest
struct | inpcbpolicy
struct | secspacq
struct | ipsecstat
struct | ipsec_output_state
struct | ipsec_history

Functions

secpolicy *ipsec4_getpolicybysock | __P ((struct mbuf *, u_int, struct socket *, int *))
secpolicy *ipsec4_getpolicybyaddr | __P ((struct mbuf *, u_int, int, int *))
int ipsec_init_policy | __P ((struct socket *so, struct inpcbpolicy **))
int ipsec_copy_policy | __P ((struct inpcbpolicy *, struct inpcbpolicy *))
u_int ipsec_get_reqlevel | __P ((struct ipsecrequest *))
int ipsec4_set_policy | __P ((struct inpcb *inp, int optname, caddr_t request, size_t len, int priv))
int ipsec4_get_policy | __P ((struct inpcb *inpcb, caddr_t request, size_t len, struct mbuf **mp))
int ipsec4_delete_pcbpolicy | __P ((struct inpcb *))
int ipsec4_in_reject_so | __P ((struct mbuf *, struct socket *))
int ipsec4_in_reject | __P ((struct mbuf *, struct inpcb *))
int ipsec_chkreplay | __P ((u_int32_t, struct secasvar *))
size_t ipsec4_hdrsiz | __P ((struct mbuf *, u_int, struct inpcb *))
size_t ipsec_hdrsiz_tcp | __P ((struct tcpcb *))
const char *ipsec4_logpacketstr | __P ((struct ip *, u_int32_t))
const char *ipsec_logsastr | __P ((struct secasvar *))
void ipsec_dumpmbuf | __P ((struct mbuf *))
int ipsec4_output | __P ((struct ipsec_output_state *, struct secpolicy *, int))
int ipsec4_tunnel_validate | __P ((struct mbuf *, int, u_int, struct secasvar *))
int ipsec_addhist | __P ((struct mbuf *, int, u_int32_t))
ipsec_history *ipsec_gethist | __P ((struct mbuf *, int *))
caddr_t ipsec_set_policy | __P ((char *, int))
int ipsec_get_policylen | __P ((caddr_t))
char *ipsec_dump_policy | __P ((caddr_t, char *))
const char *ipsec_strerror | __P ((void))

Variables

int | ipsec_debug
ipsecstat | ipsecstat
secpolicy | ip4_def_policy
int | ip4_esp_trans_deflev
int | ip4_esp_net_deflev
int | ip4_ah_trans_deflev
int | ip4_ah_net_deflev
int | ip4_ah_cleartos
int | ip4_ah_offsetmask
int | ip4_ipsec_dfbit
int | ip4_ipsec_ecn
int | ip4_esp_randpad

Generated on Wed Jan 25 15:42:40 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/netinet6/IPSEC6.H File Reference

inc/netinet6/IPSEC6.H File Reference

Detailed Description

Definition in file IPSEC6.H.

Go to the source code of this file.

Functions

secpolicy *ipsec6_getpolicybysock | __P ((struct mbuf *, u_int, struct socket *, int *))
secpolicy *ipsec6_getpolicybyaddr | __P ((struct mbuf *, u_int, int, int *))
int ipsec6_in_reject_so | __P ((struct mbuf *, struct socket *))
int ipsec6_delete_pcbpolicy | __P ((struct inpcb *))
int ipsec6_set_policy | __P ((struct inpcb *inp, int optname, caddr_t request, size_t len, int priv))
int ipsec6_get_policy | __P ((struct inpcb *inp, caddr_t request, size_t len, struct mbuf **mp))
int ipsec6_in_reject | __P ((struct mbuf *, struct inpcb *))
size_t ipsec6_hdrsiz | __P ((struct mbuf *, u_int, struct inpcb *))
const char *ipsec6_logpacketstr | __P ((struct ip6_hdr *, u_int32_t))
int ipsec6_output_trans | __P ((struct ipsec_output_state *, u_char *, struct mbuf *, struct secpolicy *, int, int *))
int ipsec6_output_tunnel | __P ((struct ipsec_output_state *, struct secpolicy *, int))
int ipsec6_tunnel_validate | __P ((struct mbuf *, int, u_int, struct secasvar *))

Variables

ipsecstat | ipsec6stat
secpolicy | ip6_def_policy
int | ip6_esp_trans_deflev
int | ip6_esp_net_deflev
int | ip6_ah_trans_deflev
int | ip6_ah_net_deflev
int | ip6_ipsec_ecn
int | ip6_esp_randpad

Generated on Wed Jan 25 15:42:40 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/netinet6/MLD6_VAR.H File Reference

inc/netinet6/MLD6_VAR.H File Reference

Detailed Description

Definition in file MLD6_VAR.H.

Go to the source code of this file.

Functions

void mld6_init | __P ((void))
void mld6_input | __P ((struct mbuf *, int))
void mld6_start_listening | __P ((struct in6_multi *))

Generated on Wed Jan 25 15:42:40 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/netinet6/ND6.H File Reference

inc/netinet6/ND6.H File Reference

Detailed Description

IPv6 Neighbor Discovery.

Definition in file ND6.H.

Go to the source code of this file.

Data Structures

struct | llinfo_nd6
struct | nd_ifinfo
struct | in6_nbrinfo
struct | in6_drlist
struct | in6_defrouter
struct | in6_prlist
struct | in6_prefix
struct | in6_ondireq
struct | in6_ndireq
struct | in6_ndifreq
struct | nd_defrouter
struct | nd_prefix
struct | inet6_ndpr_msghdr
struct | nd_pfxrouter
union | nd_opts

Functions

TAILQ_HEAD (nd_drhead, nd_defrouter)
LIST_HEAD (nd_prhead, nd_prefix)
void nd6_init | __P ((void))
void nd6_ifattach | __P ((struct ifnet *))
int nd6_is_addr_neighbor | __P ((struct sockaddr_in6 *, struct ifnet *))
void nd6_option_init | __P ((void *, int, union nd_opts *))
nd_opt_hdr *nd6_option | __P ((union nd_opts *))
rtentry *nd6_lookup | __P ((struct in6_addr *, int, struct ifnet *))
void nd6_timer | __P ((void *))
llinfo_nd6 *nd6_free | __P ((struct rtentry *))
void nd6_nud_hint | __P ((struct rtentry *, struct in6_addr *, int))
int nd6_resolve | __P ((struct ifnet *, struct rtentry *, struct mbuf *, struct sockaddr *, u_char *))
void nd6_rtrequest | __P ((int, struct rtentry *, struct rt_addrinfo *))
int nd6_ioctl | __P ((u_long, caddr_t, struct ifnet *))
rtentry *nd6_cache_lladdr | __P ((struct ifnet *, struct in6_addr *, char *, int, int, int))
int nd6_output | __P ((struct ifnet *, struct ifnet *, struct mbuf *, struct sockaddr_in6 *, struct rtentry *))
void nd6_na_input | __P ((struct mbuf *, int, int))
void nd6_na_output | __P ((struct ifnet *, const struct in6_addr *, const struct in6_addr *, u_long, int, struct sockaddr *))
void nd6_ns_output | __P ((struct ifnet *, const struct in6_addr *, const struct in6_addr *, struct llinfo_nd6 *, int))
void nd6_dad_start | __P ((struct ifaddr *, int *))
void nd6_dad_stop | __P ((struct ifaddr *))
void prelist_del | __P ((struct nd_prefix *))
void defrouter_addreq | __P ((struct nd_defrouter *))
void defrouter_delreq | __P ((struct nd_defrouter *, int))
int prelist_update | __P ((struct nd_prefix *, struct nd_defrouter *, struct mbuf *))
int nd6_prelist_add | __P ((struct nd_prefix *, struct nd_defrouter *, struct nd_prefix **))
nd_defrouter *defrouter_lookup | __P ((struct in6_addr *, struct ifnet *))
int in6_init_prefix_ltimes | __P ((struct nd_prefix *ndpr))
int nd6_setdefaultiface | __P ((int))
int in6_tmpifadd | __P ((const struct in6_ifaddr *, int))

Variables

int | nd6_prune
int | nd6_delay
int | nd6_umaxtries
int | nd6_mmaxtries
int | nd6_useloopback
int | nd6_maxnudhint
int | nd6_gctimer
llinfo_nd6 | llinfo_nd6
nd_ifinfo * | nd_ifinfo
nd_drhead | nd_defrouter
nd_prhead | nd_prefix
int | nd6_debug
callout | nd6_timer_ch
int | nd6_defifindex
int | ip6_desync_factor
u_int32_t | ip6_temp_preferred_lifetime
u_int32_t | ip6_temp_valid_lifetime
int | ip6_temp_regen_advance

Generated on Wed Jan 25 15:42:40 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/netinet6/PIM6.H File Reference

inc/netinet6/PIM6.H File Reference

Detailed Description

Definition in file PIM6.H.

Go to the source code of this file.

Data Structures

struct pim

Generated on Wed Jan 25 15:42:40 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/netinet6/PIM6_VAR.H File Reference

inc/netinet6/PIM6_VAR.H File Reference

Detailed Description

Definition in file PIM6_VAR.H.

Go to the source code of this file.

Data Structures

struct | pim6stat

Functions

int pim6_input | __P ((struct mbuf **, int *, int))

Variables

pim6stat | pim6stat

Generated on Wed Jan 25 15:42:40 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/netinet6/RAW_IP6.H File Reference

inc/netinet6/RAW_IP6.H File Reference

Detailed Description

Definition in file RAW_IP6.H.

Go to the source code of this file.

Data Structures

struct | rip6stat

Variables

rip6stat | rip6stat

Generated on Wed Jan 25 15:42:40 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/netinet6/SCOPE6_V.H File Reference

inc/netinet6/SCOPE6_V.H File Reference

Detailed Description

Definition in file SCOPE6_V.H.

Go to the source code of this file.

Functions

void scope6_ifattach | __P ((struct ifnet *))
int scope6_set | __P ((struct ifnet *, u_int32_t *))
int scope6_get_default | __P ((u_int32_t *))
u_int32_t scope6_in6_addrscope | __P ((struct in6_addr *))

Generated on Wed Jan 25 15:42:40 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/netinet6/TCP6_VAR.H File Reference

inc/netinet6/TCP6_VAR.H File Reference

Detailed Description

Definition in file TCP6_VAR.H.

Go to the source code of this file.

Functions

SYSCTL_DECL (_net_inet6_tcp6)
void tcp6_ctlinput | __P ((int, struct sockaddr *, void *))
void tcp6_init | __P ((void))
int tcp6_input | __P ((struct mbuf **, int *, int))
rtentry * | tcp_rtlookup6 (struct in_conninfo *)

Variables

int | tcp_v6mssdflt
pr_usrreqs | tcp6_usrreqs

Generated on Wed Jan 25 15:42:40 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/netinet6/UDP6_VAR.H File Reference

inc/netinet6/UDP6_VAR.H File Reference

Detailed Description

UDP in/out handling for IPv6.

Definition in file UDP6_VAR.H.

Go to the source code of this file.

Functions

SYSCTL_DECL (_net_inet6_udp6)
void udp6_ctlinput | __P ((int, struct sockaddr *, void *))
int udp6_input | __P ((struct mbuf **, int *, int))
int udp6_output | __P ((struct inpcb *inp, struct mbuf *m, struct sockaddr *addr, struct mbuf *control, struct thread *td))

Variables

pr_usrreqs | udp6_usrreqs

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/protocol/DUMPREST.H File Reference

inc/protocol/DUMPREST.H File Reference

Detailed Description

Dump/restore protocol definitions.

Definition in file DUMPREST.H.

Go to the source code of this file.

Data Structures

union | u_spcl
struct | u_spcl::s_spcl

Variables

u_spcl | u_spcl

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/protocol/ROUTED.H File Reference

inc/protocol/ROUTED.H File Reference

Detailed Description

Route Daeamon definitions.

Definition in file ROUTED.H.

Go to the source code of this file.

Data Structures

struct | netinfo
struct | netinfo
struct | netauth
struct | rip

Variables

char * | ripcmds [RIPCMD_MAX]

Variable Documentation

char* ripcmds[RIPCMD_MAX]

Initial value:

 {
        "#0", "REQUEST", "RESPONSE", "TRACEON", "TRACEOFF"
}
Definition at line 145 of file ROUTED.H.

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/protocol/RWHOD.H File Reference

inc/protocol/RWHOD.H File Reference

Detailed Description

Remote WHO daemon.

Definition in file RWHOD.H.

Go to the source code of this file.

Data Structures

struct | outmp
struct | whod
struct | whod::whoent

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/protocol/TALKD.H File Reference

inc/protocol/TALKD.H File Reference

Detailed Description

Talk server/client definitions.

Definition in file TALKD.H.

Go to the source code of this file.

Data Structures

struct | CTL_MSG
struct | CTL_RESPONSE

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/protocol/TIMED.H File Reference

inc/protocol/TIMED.H File Reference

Detailed Description

Time Synchronisation Daemon.

Definition in file TIMED.H.

Go to the source code of this file.

Data Structures

struct | tsp

Variables

char * | tsptype [TSPTYPENUMBER]

Variable Documentation

char* tsptype[TSPTYPENUMBER]

Initial value:

 {
     "ANY", "ADJTIME", "ACK", "MASTERREQ", "MASTERACK", "SETTIME", "MASTERUP",
     "SLAVEUP", "ELECTION", "ACCEPT", "REFUSE", "CONFLICT", "RESOLVE", "QUIT",
     "DATE", "DATEREQ", "DATEACK", "TRACEON", "TRACEOFF", "MSITE", "MSITEREQ",
     "TEST", "SETDATE", "SETDATEREQ", "LOOP"
   }
Definition at line 105 of file TIMED.H.

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/rpc/AUTH.H File Reference

inc/rpc/AUTH.H File Reference

Detailed Description

RPC authentication interface.

Definition in file AUTH.H.

Go to the source code of this file.

Data Structures

union | des_block
struct | opaque_auth
struct | AUTH
struct | AUTH::auth_ops

Typedefs

typedef des_block | des_block

Enumerations

enum auth_stat {
AUTH_OK = 0,
AUTH_BADCRED = 1,
AUTH_REJECTEDCRED = 2,
AUTH_BADVERF = 3,
AUTH_REJECTEDVERF = 4,
AUTH_TOOWEAK = 5,
AUTH_INVALIDRESP = 6,
AUTH_FAILED = 7
}

Functions

__BEGIN_DECLS bool_t | xdr_des_block (XDR *, des_block *)
__BEGIN_DECLS AUTH * | authunix_create (char *, int, int, int, int *)
AUTH * | authunix_create_default (void)
AUTH * | authnone_create (void)
AUTH * | authdes_create (char *, u_int, struct sockaddr *, des_block *)

Variables

opaque_auth | _null_auth

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/rpc/AUTH_DES.H File Reference

inc/rpc/AUTH_DES.H File Reference

Detailed Description

RPC authentication.

Definition in file AUTH_DES.H.

Go to the source code of this file.

Data Structures

struct | authdes_fullname
struct | authdes_cred
struct | authdes_verf

Enumerations

enum authdes_namekind {
ADN_FULLNAME,
ADN_NICKNAME
}

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/rpc/AUTH_UNI.H File Reference

inc/rpc/AUTH_UNI.H File Reference

Detailed Description

RPC authentication.

Definition in file AUTH_UNI.H.

Go to the source code of this file.

Data Structures

struct | authunix_parms
struct | short_hand_verf

Functions

__BEGIN_DECLS bool_t | xdr_authunix_parms (XDR *, struct authunix_parms *)

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/rpc/CLNT.H File Reference

inc/rpc/CLNT.H File Reference

Detailed Description

RPC client-side interface.

Definition in file CLNT.H.

Go to the source code of this file.

Data Structures

struct | rpc_err
struct | CLIENT
struct | CLIENT::clnt_ops
struct | rpc_createerr

Enumerations

enum clnt_stat {
RPC_SUCCESS = 0,
RPC_CANTENCODEARGS = 1,
RPC_CANTDECODERES = 2,
RPC_CANTSEND = 3,
RPC_CANTRECV = 4,
RPC_TIMEDOUT = 5,
RPC_VERSMISMATCH = 6,
RPC_AUTHERROR = 7,
RPC_PROGUNAVAIL = 8,
RPC_PROGVERSMISMATCH = 9,
RPC_PROCUNAVAIL = 10,
RPC_CANTDECODEARGS = 11,
RPC_SYSTEMERROR = 12,
RPC_UNKNOWNHOST = 13,
RPC_UNKNOWNPROTO = 17,
RPC_PMAPFAILURE = 14,
RPC_PROGNOTREGISTERED = 15,
RPC_FAILED = 16
}

Functions

__BEGIN_DECLS CLIENT * | clntraw_create (u_long, u_long)
CLIENT * | clnt_create (char *, u_long, u_long, char *)
CLIENT * | clnttcp_create (struct sockaddr_in *, u_long, u_long, int *, u_int, u_int)
CLIENT * | clntudp_create (struct sockaddr_in *, u_long, u_long, struct timeval, int *)
CLIENT * | clntudp_bufcreate (struct sockaddr_in *, u_long, u_long, struct timeval, int *, u_int, u_int)
void | clnt_pcreateerror (char *)
char * | clnt_spcreateerror (char *)
void | clnt_perrno (enum clnt_stat)
char * | clnt_sperrno (enum clnt_stat)
void | clnt_perror (CLIENT *, char *)
char * | clnt_sperror (CLIENT *, char *)
int | callrpc (char *host, u_long prognum, u_long versnum, u_long procnum, xdrproc_t inproc, char *in, xdrproc_t outproc, char *out)

Variables

rpc_createerr | rpc_createerr

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/rpc/KEY_PROT.H File Reference

inc/rpc/KEY_PROT.H File Reference

Detailed Description

RPC key exchange protocol.

Definition in file KEY_PROT.H.

Go to the source code of this file.

Data Structures

struct | cryptkeyarg
struct | cryptkeyres
struct | unixcred
struct | getcredres

Typedefs

typedef enum keystatus | keystatus
typedef char | keybuf [HEXKEYBYTES]
typedef char * | netnamestr
typedef cryptkeyarg | cryptkeyarg
typedef cryptkeyres | cryptkeyres
typedef unixcred | unixcred
typedef getcredres | getcredres

Enumerations

enum keystatus {
KEY_SUCCESS = 0,
KEY_NOSECRET = 1,
KEY_UNKNOWN = 2,
KEY_SYSTEMERR = 3
}

Functions

bool_t | xdr_keystatus ()
bool_t | xdr_keybuf ()
bool_t | xdr_netnamestr ()
bool_t | xdr_cryptkeyarg ()
bool_t | xdr_cryptkeyres ()
bool_t | xdr_unixcred ()
bool_t | xdr_getcredres ()
long * | key_set_1 ()
cryptkeyres * | key_encrypt_1 ()
cryptkeyres * | key_decrypt_1 ()
des_block * | key_gen_1 ()
getcredres * | key_getcred_1 ()

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/rpc/PMAP_CLN.H File Reference

inc/rpc/PMAP_CLN.H File Reference

Detailed Description

RPC portmapper (client-side).

Definition in file PMAP_CLN.H.

Go to the source code of this file.

Functions

__BEGIN_DECLS bool_t | pmap_set (u_long, u_long, int, int)
bool_t | pmap_unset (u_long, u_long)
pmaplist * | pmap_getmaps (struct sockaddr_in *)
enum clnt_stat | pmap_rmtcall (struct sockaddr_in *, u_long, u_long, u_long, xdrproc_t, caddr_t, xdrproc_t, caddr_t, struct timeval, u_long *)
enum clnt_stat | clnt_broadcast (u_long, u_long, u_long, xdrproc_t, char *, xdrproc_t, char *, bool_t(*)())
u_short | pmap_getport (struct sockaddr_in *, u_long, u_long, u_int)

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/rpc/PMAP_PRO.H File Reference

inc/rpc/PMAP_PRO.H File Reference

Detailed Description

RPC portmappper.

Definition in file PMAP_PRO.H.

Go to the source code of this file.

Data Structures

struct | pmap
struct | pmaplist

Functions

__BEGIN_DECLS bool_t | xdr_pmap (XDR *, struct pmap *)
bool_t | xdr_pmaplist (XDR *, struct pmaplist **)

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/rpc/PMAP_RMT.H File Reference

inc/rpc/PMAP_RMT.H File Reference

Detailed Description

RPC portmapper definitions.

Definition in file PMAP_RMT.H.

Go to the source code of this file.

Data Structures

struct | rmtcallargs
struct | rmtcallres

Functions

__BEGIN_DECLS bool_t | xdr_rmtcall_args (XDR *, struct rmtcallargs *)
bool_t | xdr_rmtcallres (XDR *, struct rmtcallres *)

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/rpc/RPC.H File Reference

inc/rpc/RPC.H File Reference

Detailed Description

Main RPC header.

Definition in file RPC.H.

Go to the source code of this file.

Data Structures

struct | rpcent

Functions

__BEGIN_DECLS struct rpcent * | getrpcbyname (char *)
rpcent * | getrpcbynumber (long)
rpcent * | getrpcent (void)
void | setrpcent (int)
void | endrpcent (void)
void | rpc_init (void)
void | set_user_id (u_long uid)
void | set_group_id (u_long gid)
u_long | __geteuid (void)
u_long | __getegid (void)

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/rpc/RPC_MSG.H File Reference

inc/rpc/RPC_MSG.H File Reference

Detailed Description

RPC message definitions.

Definition in file RPC_MSG.H.

Go to the source code of this file.

Data Structures

struct | accepted_reply
struct | rejected_reply
struct | reply_body
struct | call_body
struct | rpc_msg

Enumerations

enum msg_type {
CALL = 0,
REPLY = 1
}
enum reply_stat {
MSG_ACCEPTED = 0,
MSG_DENIED = 1
}
enum accept_stat {
SUCCESS = 0,
PROG_UNAVAIL = 1,
PROG_MISMATCH = 2,
PROC_UNAVAIL = 3,
GARBAGE_ARGS = 4,
SYSTEM_ERR = 5
}
enum reject_stat {
RPC_MISMATCH = 0,
AUTH_ERROR = 1
}

Functions

__BEGIN_DECLS bool_t | xdr_callmsg (XDR *, struct rpc_msg *)
bool_t | xdr_callhdr (XDR *, struct rpc_msg *)
bool_t | xdr_replymsg (XDR *, struct rpc_msg *)
void | _seterr_reply (struct rpc_msg *, struct rpc_err *)

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/rpc/SVC.H File Reference

inc/rpc/SVC.H File Reference

Detailed Description

RPC server-side interface.

Definition in file SVC.H.

Go to the source code of this file.

Data Structures

struct | SVCXPRT
struct | SVCXPRT::xp_ops
struct | svc_req

Enumerations

enum xprt_stat {
XPRT_DIED,
XPRT_MOREREQS,
XPRT_IDLE
}

Functions

__BEGIN_DECLS bool_t | svc_register (SVCXPRT *, u_long, u_long, void(*)(), int)
void | svc_unregister (u_long, u_long)
void | xprt_register (SVCXPRT *)
void | xprt_unregister (SVCXPRT *)
bool_t | svc_sendreply (SVCXPRT *, xdrproc_t, char *)
void | svcerr_decode (SVCXPRT *)
void | svcerr_weakauth (SVCXPRT *)
void | svcerr_noproc (SVCXPRT *)
void | svcerr_progvers (SVCXPRT *, u_long, u_long)
void | svcerr_auth (SVCXPRT *, enum auth_stat)
void | svcerr_noprog (SVCXPRT *)
void | svcerr_systemerr (SVCXPRT *)
void | svc_getreqset (fd_set *)
void | rpctest_service ()
void | svc_getreq (int)
void | svc_run (void)
SVCXPRT * | svcraw_create (void)
SVCXPRT * | svcudp_create (int)
SVCXPRT * | svcudp_bufcreate (int, u_int, u_int)
SVCXPRT * | svctcp_create (int, u_int, u_int)

Variables

fd_set | svc_fdset
int | svc_fds

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/rpc/SVC_AUTH.H File Reference

inc/rpc/SVC_AUTH.H File Reference

Detailed Description

RPC authentication (server-side).

Definition in file SVC_AUTH.H.

Go to the source code of this file.

Functions

__BEGIN_DECLS enum auth_stat _authenticate (struct svc_req *, struct rpc_msg *)

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/rpc/TYPES.H File Reference

inc/rpc/TYPES.H File Reference

Detailed Description

RPC type definitions.

Definition in file TYPES.H.

Go to the source code of this file.

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/rpc/XDR.H File Reference

inc/rpc/XDR.H File Reference

Detailed Description

eXternal Data Representation.

Definition in file XDR.H.

Go to the source code of this file.

Data Structures

struct | XDR
struct | XDR::xdr_ops
struct | xdr_discrim
struct | netobj

Typedefs

typedef bool_t(* | xdrproc_t )()
typedef netobj | netobj

Enumerations

enum xdr_op {
XDR_ENCODE = 0,
XDR_DECODE = 1,
XDR_FREE = 2
}

Functions

__BEGIN_DECLS bool_t | xdr_void (XDR *, caddr_t)
bool_t | xdr_int (XDR *, int *)
bool_t | xdr_u_int (XDR *, u_int *)
bool_t | xdr_long (XDR *, long *)
bool_t | xdr_u_long (XDR *, u_long *)
bool_t | xdr_short (XDR *, short *)
bool_t | xdr_u_short (XDR *, u_short *)
bool_t | xdr_bool (XDR *, bool_t *)
bool_t | xdr_enum (XDR *, enum_t *)
bool_t | xdr_array (XDR *, char **, u_int *, u_int, u_int, xdrproc_t)
bool_t | xdr_bytes (XDR *, char **, u_int *, u_int)
bool_t | __xdr_opaque (XDR *, caddr_t, u_int)
bool_t | xdr_string (XDR *, char **, u_int)
bool_t | xdr_union (XDR *, enum_t *, char *, struct xdr_discrim *, xdrproc_t)
bool_t | xdr_char (XDR *, char *)
bool_t | xdr_u_char (XDR *, char *)
bool_t | xdr_vector (XDR *, char *, u_int, u_int, xdrproc_t)
bool_t | xdr_float (XDR *, float *)
bool_t | xdr_double (XDR *, double *)
bool_t | xdr_reference (XDR *, caddr_t *, u_int, xdrproc_t)
bool_t | xdr_pointer (XDR *, caddr_t *, u_int, xdrproc_t)
bool_t | xdr_wrapstring (XDR *, char **)
void | xdr_free (xdrproc_t, char *)
__BEGIN_DECLS bool_t | xdr_netobj (XDR *, struct netobj *)
void | xdrmem_create (XDR *, char *, u_int, enum xdr_op)
void | xdrstdio_create (XDR *, FILE *, enum xdr_op)
void | xdrrec_create (XDR *, u_int, u_int, char *, int(*)(), int(*)())
bool_t | xdrrec_endofrecord (XDR *, int)
bool_t | xdrrec_skiprecord (XDR *)
bool_t | xdrrec_eof (XDR *)

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/rpcsvc/YP_PROT.H File Reference

inc/rpcsvc/YP_PROT.H File Reference

Detailed Description

RPC service - Yellow Pages protocol definitions.

Definition in file YP_PROT.H.

Go to the source code of this file.

Data Structures

struct | datum
struct | ypmap_parms
struct | ypreq_key
struct | ypreq_nokey
struct | ypreq_xfr
struct | ypresp_val
struct | ypresp_key_val
struct | ypresp_master
struct | ypresp_order
struct | ypmaplist
struct | ypresp_maplist
struct | dom_binding
struct | ypbind_binding
struct | ypbind_resp
struct | ypbind_setdom
struct | yppushresp_xfr

Typedefs

typedef u_int | bool

Enumerations

enum ypbind_resptype {
YPBIND_SUCC_VAL = 1,
YPBIND_FAIL_VAL = 2
}

Functions

bool_t | xdr_datum ()
bool_t | xdr_ypdomain_wrap_string ()
bool_t | xdr_ypmap_wrap_string ()
bool_t | xdr_ypreq_key ()
bool_t | xdr_ypreq_nokey ()
bool_t | xdr_ypreq_xfr ()
bool_t | xdr_ypresp_val ()
bool_t | xdr_ypresp_key_val ()
bool_t | xdr_ypbind_resp ()
bool_t | xdr_ypbind_setdom ()
bool_t | xdr_yp_inaddr ()
bool_t | xdr_ypmap_parms ()
bool_t | xdr_ypowner_wrap_string ()
bool_t | xdr_yppushresp_xfr ()
bool_t | xdr_ypresp_order ()
bool_t | xdr_ypresp_master ()
bool_t | xdr_ypall ()
bool_t | xdr_ypresp_maplist ()

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/rpcsvc/YPCLNT.H File Reference

inc/rpcsvc/YPCLNT.H File Reference

Detailed Description

RPC service - Yellow Pages client.

Definition in file YPCLNT.H.

Go to the source code of this file.

Data Structures

struct | ypall_callback

Functions

int | yp_get_default_domain (char **domp)
int | yp_bind (char *dom)
int | _yp_dobind (char *dom, struct dom_binding **ypdb)
void | yp_unbind (char *dom)
int | yp_match (char *indomain, char *inmap, const char *inkey, int inkeylen, char **outval, int *outvallen)
int | yp_first (char *indomain, char *inmap, char **outkey, int *outkeylen, char **outval, int *outvallen)
int | yp_next (char *indomain, char *inmap, char *inkey, int inkeylen, char **outkey, int *outkeylen, char **outval, int *outvallen)
int | yp_master (char *indomain, char *inmap, char **outname)
int | yp_order (char *indomain, char *inmap, int *outorder)
int | yp_all (char *indomain, char *inmap, struct ypall_callback *incallback)
int | yp_invalid_domain (char *dom)
char * | yperr_string (int incode)
char * | ypbinderr_string (int incode)
int | ypprot_err (unsigned int incode)

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/sys/CDEFS.H File Reference

inc/sys/CDEFS.H File Reference

Detailed Description

C-compiler definitions.

Definition in file CDEFS.H.

Go to the source code of this file.

Data Structures

struct mbuf

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/sys/ERRNO.H File Reference

inc/sys/ERRNO.H File Reference

Detailed Description

Compatibility header.

Definition in file ERRNO.H.

Go to the source code of this file.

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/sys/IOCTL.H File Reference

inc/sys/IOCTL.H File Reference

Detailed Description

BSD socket I/O control.

Definition in file IOCTL.H.

Go to the source code of this file.

Functions

int ioctl (int __fd, int __cmd,...)

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/sys/PACKOFF.H File Reference

inc/sys/PACKOFF.H File Reference

Detailed Description

Default packing of structures.

Definition in file PACKOFF.H.

Go to the source code of this file.

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/sys/PACKON.H File Reference

inc/sys/PACKON.H File Reference

Detailed Description

Sets structure packing to 1 byte.

Definition in file PACKON.H.

Go to the source code of this file.

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/sys/PARAM.H File Reference

inc/sys/PARAM.H File Reference

Detailed Description

Miscellaneous defines.

Definition in file PARAM.H.

Go to the source code of this file.

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/sys/POLL.H File Reference

inc/sys/POLL.H File Reference

Detailed Description

Definition in file POLL.H.

Go to the source code of this file.

Data Structures

struct | pollfd

Functions

int | poll (struct pollfd *p, int num, int timeout)

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/sys/QUEUE.H File Reference

inc/sys/QUEUE.H File Reference

Detailed Description

Definition in file QUEUE.H.

Go to the source code of this file.

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/sys/SELECT.H File Reference

inc/sys/SELECT.H File Reference

Detailed Description

Compatibility header.

Definition in file SELECT.H.

Go to the source code of this file.

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/sys/SO_IOCTL.H File Reference

inc/sys/SO_IOCTL.H File Reference

Detailed Description

BSD socket I/O control.

Definition in file SO_IOCTL.H.

Go to the source code of this file.

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/sys/SOCKET.H File Reference

inc/sys/SOCKET.H File Reference

Detailed Description

BSD socket API.

Definition in file SOCKET.H.

Go to the source code of this file.

Data Structures

struct | linger
struct | sockaddr
struct | sockproto
struct | cmsghdr
struct | msghdr

Functions

__BEGIN_DECLS W32_FUNC int
W32_CALL 		accept (int, struct sockaddr *, int *)
W32_FUNC int W32_CALL | bind (int, const struct sockaddr *, int)
W32_FUNC int W32_CALL | closesocket (int s)
W32_FUNC int W32_CALL | connect (int, const struct sockaddr *, int)
W32_FUNC int W32_CALL | ioctlsocket (int s, long cmd, char *argp)
W32_FUNC int MS_CDECL | fcntlsocket (int s, int cmd,...)
W32_FUNC int W32_CALL | getdomainname (char *name, int len)
BSD-style:
Return domain name of this host.
W32_FUNC int W32_CALL | setdomainname (const char *name, int len)
BSD-style:
Set the host's domain name.
W32_FUNC int W32_CALL | gethostname (char *name, int len)
W32_FUNC int W32_CALL | sethostname (const char *name, int len)
BSD-style:
Expects a "Fully Qualified Domain Name" in `fqdn'.
W32_FUNC u_long W32_CALL | gethostid (void)
BSD style: returns local IPv4-address.
W32_FUNC u_long W32_CALL | sethostid (u_long ip)
W32_FUNC int W32_CALL | getpeername (int, struct sockaddr *, int *)
W32_FUNC int W32_CALL | getsockname (int, struct sockaddr *, int *)
W32_FUNC int W32_CALL | getsockopt (int, int, int, void *, int *)
W32_FUNC int W32_CALL | listen (int, int)
W32_FUNC int W32_CALL | recv (int, void *, int, int)
W32_FUNC int W32_CALL | recvfrom (int, void *, int, int, struct sockaddr *, int *)
W32_FUNC int W32_CALL | send (int, const void *, int, int)
W32_FUNC int W32_CALL | sendto (int, const void *, int, int, const struct sockaddr *, int)
W32_FUNC int W32_CALL | setsockopt (int, int, int, const void *, int)
W32_FUNC int W32_CALL | shutdown (int, int)
W32_FUNC int W32_CALL | socket (int, int, int)
socket().

Function Documentation

__BEGIN_DECLS W32_FUNC int W32_CALL accept | ( | int | s,
 |  | struct sockaddr * | addr,
 |  | int * | addrlen
 | ) |

Todo:
Should maybe loop over all maxconn TCBs and accept the one with oldest 'syn_timestamp'.
Definition at line 60 of file ACCEPT.C.

References _inet6_ntoa(), _sock_crit_start(), _sock_crit_stop(), _sock_free_rcv_buf(), _socklist_find(), _tcp_unthread(), chk_timeout(), DWORD, set_timeout(), sock_noflush(), socket(), _tcp_Socket::state, and tcp_tick().

W32_FUNC int W32_CALL bind | ( | int | s,
 |  | const struct sockaddr * | myaddr,
 |  | int | namelen
 | ) |

Todo:
check for "sleeping" ports (lport_inuse in pctcp.c) also. And return EADDRINUSE if local port not free.
Definition at line 62 of file BIND.C.

References _inet6_ntoa(), _sock_chk_sockaddr(), _socklist_find(), _UDP6_listen(), sin_mask, socket(), and WORD.

W32_FUNC int MS_CDECL fcntlsocket | ( | int | s,
 |  | int | cmd,
 |  |  | ...
 | ) |

Todo:
handle O_TEXT and O_BINARY
Definition at line 69 of file FCNTL.C.

References _socklist_find(), list_lookup(), and socket().

W32_FUNC int W32_CALL getdomainname | ( | char * | buffer,
 |  | int | buflen
 | ) |

BSD-style:
Return domain name of this host.

As per BSD spec, the resultant buffer ... ... "will be null-terminated _unless_there_is_insufficient_space_";

Set errno on failure and return -1. Definition at line 170 of file BSDNAME.C.

References DWORD.

W32_FUNC u_long W32_CALL gethostid ( void )

BSD style: returns local IPv4-address.

Return values:
address on network order.
Definition at line 51 of file BSDNAME.C.

References my_ip_addr, and netdb_init().

W32_FUNC int W32_CALL setdomainname | ( | const char * | name,
 |  | int | len
 | ) |

BSD-style:
Set the host's domain name.

Set errno on failure and return -1. Definition at line 197 of file BSDNAME.C.

References defaultdomain, DWORD, and StrLcpy().

W32_FUNC int W32_CALL sethostname | ( | const char * | fqdn,
 |  | int | len
 | ) |

BSD-style:
Expects a "Fully Qualified Domain Name" in `fqdn'.

Split at first `.' and extract `hostname' and `def_domain'. Set errno on failure and return -1. Definition at line 277 of file BSDNAME.C.

References DWORD, hostname, and setdomainname().

W32_FUNC int W32_CALL shutdown | ( | int | s,
 |  | int | how
 | ) |

Todo:
For tcp, should send RST if we get incoming data. Don't send ICMP error.

For tcp, should send FIN when all Tx data has been ack'ed. close_s(s) should be same as shutdown(s,SHUT_WR)

Definition at line 46 of file SHUTDOWN.C.

References _socklist_find(), and socket().

W32_FUNC int W32_CALL socket | ( | int | family,
 |  | int | type,
 |  | int | protocol
 | ) |

socket().

  • family The protocol family. Supports the AF_INET, AF_INET6, AF_PACKET families.
  • type SOCK_STREAM (tcp), SOCK_DGRAM (udp), SOCK_RAW (ip) or SOCK_PACKET (link).
  • protocol IPPROTO_TCP, IPPROTO_UDP or 0/IPPROTO_IP.
Return values:
The socket ID number
Definition at line 1719 of file SOCKET.C.

References _bsd_socket_hook(), init_sockets(), set_proto(), socket_op_demux(), and socklist_add().

Generated on Wed Jan 25 15:42:43 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/sys/SWAP.H File Reference

inc/sys/SWAP.H File Reference

Detailed Description

Swapping of short/long values.

Definition in file SWAP.H.

Go to the source code of this file.

Functions

__BEGIN_DECLS W32_FUNC unsigned
short W32_CALL 		ntohs (unsigned short)
W32_FUNC unsigned short W32_CALL | htons (unsigned short)
W32_FUNC unsigned long W32_CALL | ntohl (unsigned long)
W32_FUNC unsigned long W32_CALL | htonl (unsigned long)
W32_FUNC unsigned long cdecl | _w32_intel (unsigned long x)
Convert 32-bit big-endian (network order) to intel (host order) format.
W32_FUNC unsigned short cdecl | _w32_intel16 (unsigned short x)
Convert 16-bit big-endian (network order) to intel (host order) format.
__inline__ unsigned long | __ntohl (unsigned long x)
__inline__ unsigned short | __ntohs (unsigned short x)
__declspec (naked) inline unsigned long __fastcall __ntohl(unsigned long x)
W32_FUNC unsigned long cdecl | intel (unsigned long x)
W32_FUNC unsigned short cdecl | intel16 (unsigned short x)

Function Documentation

W32_FUNC unsigned long cdecl _w32_intel ( unsigned long val )

Convert 32-bit big-endian (network order) to intel (host order) format.

Or vice-versa. These are cdecl incase we patch them. Definition at line 141 of file MISC.C.

W32_FUNC unsigned short cdecl _w32_intel16 ( unsigned short val )

Convert 16-bit big-endian (network order) to intel (host order) format.

Or vice-versa Definition at line 153 of file MISC.C.

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/sys/SYSLOG.H File Reference

inc/sys/SYSLOG.H File Reference

Detailed Description

syslog() facility.

Definition in file SYSLOG.H.

Go to the source code of this file.

Data Structures

struct | _code

Typedefs

typedef _code | CODE

Functions

__BEGIN_DECLS W32_FUNC void | closelog (void)
W32_FUNC void | openlog (const char *, int, int)
W32_FUNC int | setlogmask (int)
W32_FUNC void | syslog (int, const char *,...)
W32_FUNC void | vsyslog (int, const char *, va_list)

Variables

CODE | prioritynames [13]
CODE | facilitynames [24]

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/sys/UIO.H File Reference

inc/sys/UIO.H File Reference

Detailed Description

Dummy header.

Definition in file UIO.H.

Go to the source code of this file.

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/sys/W32API.H File Reference

inc/sys/W32API.H File Reference

Detailed Description

Watt-32 API decoration for Win32 targets.

Definition in file W32API.H.

Go to the source code of this file.

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/sys/WERRNO.H File Reference

inc/sys/WERRNO.H File Reference

Detailed Description

sys_errlist[] and errno's for compilers with limited errnos. For WIN32, we do NOT use the <winsock.h> WSAE* codes.

G. Vanem <giva@bgnett.no> 1998 - 2004

Definition in file WERRNO.H.

Go to the source code of this file.

Functions

W32_FUNC void | perror_s (const char *str)
W32_FUNC char * | strerror_s (int errnum)
W32_FUNC void | perror (const char *str)
W32_FUNC char * | strerror (int errnum)
W32_FUNC int __stdcall | WSAGetLastError (void)
W32_FUNC void __stdcall | WSASetLastError (int err)

Variables

W32_DATA int | _w32_errno
W32_DATA int | _w32_sys_nerr
W32_DATA char * | _w32_sys_errlist []

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/sys/WTIME.H File Reference

inc/sys/WTIME.H File Reference

Detailed Description

Watt-32 time functions.

Definition in file WTIME.H.

Go to the source code of this file.

Data Structures

struct | timeval
struct | timezone
struct | tms
struct | itimerval
struct | timespec

Functions

W32_FUNC int | getitimer (int, struct itimerval *)
W32_FUNC int | setitimer (int, struct itimerval *, struct itimerval *)
W32_FUNC int | gettimeofday (struct timeval *tp, struct timezone *tz)
__BEGIN_DECLS W32_FUNC unsigned
long 		net_times (struct tms *buffer)
W32_FUNC int | gettimeofday2 (struct timeval *tv, struct timezone *tz)

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/sys/WTYPES.H File Reference

inc/sys/WTYPES.H File Reference

Detailed Description

Watt-32 type definitions.

Definition in file WTYPES.H.

Go to the source code of this file.

Data Structures

struct | iovec
struct | fd_set

Typedefs

typedef unsigned long long | u_int64_t
typedef unsigned char | u_char
typedef unsigned short | u_short
typedef unsigned short | ushort
typedef unsigned long | u_long
typedef unsigned long | u_int
typedef unsigned long | caddr_t
typedef unsigned char | u_int8_t
typedef unsigned short | u_int16_t
typedef unsigned long | u_int32_t
typedef short | int16_t
typedef long | int32_t
typedef fd_set | fd_set

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/ACCEPT.C File Reference

SRC/ACCEPT.C File Reference

Detailed Description

BSD accept().

Definition in file ACCEPT.C.

Go to the source code of this file.

Functions

int | dup_bind (Socket *socket, Socket **clone, int idx)
int | alloc_addr (Socket *socket, Socket *clone)
void | listen_free (Socket *socket, int idx)
int W32_CALL | accept (int s, struct sockaddr *addr, int *addrlen)
int | _sock_append (_tcp_Socket **tcp)
Called from tcp_fsm.c / tcp_listen_state() (via _bsd_socket_hook) to append a new connection to the listen-queue of socket 'sock'.

Function Documentation

int _sock_append ( _tcp_Socket ** tcp )

Called from tcp_fsm.c / tcp_listen_state() (via _bsd_socket_hook) to append a new connection to the listen-queue of socket 'sock'.

TCB on input ('orig') has received a SYN. Replace TCB on output with a cloned TCB that we append to the listen-queue and eventually is used by accept() to create a new socket.

TCB on input ('orig') must still be listening for further connections on the same port as specified in call to _TCP_listen().

Todo:
Implement SYN-cookies. http://cr.yp.to/syncookies.html

Todo:
Implement SYN-cookies and drop the segment if no match

drop the oldest (or a random) slot in the listen-queue.

Definition at line 416 of file ACCEPT.C.

References _bsd_socket_hook(), _sock_set_rcv_buf(), _tcp_allsocs, _tcp_Socket::last_acknum, _tcp_Socket::last_seqnum, _tcp_Socket::my6addr, _tcp_Socket::send_next, set_timeout(), tcp_recv_win, and _tcp_Socket::unhappy.

int W32_CALL accept | ( | int | s,
 |  | struct sockaddr * | addr,
 |  | int * | addrlen
 | ) |

Todo:
Should maybe loop over all maxconn TCBs and accept the one with oldest 'syn_timestamp'.
Definition at line 60 of file ACCEPT.C.

References _inet6_ntoa(), _sock_crit_start(), _sock_crit_stop(), _sock_free_rcv_buf(), _socklist_find(), _tcp_unthread(), chk_timeout(), DWORD, set_timeout(), sock_noflush(), socket(), _tcp_Socket::state, and tcp_tick().

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/ADR2ASC.C File Reference

SRC/ADR2ASC.C File Reference

Detailed Description

Make network address to printable formats

Definition in file ADR2ASC.C.

Go to the source code of this file.

Functions

char * addr2ascii (int af, const void *addrp, int len, char *buf)

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/ASC2ADR.C File Reference

SRC/ASC2ADR.C File Reference

Detailed Description

Convert ASCII to network addresses.

Definition in file ASC2ADR.C.

Go to the source code of this file.

Functions

int ascii2addr (int af, const char *ascii, void *result)

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/ASMPKT.H File Reference

SRC/ASMPKT.H File Reference

Detailed Description

Prototypes for functions in asmpkt.asm and asmpkt4.asm

Definition in file ASMPKT.H.

Go to the source code of this file.

Functions

void far cdecl | pkt_receiver_rm (void)
void cdecl | pkt_receiver4_start (void)
void cdecl | pkt_receiver4_rm (void)
void cdecl | pkt_receiver4_end (void)

Variables

WORD cdecl | asmpkt_size_chk
pkt_info *cdecl | asmpkt_inf

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/BIND.C File Reference

SRC/BIND.C File Reference

Detailed Description

BSD bind().

Definition in file BIND.C.

Go to the source code of this file.

Functions

int W32_CALL | bind (int s, const struct sockaddr *myaddr, int namelen)
int | main (int argc, char **argv)

Function Documentation

int W32_CALL bind | ( | int | s,
 |  | const struct sockaddr * | myaddr,
 |  | int | namelen
 | ) |

Todo:
check for "sleeping" ports (lport_inuse in pctcp.c) also. And return EADDRINUSE if local port not free.
Definition at line 62 of file BIND.C.

References _inet6_ntoa(), _sock_chk_sockaddr(), _socklist_find(), _UDP6_listen(), sin_mask, socket(), and WORD.

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/BSDDBUG.C File Reference

SRC/BSDDBUG.C File Reference

Detailed Description

BSD socket debugging.

Definition in file BSDDBUG.C.

Go to the source code of this file.

Functions

void | bsddbug_exit (void)
void | bsddbug_close (void)
int MS_CDECL | _sock_debugf (const char *fmt,...)
BOOL | _sock_dbug_active (void)
void | _sock_dbug_flush (void)
void | _sock_dbug_open (void)
void | set_dbg_fname (const char *value)
void | set_dbg_openmode (const char *value)
void | dbug_parse (const char *name, const char *value)
void | _sock_dbug_init (void)
void | show_local_ports_inuse (void)
void | bsd_fortify_print (const char *buf)
void | _sock_enter_scope (void)
void | _sock_leave_scope (void)

Variables

int | sk_scope = 0
void(* | prev_hook )(const char *, const char *)
BOOL | dbg_use_ods = FALSE
FILE * | dbg_file = NULL
char | dbg_omode [5] = "w+"
char | dbg_fname [MAX_PATHLEN+1] = ""

Variable Documentation

int sk_scope = 0 [static]

scope-level (indent printout) Definition at line 47 of file BSDDBUG.C.

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/BSDDBUG.H File Reference

SRC/BSDDBUG.H File Reference

Detailed Description

Definition in file BSDDBUG.H.

Go to the source code of this file.

Functions

int MS_CDECL | _sock_debugf (const char *fmt,...) ATTR_PRINTF(1
void | _sock_dbug_flush (void)
void | _sock_dbug_init (void)
void | _sock_dbug_open (void)
BOOL | _sock_dbug_active (void)
void | _sock_enter_scope (void)
void | _sock_leave_scope (void)
void | bsd_fortify_print (const char *buf)

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/BSDNAME.C File Reference

SRC/BSDNAME.C File Reference

Detailed Description

BSD and core-style name function.

Deprecated:
Oldstyle BSD similar functions are prefixed with '_'.

Definition in file BSDNAME.C.

Go to the source code of this file.

Functions

DWORD | _gethostid (void)
Core style: Returns local IPv4-address.
DWORD | _sethostid (DWORD ip)
Core-style: Sets local IPv4-address.
u_long W32_CALL | gethostid (void)
BSD style: returns local IPv4-address.
u_long W32_CALL | sethostid (DWORD ip)
BSD-style: Sets local IPv4-address.
const void * | _gethostid6 (void)
Core-style: Returns local IPv6-address.
void | _sethostid6 (const void *addr)
Core-style: Sets local IPv6-address.
int | _getpeername (const sock_type *s, void *dest, int *len)
Core-style:
Return 'watt_sockaddr' for peer in a UDP/TCP connection.
int | _getsockname (const sock_type *s, void *dest, int *len)
Core-style:
Return 'watt_sockaddr' for our side of a UDP/TCP connection.
int W32_CALL | getdomainname (char *buffer, int buflen)
BSD-style:
Return domain name of this host.
int W32_CALL | setdomainname (const char *name, int len)
BSD-style:
Set the host's domain name.
int W32_CALL | gethostname (char *buffer, int buflen)
int W32_CALL | sethostname (const char *fqdn, int len)
BSD-style:
Expects a "Fully Qualified Domain Name" in `fqdn'.
int | _get_machine_name (char *buf, int size)
Try asking a LAN extension of DOS for a host-name.

Function Documentation

DWORD _gethostid ( void )

Core style: Returns local IPv4-address.

Return values:
address on host order.
Definition at line 32 of file BSDNAME.C.

References DWORD, and my_ip_addr.

const void* _gethostid6 ( void )

Core-style: Returns local IPv6-address.

Note:
no BSD equivalent for this.
Return values:
pointer to current local IPv6 address.
Definition at line 74 of file BSDNAME.C.

References netdb_init().

DWORD _sethostid ( DWORD ip )

Core-style: Sets local IPv4-address.

Return values:
address on host order.
Definition at line 41 of file BSDNAME.C.

References DWORD, and my_ip_addr.

void _sethostid6 ( const void * addr )

Core-style: Sets local IPv6-address.

Note:
no BSD equivalent for this.
Definition at line 85 of file BSDNAME.C.

int W32_CALL getdomainname | ( | char * | buffer,
 |  | int | buflen
 | ) |

BSD-style:
Return domain name of this host.

As per BSD spec, the resultant buffer ... ... "will be null-terminated _unless_there_is_insufficient_space_";

Set errno on failure and return -1. Definition at line 170 of file BSDNAME.C.

References DWORD.

u_long W32_CALL gethostid ( void )

BSD style: returns local IPv4-address.

Return values:
address on network order.
Definition at line 51 of file BSDNAME.C.

References my_ip_addr, and netdb_init().

int W32_CALL setdomainname | ( | const char * | name,
 |  | int | len
 | ) |

BSD-style:
Set the host's domain name.

Set errno on failure and return -1. Definition at line 197 of file BSDNAME.C.

References defaultdomain, DWORD, and StrLcpy().

u_long W32_CALL sethostid ( DWORD ip )

BSD-style: Sets local IPv4-address.

Return values:
address on host order.
Definition at line 62 of file BSDNAME.C.

References my_ip_addr, and sethostid().

int W32_CALL sethostname | ( | const char * | fqdn,
 |  | int | len
 | ) |

BSD-style:
Expects a "Fully Qualified Domain Name" in `fqdn'.

Split at first `.' and extract `hostname' and `def_domain'. Set errno on failure and return -1. Definition at line 277 of file BSDNAME.C.

References DWORD, hostname, and setdomainname().

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/BSDNAME.H File Reference

SRC/BSDNAME.H File Reference

Detailed Description

Definition in file BSDNAME.H.

Go to the source code of this file.

Functions

W32_FUNC int | _getpeername (const sock_type *s, void *dest, int *len)
Core-style:
Return 'watt_sockaddr' for peer in a UDP/TCP connection.
W32_FUNC int | _getsockname (const sock_type *s, void *dest, int *len)
Core-style:
Return 'watt_sockaddr' for our side of a UDP/TCP connection.
W32_FUNC DWORD | _gethostid (void)
Core style: Returns local IPv4-address.
W32_FUNC DWORD | _sethostid (DWORD ip)
Core-style: Sets local IPv4-address.
int | _get_machine_name (char *buf, int size)
Try asking a LAN extension of DOS for a host-name.
void | _sethostid6 (const void *addr)
Core-style: Sets local IPv6-address.
const void * | _gethostid6 (void)
Core-style: Returns local IPv6-address.

Function Documentation

W32_FUNC DWORD _gethostid ( void )

Core style: Returns local IPv4-address.

Return values:
address on host order.
Definition at line 32 of file BSDNAME.C.

const void* _gethostid6 ( void )

Core-style: Returns local IPv6-address.

Note:
no BSD equivalent for this.
Return values:
pointer to current local IPv6 address.
Definition at line 74 of file BSDNAME.C.

References netdb_init().

W32_FUNC DWORD _sethostid ( DWORD ip )

Core-style: Sets local IPv4-address.

Return values:
address on host order.
Definition at line 41 of file BSDNAME.C.

void _sethostid6 ( const void * addr )

Core-style: Sets local IPv6-address.

Note:
no BSD equivalent for this.
Definition at line 85 of file BSDNAME.C.

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/BTRACE.H File Reference

SRC/BTRACE.H File Reference

Detailed Description

A simple stack-tracer inspired by glib. Handy for asserts and crashes.

NOT FINISHED.

Definition in file BTRACE.H.

Go to the source code of this file.

Functions

int | backtrace_init (const char *prog)
int | backtrace (void **buf, int size)
int | backtrace_symbols_fd (const void *buf, int size, int file)
int | traceback_exit (const void *caller)

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/BTREE.C File Reference

SRC/BTREE.C File Reference

Detailed Description

Binary Tree with variably sized data and node deletion.

C User Journal May 1992

Definition in file BTREE.C.

Go to the source code of this file.

Data Structures

struct | record

Typedefs

typedef enum tree_order | tree_order

Enumerations

enum tree_order {
NO_ORDER,
PRE_ORDER,
IN_ORDER,
POST_ORDER
}

Functions

int | tree_insert (TreeNode **root, const void *info, size_t info_size, CmpFunc cmp)
TreeNode * | tree_find (TreeNode *root, const void *info, CmpFunc cmp)
TreeNode * | tree_delete (TreeNode *root, TreeNode *node)
void | tree_free (TreeNode *root)
void | prompt (const char *verb)
int | rec_cmp (const void *a, const void *b)
void | tree_print (const record *record)
void | tree_trace (TreeNode *root)
int | main (void)

Variables

tree_order | t_order = IN_ORDER
record | rec

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/BTREE.H File Reference

SRC/BTREE.H File Reference

Detailed Description

Note:
Not used

Definition in file BTREE.H.

Go to the source code of this file.

Data Structures

struct | TreeNode

Typedefs

typedef TreeNode | TreeNode
typedef enum TreeChild | TreeChild
typedef int(* | CmpFunc )(const void *, const void *)

Enumerations

enum TreeChild {
NOT_CHILD = 1,
LEFT_CHILD,
RIGHT_CHILD
}

Functions

int | tree_insert (TreeNode **, const void *, size_t, CmpFunc)
TreeNode * | tree_find (TreeNode *, const void *, CmpFunc)
TreeNode * | tree_delete (TreeNode *, TreeNode *)
void | tree_free (TreeNode *)

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/CHKSUM.C File Reference

SRC/CHKSUM.C File Reference

Detailed Description

Compute internet checksum on data buffer. 1's complement (~) is done by caller.

Definition in file CHKSUM.C.

Go to the source code of this file.

Functions

WORD | in_checksum (const void *ptr, unsigned len)
This checksum routine is only used by 16-bit targets (and files outside the library).
WORD | _ip6_checksum (const in6_Header *ip, WORD proto, const void *payload, unsigned payloadlen)
Generic IPv6 checksum function.
int | _ip6_tcp_checksum (const in6_Header *ip, const tcp_Header *tcp, unsigned len)
Check tcp header checksum for an IPv6 packet.
int | _ip6_udp_checksum (const in6_Header *ip, const udp_Header *udp, unsigned len)
Check udp header checksum for an IPv6 packet.
int | _ip6_icmp_checksum (const in6_Header *ip, const void *icmp, unsigned len)
int | do_checksum (const BYTE *buf, BYTE protocol, unsigned len)

Function Documentation

WORD in_checksum | ( | const void * | ptr,
 |  | unsigned | len
 | ) |

This checksum routine is only used by 16-bit targets (and files outside the library).

32-bit targets use in_checksum_fast() in chksum0.s + chksum0.asm.

Note:
`in_check_sum()' and `in_checksum_fast()' are equally fast on a Pentium 4 CPU. But on a Pentium 2 the ASM version is approx. 10 times faster.
Definition at line 29 of file CHKSUM.C.

References BYTE, and WORD.

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/CHKSUM.H File Reference

SRC/CHKSUM.H File Reference

Detailed Description

Definition in file CHKSUM.H.

Go to the source code of this file.

Functions

W32_FUNC WORD | in_checksum (const void *ptr, unsigned len)
This checksum routine is only used by 16-bit targets (and files outside the library).
int | do_checksum (const BYTE *buf, BYTE proto, unsigned len)
WORD | _ip6_checksum (const in6_Header *ip, WORD proto, const void *payload, unsigned payloadlen)
Generic IPv6 checksum function.
int | _ip6_tcp_checksum (const in6_Header *ip, const tcp_Header *tcp, unsigned len)
Check tcp header checksum for an IPv6 packet.
int | _ip6_udp_checksum (const in6_Header *ip, const udp_Header *udp, unsigned len)
Check udp header checksum for an IPv6 packet.
int | _ip6_icmp_checksum (const in6_Header *ip, const void *icmp, unsigned len)
WORD cdecl | in_checksum_fast (const void *ptr, unsigned len)

Function Documentation

W32_FUNC WORD in_checksum | ( | const void * | ptr,
 |  | unsigned | len
 | ) |

This checksum routine is only used by 16-bit targets (and files outside the library).

32-bit targets use in_checksum_fast() in chksum0.s + chksum0.asm.

Note:
`in_check_sum()' and `in_checksum_fast()' are equally fast on a Pentium 4 CPU. But on a Pentium 2 the ASM version is approx. 10 times faster.
Definition at line 29 of file CHKSUM.C.

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/CLOSE.C File Reference

SRC/CLOSE.C File Reference

Detailed Description

BSD close()

Definition in file CLOSE.C.

Go to the source code of this file.

Functions

int | close_dgram (Socket *socket)
int | close_stream (Socket *socket)
int | close_s (int s)
int W32_CALL | closesocket (int s)

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/CONFIG.H File Reference

SRC/CONFIG.H File Reference

Detailed Description

Defines global library options.

Definition in file CONFIG.H.

Go to the source code of this file.

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/CONNECT.C File Reference

SRC/CONNECT.C File Reference

Detailed Description

BSD connect().

Definition in file CONNECT.C.

Go to the source code of this file.

Functions

int | tcp_connect (Socket *socket)
int | udp_connect (Socket *socket)
int | raw_connect (Socket *socket)
int | nblk_connect (Socket *socket)
int W32_CALL | connect (int s, const struct sockaddr *servaddr, int addrlen)
int | chk_signals (void)

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/COPYRIGH.H File Reference

SRC/COPYRIGH.H File Reference

Detailed Description

 *
 *   This copyright applies only to files that include copyright.h.
 *   Other files have their licence stated in the top.
 *
 *   WATTCP - TCP/IP library routines
 *
 *   Copyright (c) 1990, 1991, 1992, 1993 Erick Engelke
 *
 *   Portions Copyright (c) 1993  The Regents of the University of California
 *   Portions Copyright (c) 1993  Digital Equipment Corporation.
 *   Portions Copyright (c) 1993  Quentin Smart
 *   Portions Copyright (c) 1991  University of Waterloo
 *   Portions Copyright (c) 1990  National Center for Supercomputer Applications
 *   Portions Copyright (c) 1990  Clarkson University
 *   Portions Copyright (c) 1983, 1986, Imagen Corporation
 *
 *      This software is distributed in the hope that it will be useful,
 *      but without any warranty; without even the implied warranty of
 *      merchantability or fitness for a particular purpose.
 *
 *   RESTRICTIONS
 *   ------------
 *   You may freely use this library to produce programs which you may give
 *   away or sell in source format, or as compiled executables, or both.
 *
 *   You may not sell this library or a portion thereof or distribute modified
 *   versions the library code in either source or OBJect or LIBrary format
 *   without written permission from the author.  The author still maintains
 *   copyright privileges and will assert the privileges of ownership for
 *   purposes of royalties such distributions.
 *
 *   Portions of this code were written or enhanced by others and offerred
 *   to me for distribution in WATTCP under my copyright.  To my knowledge,
 *   all copyrights exercised are listed at the top of this file.  If this
 *   is incorrect, please contact me so I can rectify the situation.
 *
 *
 *   OFFICIAL SITE
 *   -------------
 *   The official distribution site for WATTCP (and many other TCP goodies)
 *   is dorm.rutgers.edu in pub/msdos/wattcp  (thanks Jim!)
 *
 *   That is where I upload the latest libraries, my own free applications
 *   and other applications I have collected and find useful.
 *
 *
 *   DOCUMENTATION
 *   -------------
 *   A programmer's reference manual I wrote is now available from the
 *   publisher.  They provide no additional support and cannot help
 *   you with any aspect of the software.  But they do pay a royalty
 *   to me which has been used to compensate my costs for developing
 *   this software and extending it, so I am very appreciative.
 *
 *   That manual is copyrighted and protected by international law.
 *   It may not be copied without the authors permission.  And its
 *   sale does not constitute a warranty or an automatic license to
 *   use WATTCP beyond the terms described in this file.
 *
 *   For payment they accept credit cards, cheques, checks, money orders
 *   and P.O.s.  Credit card orders can be processed over the telephone.
 *
 *   Note that they are located in Canada and mail to them MAY REQUIRE
 *   additional postage depending on where you live.  Also, be sure to
 *   use the entire address, including the last line.  Canada is a heck
 *   of a large country and that line really makes a difference.
 *
 *   Prices are listed in US dollars for convienence to our many
 *   international readers.  The value charged on credit card items
 *   will be the equivalent in Canadian dollars at the exchange rate
 *   of the day.
 *
 *   WATTCP Manual          $ 40  US funds for each manual orderred
 *                     ----------
 *   Shipping + Handling    $  5  US funds to North America
 *   (Air Mail)          or $ 10  US funds to anywhere else in the world
 *
 *                     ADD  $ 20  US funds IF YOU ARE USING PURCHASE ORDERS
 *                                in which case payment is due in 30 days.
 *                                Not necessary for cheques, credit cards, etc.
 *                     ----------
 *
 *          WATTCP Manual
 *          c/o Supro Network Software Inc.
 *          P.O. Box 18,
 *          Warsaw, Ont.
 *          CANADA
 *          K0L 3A0
 *
 *  Phone (705) 652-1572 and be certain to mention that you are talking
 *  about the WATTCP manual.
 *
 *  Please note, I am not involved in the processing loop for the manual
 *  and cannot tell you of the status of your order.  Use Supro's number
 *  instead.
 *
 *
 *  Developers' Meeting Place
 *  -------------------------
 *  Many of the key people involved in WATTCP frequent the
 *  comp.protocols.tcp-ip.ibmpc Usenet newgroup, and there
 *  are several people there who can answer most any question.
 *
 *  If you need my personal attention (I seem to have less and less
 *  available) you will have to Email my address below.  I cannot take
 *  phone calls relating to WATTCP at my place of occupation.
 *
 *

Erick Engelke erick@dorm.rutgers.edu
48 Daytona St.
Kitchener, Ont.
Canada

Definition in file COPYRIGH.H.

Go to the source code of this file.

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/COUNTRY.C File Reference

SRC/COUNTRY.C File Reference

Detailed Description

Function for fetching DOS's country info.

Definition in file COUNTRY.C.

Go to the source code of this file.

Functions

int | GetCountryCode (void)
int | GetCodePage (void)

Variables

char | country_info [35]

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/CPUMODEL.H File Reference

SRC/CPUMODEL.H File Reference

Detailed Description

Definition in file CPUMODEL.H.

Go to the source code of this file.

Functions

void SYSCALL cdecl | CheckCpuType (void)
int SYSCALL cdecl | asm_ffs (int val)
WORD SYSCALL cdecl | MY_CS (void)
WORD SYSCALL cdecl | MY_DS (void)
WORD SYSCALL cdecl | MY_ES (void)
WORD SYSCALL cdecl | MY_SS (void)
DWORD SYSCALL cdecl | Get_CR4 (void)
BOOL SYSCALL cdecl | SelWriteable (WORD sel)
BOOL SYSCALL cdecl | SelReadable (WORD sel)
__inline__ void | get_cpuid (DWORD val, DWORD *eax, DWORD *ebx, DWORD *ecx, DWORD *edx)
__inline__ uint64 | get_rdtsc (void)
__inline__ void | get_rdtsc2 (struct ulong_long *tsc)
void | pkt_save_fpu (char far *state)
void | pkt_restore_fpu (char far *state)
__inline__ BOOL | have_cpuid (void)
__declspec (naked) static BOOL have_cpuid(void)

Variables

CONST char DATA_DECL | x86_type
CONST char DATA_DECL | x86_model
CONST char DATA_DECL | x86_mask
CONST int DATA_DECL | x86_hard_math
CONST DWORD DATA_DECL | x86_capability
CONST int DATA_DECL | x86_have_cpuid
CONST char DATA_DECL | x86_vendor_id [13]

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/CRC.C File Reference

SRC/CRC.C File Reference

Detailed Description

CRC calculation.

These CRC functions are derived from code in chapter 19 of the book "C Programmer's Guide to Serial Communications", by Joe Campbell.

Only used by the language module (ref. language.l)

Definition in file CRC.C.

Go to the source code of this file.

Functions

void | mk_crctbl (DWORD poly, DWORD *tab)
DWORD | crc_bytes (const char *buf, unsigned len)
BOOL | crc_init (void)

Variables

DWORD * | crctable

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/CRIT.C File Reference

SRC/CRIT.C File Reference

Detailed Description

WatTCP critical error (int24h).

Definition in file CRIT.C.

Go to the source code of this file.

Functions

void cdecl | int24_isr (SWI_REGS *reg)
void | int24_restore (void)
void | int24_init (void)
int _far | int24_isr (unsigned dev_err, unsigned err_code, unsigned _far *dev_hdr)
void | int24_isr (void)
INTR_PROTOTYPE | int24_isr (bp, di, si, ds, es, dx, cx, bx, ax, ip, cs, flags)

Variables

REALPTR | int24_old
REALPTR | rmcb
_go32_dpmi_seginfo | rm_cb
__dpmi_regs | rm_reg

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/DYNIP.C File Reference

SRC/DYNIP.C File Reference

Detailed Description

Simple dynamic IP/hostname update client. Only updating using the DynDNS2 protocol is supported.

This code is based on the ddclient Perl-script by Paul Burry: http://members.rogers.com/ddclient/pub/ddclient.tar.gz

Definition in file DYNIP.C.

Go to the source code of this file.

Data Structures

struct | URL

Functions

int | get_url (const char *host, int port, const char *path, const char *user_pass)
Fetch a single URL optionally with authentication.
const char * | parse_myip_address (const char *buf)
Parse response buffer and find the first IP-address.
int | parse_dyndns_response (const char *buf)
Parse the status response from DynDNS.
int | chkip_method (const char *value)
Select method of getting your public IP (WAN-side) address.
int | dyndns_params (const char *value)
Extracts the host, port and request from the value.
void | url_free (struct URL *url)
Free the URL.
BOOL | url_parse (struct URL *res, const char *url)
Simple URL parser; accepts only "http://" prefixes (optional).
void | dynip_config (const char *name, const char *value)
Parser for DYNIP configuration.
void | dynip_exit (void)
Free allocated memory.
void | dynip_init (void)
int | dynip_exec (void)
int | base64encode (const char *in, char *out, size_t out_len)
BOOL | get_header (void *sock, long *cont_len_ptr)
Receive and parse the HYTTP header.

Variables

char | dyndns_user [MAX_VALUELEN+1] = ""
char | dyndns_passwd [MAX_VALUELEN+1] = ""
char | dyn_myhostname [MAX_VALUELEN+1] = ""
char | dyn_myip [20] = ""
BOOL | dynip_enable = FALSE
int | dyndns_refresh = 3600
int | trace_level = 0
char | config_file [MAX_PATHLEN+1] = "$(TEMP)\\W32DYNIP.TMP"
URL | dyndns
URL | chkip = { NULL, NULL, 0, FALSE }
char | resp_buf [2048]
void(* | prev_hook )(const char *, const char *)

Function Documentation

int chkip_method ( const char * value ) [static]

Select method of getting your public IP (WAN-side) address.

Either a dotted IPv4 address or an URL to return your address. Definition at line 367 of file DYNIP.C.

References isaddr(), StrLcpy(), and url_parse().

int dyndns_params ( const char * value ) [static]

Extracts the host, port and request from the value.

Used for sending the DynDNS IP/host update. Definition at line 379 of file DYNIP.C.

References url_parse().

void dynip_config | ( | const char * | name,
 |  | const char * | value
 | ) | [static]

Parser for DYNIP configuration.

Matches all "\c DYNIP.xx" values from WATTCP.CFG file and make appropriate actions. Definition at line 91 of file DYNIP.C.

References ARG_ATOI, ARG_FUNC, ARG_STRCPY, chkip_method(), dyndns_params(), and parse_config_table().

BOOL get_header | ( | void * | sock,
 |  | long * | cont_len_ptr
 | ) | [static]

Receive and parse the HYTTP header.

Return FALSE if header isn't correct. Return TRUE and extract "Content-Length" field. Definition at line 471 of file DYNIP.C.

References BYTE.

const char * parse_myip_address ( const char * orig ) [static]

Parse response buffer and find the first IP-address.

'buf' must be 0-terminated. Definition at line 213 of file DYNIP.C.

References aton(), and StrLcpy().

BOOL url_parse | ( | struct URL * | res,
 |  | const char * | url
 | ) | [static]

Simple URL parser; accepts only "http://" prefixes (optional).

Extracts host, port and request parts. Definition at line 297 of file DYNIP.C.

References StrLcpy().

Variable Documentation

struct URL dyndns [static]

Initial value:

 { "members.dyndns.org",
                             "/nic/update?system=dyndns&hostname=%s",
                             80, FALSE
                           }
Definition at line 66 of file DYNIP.C.

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/DYNIP.H File Reference

SRC/DYNIP.H File Reference

Detailed Description

Definition in file DYNIP.H.

Go to the source code of this file.

Functions

void | dynip_init (void)
int | dynip_exec (void)

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/ECHO.C File Reference

SRC/ECHO.C File Reference

Detailed Description

A simple echo/discard daemon. Listens for traffic on udp/tcp ports 7 and 9.

Definition in file ECHO.C.

Go to the source code of this file.

Functions

void | echo_discard_daemon (void)
"background" process handling echo + discard TCP sockets.
void | udp_handler (sock_type *s, void *data, int len, const tcp_PseudoHeader *ph)
Callback handler for echo + discard UDP sockets.
void | echo_config (const char *name, const char *value)
void | echo_discard_exit (void)
Don't bother resetting any connections.
void | echo_discard_init (void)
Called from watt_sock_init(): Setup config-file parser for "echo..." and "discard.." keywords.
void | echo_discard_start (void)
Starts the echo/discard services (udp/tcp).
int | main (int argc, char **argv)

Variables

_udp_Socket * | udp_echo_sock
_udp_Socket * | udp_disc_sock
_tcp_Socket * | tcp_echo_sock
_tcp_Socket * | tcp_disc_sock
BOOL | do_echo = 0
WORD | echo_port = 7
DWORD | echo_host = 0
BOOL | do_disc = 0
WORD | disc_port = 9
DWORD | disc_host = 0
void(* | prev_hook )(const char *, const char *)=NULL

Function Documentation

void echo_discard_daemon ( void ) [static]

"background" process handling echo + discard TCP sockets.

Todo:
handle jumbo packets (IP-fragments)
Definition at line 165 of file ECHO.C.

References BYTE, sock_dataready(), sock_read(), and sock_write().

void echo_discard_exit ( void ) [static]

Don't bother resetting any connections.

Just remove daemon and free allocated memory. Definition at line 96 of file ECHO.C.

References delwattcpd(), and echo_discard_daemon().

int main | ( | int | argc,
 |  | char ** | argv
 | ) |

Todo:
Make a echo client/server test program
Definition at line 202 of file ECHO.C.

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/ECHO.H File Reference

SRC/ECHO.H File Reference

Detailed Description

Definition in file ECHO.H.

Go to the source code of this file.

Functions

void | echo_discard_init (void)
Called from watt_sock_init(): Setup config-file parser for "echo..." and "discard.." keywords.
void | echo_discard_start (void)
Starts the echo/discard services (udp/tcp).

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/FCNTL.C File Reference

SRC/FCNTL.C File Reference

Detailed Description

BSD fcntlsocket().

Definition in file FCNTL.C.

Go to the source code of this file.

Functions

int MS_CDECL | fcntlsocket (int s, int cmd,...)

Variables

const struct search_list | commands []

Function Documentation

int MS_CDECL fcntlsocket | ( | int | s,
 |  | int | cmd,
 |  |  | ...
 | ) |

Todo:
handle O_TEXT and O_BINARY
Definition at line 69 of file FCNTL.C.

References _socklist_find(), list_lookup(), and socket().

Variable Documentation

const struct search_list commands[] [static]

Initial value:

 {
           { F_DUPFD,  "F_DUPFD"  },
           { F_GETFL,  "F_GETFL"  },
           { F_SETFL,  "F_SETFL"  },
           { F_GETFD,  "F_GETFD"  },
           { F_SETFD,  "F_SETFD"  },
           { F_GETLK,  "F_GETLK"  },
           { F_SETLK,  "F_SETLK"  },
           { F_SETLKW, "F_SETLKW" },
           { F_GETOWN, "F_GETOWN" },
           { F_SETOWN, "F_SETOWN" }
         }
Definition at line 54 of file FCNTL.C.

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/FORTIFY.C File Reference

SRC/FORTIFY.C File Reference

Detailed Description

A fortified memory allocation shell - V2.2.

Definition in file FORTIFY.C.

Go to the source code of this file.

Namespaces

namespace | std

Data Structures

struct | Header
class | Fortify_AutoLogFile

Functions

int | st_CheckBlock (struct Header *h, const char *file, DWORD line)
int | st_CheckFortification (BYTE *ptr, BYTE value, size_t size)
void | st_SetFortification (BYTE *ptr, BYTE value, size_t size)
void | st_OutputFortification (BYTE *ptr, BYTE value, size_t size)
void | st_HexDump (BYTE *ptr, size_t offset, size_t size, int title)
void | st_MakeHeaderValid (struct Header *h)
int | st_IsHeaderValid (const struct Header *h)
WORD | st_ChecksumHeader (const struct Header *h)
int | st_IsOnAllocatedList (const struct Header *h)
int | st_OutputHeader (struct Header *h)
void | st_OutputMemory (struct Header *h)
void | st_OutputLastVerifiedPoint (void)
void | st_DefaultOutput (const char *String)
const char * | st_MemoryBlockString (struct Header *h)
void | st_OutputDeleteTrace (void)
const char * | st_DeallocatedMemoryBlockString (struct Header *h)
int | st_IsOnDeallocatedList (const struct Header *h)
int | st_PurgeDeallocatedBlocks (DWORD Bytes, const char *file, DWORD line)
int | st_PurgeDeallocatedScope (BYTE Scope, const char *file, DWORD line)
int | st_CheckDeallocatedBlock (struct Header *h, const char *file, DWORD line)
void | st_FreeDeallocatedBlock (struct Header *h, const char *file, DWORD line)
void | message (BOOL warn, const char *fmt,...)
Fortify_LockLocalData (int lock)
void | heap_integrity_check (BOOL on)
void *FORTIFY_STORAGE | Fortify_Allocate (size_t size, unsigned char allocator, unsigned long flags, const char *file, DWORD line)
void FORTIFY_STORAGE | Fortify_Deallocate (void *uptr, BYTE deallocator, const char *file, DWORD line)
void | Fortify_LabelPointer (void *uptr, const char *label, const char *file, DWORD line)
int FORTIFY_STORAGE | Fortify_CheckPointer (void *uptr, const char *file, DWORD line)
Fortify_OutputFuncPtr FORTIFY_STORAGE | Fortify_SetOutputFunc (Fortify_OutputFuncPtr Output)
int FORTIFY_STORAGE | Fortify_SetAllocateFailRate (int Percent)
DWORD FORTIFY_STORAGE | Fortify_CheckAllMemory (const char *file, DWORD line)
BYTE FORTIFY_STORAGE | Fortify_EnterScope (const char *file, DWORD line)
BYTE FORTIFY_STORAGE | Fortify_LeaveScope (const char *file, DWORD line)
DWORD FORTIFY_STORAGE | Fortify_ListAllMemory (const char *file, DWORD line)
DWORD FORTIFY_STORAGE | Fortify_DumpAllMemory (const char *file, DWORD line)
void FORTIFY_STORAGE | Fortify_OutputStatistics (const char *file, DWORD line)
DWORD FORTIFY_STORAGE | Fortify_GetCurrentAllocation (const char *file, DWORD line)
void FORTIFY_STORAGE | Fortify_SetAllocationLimit (DWORD NewLimit, const char *file, DWORD line)
void FORTIFY_STORAGE | Fortify_Disable (const char *file, DWORD line)
void *FORTIFY_STORAGE | Fortify_malloc (size_t size, const char *file, DWORD line)
void * | Fortify_realloc (void *uptr, size_t new_size, const char *file, DWORD line)
void * | Fortify_calloc (size_t num, size_t size, const char *file, DWORD line)
void | Fortify_free (void *uptr, const char *file, DWORD line)
HGLOBAL | Fortify_GlobalAlloc (UINT flags, DWORD size, const char *file, DWORD line)
BOOL | Fortify_GlobalFree (void *ptr, const char *file, DWORD line)
char *FORTIFY_STORAGE | Fortify_strdup (const char *oldStr, const char *file, DWORD line)
Fortify_NewHandlerFunc | st_NewHandler (void)
void *FORTIFY_STORAGE | operator new (size_t size)
void *FORTIFY_STORAGE | operator new (size_t size, const char *file, DWORD line)
void *FORTIFY_STORAGE | operator new[] (size_t size)
void *FORTIFY_STORAGE | operator new[] (size_t size, const char *file, DWORD line)
void FORTIFY_STORAGE | Fortify_PreDelete (const char *file, DWORD line)
void FORTIFY_STORAGE | Fortify_PostDelete (void)
void FORTIFY_STORAGE | operator delete (void *uptr)
void FORTIFY_STORAGE | operator delete[] (void *uptr)

Variables

char | st_Buffer [4096] = { 0 }
Header * | st_AllocatedHead = 0
int | st_AllocateFailRate = 0
Fortify_OutputFuncPtr | st_Output = st_DefaultOutput
const char * | st_LastVerifiedFile = "unknown"
DWORD | st_LastVerifiedLine = 0
BYTE | st_Scope = 0
BYTE | st_Disabled = 0
char | st_LockDataStart = 0
int | gbl_FortifyMagic = 0
const char * | st_DeleteFile [FORTIFY_DELETE_STACK_SIZE]
DWORD | st_DeleteLine [FORTIFY_DELETE_STACK_SIZE]
DWORD | st_DeleteStackTop
DWORD | st_MaxBlocks = 0
DWORD | st_MaxAllocation = 0
DWORD | st_CurBlocks = 0
DWORD | st_CurAllocation = 0
DWORD | st_Allocations = 0
DWORD | st_Frees = 0
DWORD | st_TotalAllocation = 0
DWORD | st_AllocationLimit = 0xffffffff
Header * | st_DeallocatedHead = 0
Header * | st_DeallocatedTail = 0
DWORD | st_TotalDeallocated = 0
const char * | st_AllocatorName []
const char * | st_DeallocatorName []
const BYTE | st_ValidDeallocator []
char | st_LockDataEnd = 0
BYTE | Check_heap_integrity_flag
BYTE | Heap_init_byte
BYTE | Init_allocated_storage
Fortify_AutoLogFile | Abracadabra

Variable Documentation

const char* st_AllocatorName[] [static]

Initial value:

 {
                  "malloc()",
                  "calloc()",
                  "realloc()",
                  "strdup()",
                  "new",
                  "new[]",
                  "GlobalAllocPtr()"
                }
Definition at line 232 of file FORTIFY.C.

const char* st_DeallocatorName[] [static]

Initial value:

 {
                  "nobody",
                  "free()",
                  "realloc()",
                  "delete",
                  "delete[]",
                  "GlobalFreePtr()"
                }
Definition at line 243 of file FORTIFY.C.

const BYTE st_ValidDeallocator[] [static]

Initial value:

 {
    (1 << Fortify_Deallocator_free) | (1 << Fortify_Deallocator_realloc),
    (1 << Fortify_Deallocator_free) | (1 << Fortify_Deallocator_realloc),
    (1 << Fortify_Deallocator_free) | (1 << Fortify_Deallocator_realloc),
    (1 << Fortify_Deallocator_free) | (1 << Fortify_Deallocator_realloc),
#if defined(FORTIFY_PROVIDE_ARRAY_NEW) && defined(FORTIFY_PROVIDE_ARRAY_DELETE)
    (1 << Fortify_Deallocator_delete),
    (1 << Fortify_Deallocator_array_delete)
#else
    (1 << Fortify_Deallocator_delete) | (1 << Fortify_Deallocator_array_delete),
    (1 << Fortify_Deallocator_delete) | (1 << Fortify_Deallocator_array_delete)
#endif
}
Definition at line 252 of file FORTIFY.C.

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/FORTIFY.H File Reference

SRC/FORTIFY.H File Reference

Detailed Description

V2.2 - All C & C++ source files to be fortified should #include this file

Definition in file FORTIFY.H.

Go to the source code of this file.

Typedefs

typedef void(* | Fortify_NewHandlerFunc )(void)
typedef void(* | Fortify_OutputFuncPtr )(const char *)

Functions

void * | Fortify_Allocate (size_t size, unsigned char allocator, unsigned long flags, const char *file, unsigned long line)
void | Fortify_Deallocate (void *uptr, unsigned char deallocator, const char *file, unsigned long line)
unsigned long | Fortify_CheckAllMemory (const char *file, unsigned long line)
unsigned long | Fortify_ListAllMemory (const char *file, unsigned long line)
unsigned long | Fortify_DumpAllMemory (const char *file, unsigned long line)
int | Fortify_CheckPointer (void *uptr, const char *file, unsigned long line)
void | Fortify_LabelPointer (void *uptr, const char *label, const char *file, unsigned long line)
unsigned char | Fortify_EnterScope (const char *file, unsigned long line)
unsigned char | Fortify_LeaveScope (const char *file, unsigned long line)
void | Fortify_OutputStatistics (const char *file, unsigned long line)
unsigned long | Fortify_GetCurrentAllocation (const char *file, unsigned long line)
void | Fortify_SetAllocationLimit (unsigned long Limit, const char *file, unsigned long line)
int | Fortify_SetFailRate (int Percent)
void | Fortify_Disable (const char *file, unsigned long line)
int | Fortify_SetAllocateFailRate (int Percent)
Fortify_OutputFuncPtr | Fortify_SetOutputFunc (Fortify_OutputFuncPtr Output)
void * | Fortify_malloc (size_t size, const char *file, unsigned long line)
void * | Fortify_realloc (void *ptr, size_t new_size, const char *file, unsigned long line)
void * | Fortify_calloc (size_t num, size_t size, const char *file, unsigned long line)
void | Fortify_free (void *uptr, const char *file, unsigned long line)
char * | Fortify_strdup (const char *oldStr, const char *file, unsigned long line)
void * | operator new (size_t size)
void * | operator new (size_t size, const char *file, unsigned long line)
void | operator delete (void *pointer)
void | Fortify_PreDelete (const char *file, unsigned long line)
void | Fortify_PostDelete ()
void * | operator new[] (size_t size)
void * | operator new[] (size_t size, const char *file, unsigned long line)
void | operator delete[] (void *pointer)
void * | Fortify_GlobalAlloc (UINT flags, DWORD size, const char *file, DWORD line)
BOOL | Fortify_GlobalFree (void *ptr, const char *file, DWORD line)

Variables

int | gbl_FortifyMagic

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/FSEXT.C File Reference

SRC/FSEXT.C File Reference

Detailed Description

File System extensions for djgpp.

Definition in file FSEXT.C.

Go to the source code of this file.

Data Structures

struct | wstat

Functions

int | _fsext_demux (__FSEXT_Fnumber func, int *rv, va_list _args)

Variables

search_list | fs_func []

Variable Documentation

struct search_list fs_func[] [static]

Initial value:

 {
                      { __FSEXT_nop,   "nop"    },
                      { __FSEXT_open,  "open"   },
                      { __FSEXT_creat, "creat"  },
                      { __FSEXT_read,  "read"   },
                      { __FSEXT_write, "write"  },
                      { __FSEXT_ready, "ready"  },
                      { __FSEXT_close, "close"  },
                      { __FSEXT_fcntl, "fcntl"  },
                      { __FSEXT_ioctl, "ioctl"  },
                      { __FSEXT_lseek, "lseek"  },
                      { __FSEXT_link,  "link"   },
                      { __FSEXT_unlink,"unlink" },
#if (DJGPP_MINOR >= 2)
                      { __FSEXT_dup,   "dup"    },
                      { __FSEXT_dup2,  "dup2"   },
                      { __FSEXT_fstat, "fstat"  },
                      { __FSEXT_stat,  "stat"   },
#endif
#if (DJGPP_MINOR >= 4)
                      { __FSEXT_llseek,  "llseek"   },
                      { __FSEXT_readlink,"readlink" },
                      { __FSEXT_symlink, "symlink"  },
                      { __FSEXT_fchown,  "fchown"   },
                      { __FSEXT_chmod,   "chmod",   },
                      { __FSEXT_chown,   "chown",   },
                      { __FSEXT_fchmod,  "fchmod"   }
#endif
                    }
Definition at line 74 of file FSEXT.C.

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/GET_AI.C File Reference

SRC/GET_AI.C File Reference

Detailed Description

BSD getaddrinfo().

Definition in file GET_AI.C.

Go to the source code of this file.

Data Structures

struct | afd
struct | explore

Functions

int | str_isnumber (const char *)
int | explore_fqdn (const struct addrinfo *, const char *, const char *, struct addrinfo **res)
int | explore_null (const struct addrinfo *, const char *, struct addrinfo **)
int | explore_numeric (const struct addrinfo *, const char *, const char *, struct addrinfo **)
int | explore_numeric_scope (const struct addrinfo *, const char *, const char *, struct addrinfo **)
int | get_name (const char *, const struct afd *, struct addrinfo **, char *, const struct addrinfo *, const char *)
int | get_canonname (const struct addrinfo *, struct addrinfo *, const char *)
addrinfo * | get_ai (const struct addrinfo *, const struct afd *, const char *)
int | get_portmatch (const struct addrinfo *, const char *)
int | get_port (struct addrinfo *, const char *, int)
const struct afd * | find_afd (int)
char *W32_CALL | gai_strerror (int ecode)
int W32_CALL | if_nametoindex (const char *if_name)
char *W32_CALL | if_indextoname (int if_id, char *if_name)
int | __scope_ascii_to_id (const char *str)
int | __scope_id_to_ascii (int scope)
void | free_addrinfo (struct addrinfo *ai)
void W32_CALL | freeaddrinfo (struct addrinfo *ai)
void | afd_list_init (BOOL ip6_prio)
Initialise afd_list[].
int W32_CALL | getaddrinfo (const char *hostname, const char *servname, const struct addrinfo *hints, struct addrinfo **res)
void | dump_addrinfo (const struct addrinfo *ai)
int | main (void)

Variables

const char | rcsid []
explore | explore []
BOOL | called_from_getai = FALSE
afd | afd_list [3]
char * | ai_errlist []

Function Documentation

void afd_list_init ( BOOL ip6_prio ) [static]

Initialise afd_list[].

Give IPv6 protocol highest priority if 'ip6_prio' is TRUE. Definition at line 273 of file GET_AI.C.

References afd_list_init().

Variable Documentation

char* ai_errlist[] [static]

Initial value:

 {
  "Success",
  "Address family for hostname not supported",
  "Temporary failure in name resolution",
  "Invalid value for ai_flags",
  "Non-recoverable failure in name resolution",
  "ai_family not supported",
  "Memory allocation failure",
  "No address associated with hostname",
  "hostname nor servname provided, or not known",
  "servname not supported for ai_socktype",
  "ai_socktype not supported",
  "System error returned in errno",
  "Invalid value for hints",
  "Resolved protocol is unknown",
  "Unknown error",
}
Definition at line 128 of file GET_AI.C.

struct explore explore[] [static]

Initial value:

 {
     { AF_INET6, SOCK_DGRAM,  IPPROTO_UDP, "udp", 7 },
     { AF_INET6, SOCK_STREAM, IPPROTO_TCP, "tcp", 7 },
     { AF_INET6, SOCK_RAW,    ANY,         NULL,  5 },
     { AF_INET,  SOCK_DGRAM,  IPPROTO_UDP, "udp", 7 },
     { AF_INET,  SOCK_STREAM, IPPROTO_TCP, "tcp", 7 },
     { AF_INET,  SOCK_RAW,    ANY,         NULL,  5 },
     { -1,       0,           0,           NULL,  0 }
   }
Definition at line 88 of file GET_AI.C.

const char rcsid[] [static]

Initial value:

 "@(#) $Header: /tcpdump/master/tcpdump/missing/"
                            "getaddrinfo.c,v 1.10 2000/10/24 00:56:53 fenner Exp $"
Definition at line 51 of file GET_AI.C.

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/GET_IP.C File Reference

SRC/GET_IP.C File Reference

Detailed Description

BSD getipnodebyX().

Definition in file GET_IP.C.

Go to the source code of this file.

Functions

hostent * | copyandmerge (const struct hostent *he1, const struct hostent *he2, int af, int *err)
__inline void | scan_interface (BOOL *have_v4, BOOL *have_v6)
hostent *W32_CALL | getipnodebyname (const char *name, int af, int flags, int *error)
hostent *W32_CALL | getipnodebyaddr (const void *src, size_t len, int af, int *error)
void W32_CALL | freehostent (struct hostent *he)

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/GET_NI.C File Reference

SRC/GET_NI.C File Reference

Detailed Description

BSD getnameinfo(),

Definition in file GET_NI.C.

Go to the source code of this file.

Data Structures

struct | afd
struct | sockinet

Functions

void | afd_list_init (BOOL ip6_prio)
int | gi_result (int err, const char *str, unsigned line)
int W32_CALL | getnameinfo (const struct sockaddr *sa, int salen, char *host, int hostlen, char *serv, int servlen, int flags)
int | ip4_resolve (const char *name)
int | ip6_resolve (const char *name)
int | main (int argc, char **argv)

Variables

const char | rcsid []
afd | afd_list
int | ni_flags = NI_NAMEREQD

Variable Documentation

const char rcsid[] [static]

Initial value:

 "@(#) $Header: /tcpdump/master/tcpdump/missing/"
                            "getnameinfo.c,v 1.8 2000/10/24 00:56:53 fenner Exp $"
Definition at line 46 of file GET_NI.C.

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/GET_XBY.H File Reference

SRC/GET_XBY.H File Reference

Detailed Description

Definition in file GET_XBY.H.

Go to the source code of this file.

Data Structures

struct | _hostent
struct | _hostent6
struct | _netent
struct | _protoent
struct | _servent

Functions

W32_FUNC void | ReadHostsFile (const char *fname)
W32_FUNC void | ReadServFile (const char *fname)
W32_FUNC void | ReadProtoFile (const char *fname)
W32_FUNC void | ReadNetworksFile (const char *fname)
W32_FUNC void | ReadEthersFile (void)
W32_FUNC int | NumEtherEntries (void)
W32_FUNC void | InitEthersFile (const char *fname)
W32_FUNC void | CloseHostFile (void)
Close hosts-file.
W32_FUNC void | CloseServFile (void)
W32_FUNC void | CloseProtoFile (void)
W32_FUNC void | CloseNetworksFile (void)
W32_FUNC const char * | GetHostsFile (void)
Return name of hosts-file.
W32_FUNC const char * | GetServFile (void)
W32_FUNC const char * | GetProtoFile (void)
W32_FUNC const char * | GetNetFile (void)
W32_FUNC const char * | GetEthersFile (void)
W32_FUNC void | DumpHostsCache (void)
W32_FUNC void | ReadHosts6File (const char *fname)
W32_FUNC void | CloseHost6File (void)
W32_FUNC void | DumpHosts6Cache (void)
W32_FUNC const char * | GetHosts6File (void)
W32_FUNC void | sethostent6 (int stayopen)
W32_FUNC void | endhostent6 (void)
W32_FUNC struct hostent * | gethostent6 (void)
W32_FUNC struct hostent * | gethostbyname6 (const char *name)
W32_FUNC struct hostent * | gethostbyaddr6 (const void *addr)

Variables

BOOL | called_from_getai
W32_DATA unsigned | netdbCacheLife

Function Documentation

W32_FUNC void CloseHostFile ( void )

Close hosts-file.

To prevent running out of file-handles, one should close the hosts-file before spawning a new shell. Definition at line 189 of file GETHOST.C.

W32_FUNC const char* GetHostsFile ( void )

Return name of hosts-file.

Note:
Only returns the last 'hosts' file opened.
Definition at line 179 of file GETHOST.C.

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/GETETH.C File Reference

SRC/GETETH.C File Reference

Detailed Description

`/etc/ethers' file functions for Watt-32.

Definition in file GETETH.C.

Go to the source code of this file.

Data Structures

struct | ethent

Functions

int | getethent (const char *line, eth_address *e, char *name, size_t max)
void | endethent (void)
void | InitEthersFile (const char *fname)
const char * | GetEthersFile (void)
int | NumEtherEntries (void)
void | ReadEthersFile (void)
int | main (void)

Variables

ethent * | eth0 = NULL
int | num_entries = -1
char | ethersFname [MAX_PATHLEN] = ""

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/GETHOST.C File Reference

SRC/GETHOST.C File Reference

Detailed Description

BSD-like host-entry functions.

Definition in file GETHOST.C.

Go to the source code of this file.

Functions

BOOL | gethostbyname_internal (const char *name, const char **alias, struct _hostent *ret)
BOOL | gethostbyaddr_internal (const char *addr_name, int len, int type, struct _hostent *ret)
hostent * | fill_hostent (const struct _hostent *h)
_hostent * | add_hostent (struct _hostent *h, const char *name, const char *cname, DWORD *alist, DWORD addr, DWORD ttl)
void | ReadHostsFile (const char *fname)
const char * | GetHostsFile (void)
Return name of hosts-file.
void | CloseHostFile (void)
Close hosts-file.
void | ReopenHostFile (void)
Reopen hosts-file.
hostent *W32_CALL | gethostent (void)
Return the next (non-commented) line from the host-file.
hostent *W32_CALL | gethostbyname (const char *name)
hostent *W32_CALL | gethostbyname2 (const char *name, int family)
hostent *W32_CALL | gethostbyaddr (const char *addr_name, int len, int type)
void W32_CALL | sethostent (int stayopen)
void W32_CALL | endhostent (void)
void | uninit_warn (const char *func)
int *W32_CALL | __h_errno_location (void)
BOOL | ReverseHostsList (void)
void | DumpHostsCache (void)
void | print_hosts (void)
void | Sleep (int time)
int | main (void)

Variables

int | h_errno = 0
unsigned | netdbCacheLife = MAX_CACHE_LIFE
char * | hostFname = NULL
FILE * | hostFile = NULL
BOOL | hostClose = FALSE
const char * | from_where = NULL
_hostent * | host0 = NULL
BOOL | did_lookup = FALSE

Function Documentation

void CloseHostFile ( void )

Close hosts-file.

To prevent running out of file-handles, one should close the hosts-file before spawning a new shell. Definition at line 189 of file GETHOST.C.

BOOL gethostbyaddr_internal | ( | const char * | addr_name,
 |  | int | len,
 |  | int | type,
 |  | struct _hostent * | ret
 | ) | [static]

Todo:
Should return all our addresses if we're multihomed.

should be the new aliases

Definition at line 501 of file GETHOST.C.

References DWORD, gethostid(), _hostent::h_address, _hostent::h_next, _hostent::h_num_addr, _hostent::h_timeout, netdb_init(), and sin_mask.

BOOL gethostbyname_internal | ( | const char * | name,
 |  | const char ** | alias,
 |  | struct _hostent * | ret
 | ) | [static]

Todo:
should be canonical name
Definition at line 297 of file GETHOST.C.

References called_from_resolve, DWORD, gethostid(), _hostent::h_next, hostname, netdb_init(), and resolve().

struct hostent* W32_CALL gethostent ( void )

Return the next (non-commented) line from the host-file.

Format is: ip-address host-name [alias..] {
| # ..} Definition at line 210 of file GETHOST.C.

References isaddr(), netdb_init(), StrLcpy(), and strltrim().

const char* GetHostsFile ( void )

Return name of hosts-file.

Note:
Only returns the last 'hosts' file opened.
Definition at line 179 of file GETHOST.C.

void ReopenHostFile ( void )

Reopen hosts-file.

Call this after e.g. system() returns. Definition at line 200 of file GETHOST.C.

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/GETHOST6.C File Reference

SRC/GETHOST6.C File Reference

Detailed Description

gethostbyname6() for IPv6.

Definition in file GETHOST6.C.

Go to the source code of this file.

Functions

BOOL | gethostbyname6_internal (const char *name, const char **alias, struct _hostent6 *ret)
BOOL | gethostbyaddr6_internal (const char *addr, struct _hostent6 *ret)
hostent * | fill_hostent6 (const struct _hostent6 *h)
_hostent6 * | add_hostent6 (struct _hostent6 *h, const char *name, const char *cname, const void *addr_list, const void *addr, DWORD ttl)
void | ReadHosts6File (const char *fname)
const char * | GetHosts6File (void)
void | CloseHost6File (void)
void | ReopenHost6File (void)
hostent * | gethostent6 (void)
hostent * | gethostbyname6 (const char *name)
void | sethostent6 (int stayopen)
void | endhostent6 (void)
hostent * | gethostbyaddr6 (const void *addr)
BOOL | ReverseHosts6List (void)
void | DumpHosts6Cache (void)
void | print_hosts (void)
int | main (void)

Variables

char * | hostFname = NULL
FILE * | hostFile = NULL
BOOL | hostClose = FALSE
_hostent6 * | host0 = NULL
BOOL | did_lookup = FALSE

Function Documentation

BOOL gethostbyaddr6_internal | ( | const char * | addr,
 |  | struct _hostent6 * | ret
 | ) | [static]

Todo:
should check all addresses

should be the new aliases

Definition at line 439 of file GETHOST6.C.

References _hostent6::h_address, _hostent6::h_next, _hostent6::h_timeout, ip6_address, and netdb_init().

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/GETNAME.C File Reference

SRC/GETNAME.C File Reference

Detailed Description

BSD getsockname(), getpeername().

Definition in file GETNAME.C.

Go to the source code of this file.

Functions

int W32_CALL | getsockname (int s, struct sockaddr *name, int *namelen)
int W32_CALL | getpeername (int s, struct sockaddr *name, int *namelen)

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/GETNET.C File Reference

SRC/GETNET.C File Reference

Detailed Description

Simple BSD-like network-entry functions.

Definition in file GETNET.C.

Go to the source code of this file.

Functions

__inline struct netent * | fill_netent (const struct _netent *n)
void | ReadNetworksFile (const char *fname)
const char * | GetNetFile (void)
void | CloseNetworksFile (void)
void | ReopenNetworksFile (void)
netent *W32_CALL | getnetent (void)
netent *W32_CALL | getnetbyname (const char *name)
netent *W32_CALL | getnetbyaddr (long net, int type)
void W32_CALL | setnetent (int stayopen)
void W32_CALL | endnetent (void)

Variables

_netent * | network0 = NULL
char * | networkFname = NULL
FILE * | networkFile = NULL
BOOL | networkClose = FALSE

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/GETOPT.C File Reference

SRC/GETOPT.C File Reference

Detailed Description

Parse command-line options.

Definition in file GETOPT.C.

Go to the source code of this file.

Functions

int | getopt (int argc, char *const *_argv, const char *opt_str)

Variables

char * | optarg = NULL
int | optopt = 0
int | optind = 0
int | opterr = 1
char * | optswchar = "-/"
enum _optmode | optmode = GETOPT_UNIX
char * | next_opt
char * | empty = ""
BOOL | done
char | sw_char
char ** | options
char ** | non_options
int | options_count
int | non_options_count

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/GETOPT.H File Reference

SRC/GETOPT.H File Reference

Detailed Description

Definition in file GETOPT.H.

Go to the source code of this file.

Enumerations

enum _optmode {
GETOPT_UNIX,
GETOPT_ANY,
GETOPT_KEEP
}

Functions

W32_FUNC int | getopt (int argc, char *const *argv, const char *opt_str)

Variables

W32_DATA char * | optarg
W32_DATA int | optind
W32_DATA int | opterr
W32_DATA char * | optswchar
W32_DATA enum _optmode | optmode

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/GETPROT.C File Reference

SRC/GETPROT.C File Reference

Detailed Description

BSD getprotobyxx() functions.

Definition in file GETPROT.C.

Go to the source code of this file.

Functions

__inline struct protoent * | fill_protoent (const struct _protoent *p)
void | ReadProtoFile (const char *fname)
const char * | GetProtoFile (void)
void | CloseProtoFile (void)
void | ReopenProtoFile (void)
protoent *W32_CALL | getprotoent (void)
protoent *W32_CALL | getprotobyname (const char *proto)
protoent *W32_CALL | getprotobynumber (int proto)
void W32_CALL | setprotoent (int stayopen)
void W32_CALL | endprotoent (void)

Variables

_protoent * | proto0 = NULL
char * | protoFname = NULL
FILE * | protoFile = NULL
BOOL | protoClose = FALSE

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/GETPUT.C File Reference

SRC/GETPUT.C File Reference

Detailed Description

get/put short/long functions for little-endian platforms.

Definition in file GETPUT.C.

Go to the source code of this file.

Functions

WORD | _getshort (const BYTE *x)
DWORD | _getlong (const BYTE *x)
void | __putshort (WORD var, BYTE *ptr)
void | __putlong (DWORD var, BYTE *ptr)
DWORD W32_CALL | htonl (DWORD val)
DWORD W32_CALL | ntohl (DWORD val)
WORD W32_CALL | htons (WORD val)
WORD W32_CALL | ntohs (WORD val)

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/GETSERV.C File Reference

SRC/GETSERV.C File Reference

Detailed Description

Simple BSD-like services functions.

Definition in file GETSERV.C.

Go to the source code of this file.

Functions

__inline struct servent * | fill_servent (const struct _servent *s)
void | ReadServFile (const char *fname)
const char * | GetServFile (void)
void | CloseServFile (void)
void | ReopenServFile (void)
servent *W32_CALL | getservent (void)
servent *W32_CALL | getservbyname (const char *serv, const char *proto)
servent *W32_CALL | getservbyport (int port, const char *proto)
void W32_CALL | setservent (int stayopen)
void W32_CALL | endservent (void)
int | main (void)

Variables

_servent * | serv0 = NULL
char * | servFname = NULL
FILE * | servFile = NULL
BOOL | servClose = FALSE
_servent * | port_hash [PORT_HASH_SIZE]

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/GETTOD.C File Reference

SRC/GETTOD.C File Reference

Detailed Description

gettimeofday() for non-djgpp targets and
gettimeofday2() for higher accuracy timing.

Definition in file GETTOD.C.

Go to the source code of this file.

Functions

void | get_zone (struct timezone *tz, time_t now)
void | set_utc_offset (void)
Called from init_timers() once.
__inline uint64 | FileTimeToUnixEpoch (const FILETIME *ft)
int | gettimeofday (struct timeval *tv, struct timezone *tz)
__inline uint64 | microsec_clock (void)
uint64 | tsc_microsec (const uint64 *base)
void | adjust_cpu_clock (const struct timeval *tv)
BOOL | get_tv_from_tsc (const struct ulong_long *tsc, struct timeval *tv)
int | gettimeofday2 (struct timeval *tv, struct timezone *tz)
__inline BOOL | dayrollover (void)
void | usleep (DWORD usec)
int | main (int argc, char **argv)

Variables

long | utc_offset = 0

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/GETTOD.H File Reference

SRC/GETTOD.H File Reference

Detailed Description

Definition in file GETTOD.H.

Go to the source code of this file.

Functions

BOOL | get_tv_from_tsc (const struct ulong_long *tsc, struct timeval *tv)
void | set_utc_offset (void)
Called from init_timers() once.
int | gettimeofday2 (struct timeval *tv, struct timezone *tz)

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/HIGHC.C File Reference

SRC/HIGHC.C File Reference

Detailed Description

Functions for Metaware's High-C.

This file is for Metaware HighC/C++ with Pharlap only. Handles tracing of entry/exit functions and replaces the buggy system() routine.

Copyright (c) 1997-2002 Gisle Vanem <giva@bgnett.no>

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. All advertising materials mentioning features or use of this software must display the following acknowledgement: This product includes software developed by Gisle Vanem Bergen, Norway.

THIS SOFTWARE IS PROVIDED BY ME (Gisle Vanem) AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL I OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

Definition in file HIGHC.C.

Go to the source code of this file.

Functions

char * | SetupEnvironment (void)
int | Execute (const char *path, const char *args, char **env)
int | _mw_watt_system (const char *cmd)
BOOL | is_watt32_func (const char *func)
void | _call_trace (const char *from, const char *module, unsigned line, const char *to)
void | _prolog_trace (const char *func)
void | _epilog_trace (const char *func)

Variables

int | level = 0
const char * | caller [MAX_LEVEL]

Function Documentation

BOOL is_watt32_func ( const char * func ) [static]

<

Todo:
Fill in the rest (use a generated table?)
Definition at line 173 of file HIGHC.C.

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/IDNA.H File Reference

SRC/IDNA.H File Reference

Detailed Description

Definition in file IDNA.H.

Go to the source code of this file.

Data Structures

struct | conv_t
struct | Summary16

Typedefs

typedef long | ucs4_t

Functions

const char * | iconv_strerror (int rc)
Return textual error for 'rc'.
BOOL | iconv_init (WORD code_page)
Initialise iconv; find codepage and mapping functions to use.
BOOL | IDNA_convert_to_ACE (char *name, size_t *size)
Convert a possibly non-ASCII name into ACE-form.
BOOL | IDNA_convert_from_ACE (char *name, size_t *size)
Convert a possibly ACE-encoded name to a name in native codepage.

Function Documentation

BOOL IDNA_convert_from_ACE | ( | char * | name,
 |  | size_t * | size
 | ) |

Convert a possibly ACE-encoded name to a name in native codepage.

Todo:
Check for over-run on output.
1) Pass through labels w/o "xn--" prefix unaltered. 2) Strip "xn--" prefix and pass to punycode_decode() 3) Repeat for all labels with "xn--" prefix. 4) Collect Unicode strings and convert to original codepage. Definition at line 452 of file IDNA.C.

BOOL IDNA_convert_to_ACE | ( | char * | name,
 |  | size_t * | size
 | ) |

Convert a possibly non-ASCII name into ACE-form.

E.g. convert "www.troms›.no" to ACE:

1) Convert each label separately. "www", "troms›" and "no" 2) "troms›" -> u+0074 u+0072 u+006F u+006D u+0073 u+00F8 3) Pass this through `punycode_encode()' which gives "troms-zua". 4) Repeat for all labels with non-ASCII letters. 5) Prepending "xn--" for each converted label gives "www.xn--troms-zua.no".

E.g. 2: "bl†b‘r.syltet›y.no" -> "xn--blbr-roah.xn--syltety-v1a.no"

Ref. http://www.imc.org/idna/do-idna.cgi http://www.norid.no/domenenavnbaser/ace/ace_technical.en.html Definition at line 385 of file IDNA.C.

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/IOCTL.C File Reference

SRC/IOCTL.C File Reference

Detailed Description

BSD ioctlsocket().

Definition in file IOCTL.C.

Go to the source code of this file.

Functions

int | file_ioctrl (Socket *socket, long cmd, char *argp)
int | iface_ioctrl (Socket *socket, long cmd, char *argp)
int | arp_ioctrl (Socket *socket, long cmd, char *argp)
int | waterm_ioctrl (Socket *socket, long cmd, char *argp)
const char * | get_ioctl_cmd (long cmd)
int W32_CALL | ioctlsocket (int s, long cmd, char *argp)
void | __get_ifname (char *if_name)
void | __set_ifname (const char *if_name)
ifnet * | eth_ifnet (void)
ifnet * | tok_ifnet (void)
void | AssertFail (unsigned line)
char * | eth_addr_string (struct ether_addr *eth)
int | main (void)

Variables

char | eth_ifname [IFNAMSIZ] = "eth0"
char | arc_ifname [IFNAMSIZ] = "arch0"
char | tok_ifname [IFNAMSIZ] = "tr0"
char | fddi_ifname [IFNAMSIZ] = "fddi0"
char | ppp_ifname [IFNAMSIZ] = "ppp0"
char | slp_ifname [IFNAMSIZ] = "slp0"
const struct search_list | commands []

Function Documentation

struct ifnet* eth_ifnet ( void ) [static]

Todo:
fill info
Definition at line 231 of file IOCTL.C.

int iface_ioctrl | ( | Socket * | socket,
 |  | long | cmd,
 |  | char * | argp
 | ) | [static]

Todo:
Get point-to-point address

Set point-to-point address

Set interface metric

Handle deleting interface address

Handle add/change interface alias

Definition at line 251 of file IOCTL.C.

References _eth_addr, _eth_is_init, _eth_set_addr(), _pkt_rxmode, _pktdevclass, DWORD, eth_address, my_ip_addr, RXMODE_MULTICAST2, RXMODE_PROMISCOUS, sin_mask, and socket().

struct ifnet* tok_ifnet ( void ) [static]

Todo:
fill info
Definition at line 239 of file IOCTL.C.

int waterm_ioctrl | ( | Socket * | socket,
 |  | long | cmd,
 |  | char * | argp
 | ) | [static]

Todo:
set high watermark

get high watermark

set low watermark

get low watermark

OOB data available?

Definition at line 493 of file IOCTL.C.

References DWORD, and socket().

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/IOPORT.H File Reference

SRC/IOPORT.H File Reference

Detailed Description

Definition in file IOPORT.H.

Go to the source code of this file.

Functions

__inline__ unsigned char | inportb (unsigned short port)
__inline__ unsigned short | inportw (unsigned short port)
__inline__ void | outportb (unsigned short port, unsigned char data)
__inline__ void | outportw (unsigned short port, unsigned short data)

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/IP4_FRAG.C File Reference

SRC/IP4_FRAG.C File Reference

Detailed Description

IP4 de-fragmenter.

Definition in file IP4_FRAG.C.

Go to the source code of this file.

Data Structures

struct | huge_ip
struct | frag_key
struct | frag_bucket
struct | hd
struct | frag_hdr

Typedefs

typedef huge_ip | HugeIP
typedef hd | hole_descr

Functions

BOOL | setup_first_frag (const in_Header *ip, int idx)
in_Header * | alloc_frag_buffer (const in_Header *ip, int idx)
BOOL | match_frag (const in_Header *ip, int *slot, int *bucket, int *free)
__inline int | check_data_start (const in_Header *ip, DWORD ofs)
int | ip4_defragment (const in_Header **ip_ptr, DWORD offset, WORD flags)
int | ip4_free_fragment (const in_Header *ip)
void | chk_timeout_frags (void)
void | usage (char *argv0)
BYTE * | init_frag (int argc, char **argv)
int | rand_packet (fd_set *fd, int max)
int | main (int argc, char **argv)

Variables

int | _ip4_frag_reasm = MAX_IP_HOLDTIME
frag_hdr | frag_list [MAX_IP_FRAGS][MAX_FRAGMENTS]
frag_bucket | frag_buckets [MAX_IP_FRAGS]
long | data_start
long | data_end
long | data_length
BOOL | more_frags
DWORD | to_host = 0
WORD | frag_ofs = 0
int | max_frags = 5
int | frag_size = 1000
int | rand_frag = 0
int | rev_order = 0
int | time_frag = 0

Function Documentation

BYTE* init_frag | ( | int | argc,
 |  | char ** | argv
 | ) |

Todo:
Simulate fragment timeout
Definition at line 639 of file IP4_FRAG.C.

References BYTE.

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/IP4_FRAG.H File Reference

SRC/IP4_FRAG.H File Reference

Detailed Description

Definition in file IP4_FRAG.H.

Go to the source code of this file.

Functions

int | ip4_defragment (const in_Header **ip, DWORD ofs, WORD flags)
int | ip4_free_fragment (const in_Header *ip)
void | chk_timeout_frags (void)

Variables

int | _ip4_frag_reasm

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/IP4_IN.C File Reference

SRC/IP4_IN.C File Reference

Detailed Description

IPv4 input routines.

Version

1.0 : Sep 18, 2001 : G. Vanem - moved from pctcp.c & ip_out.c

Definition in file IP4_IN.C.

Go to the source code of this file.

Functions

int | _ip4_handler (const in_Header *ip, BOOL broadcast)
int | _chk_ip4_header (const in_Header *ip)
int | _ip4_is_local_addr (DWORD ip)
int | _ip4_is_loopback_addr (DWORD ip)
int | _ip4_is_unique_addr (DWORD ip)
int | _ip4_is_multihome_addr (DWORD ip)
int | _ip4_is_ip_brdcast (const in_Header *ip)
int | _ip4_is_multicast (DWORD ip)

Function Documentation

int _ip4_handler | ( | const in_Header * | ip,
 |  | BOOL | broadcast
 | ) |

Todo:
check for LSRR option and replace ip->source with actual source-address burried in option (ref. RFC-1122)

handle compressed IP (use zlib)

Definition at line 33 of file IP4_IN.C.

References _bsd_socket_hook(), _tcp_handler(), _udp_handler(), block_ip, in_Header::destination, DWORD, in_Header::frag_ofs, icmp_handler(), icmp_send_unreach(), in_Header::proto, sock_type::tcp, and WORD.

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/IP4_IN.H File Reference

SRC/IP4_IN.H File Reference

Detailed Description

Definition in file IP4_IN.H.

Go to the source code of this file.

Functions

int | _ip4_handler (const in_Header *ip, BOOL broadcast)
int | _chk_ip4_header (const in_Header *ip)
int | _ip4_is_local_addr (DWORD ip)
int | _ip4_is_unique_addr (DWORD ip)
int | _ip4_is_multihome_addr (DWORD ip)
int | _ip4_is_ip_brdcast (const in_Header *ip)
int | _ip4_is_multicast (DWORD ip)
int | _ip4_is_loopback_addr (DWORD ip)

Function Documentation

int _ip4_handler | ( | const in_Header * | ip,
 |  | BOOL | broadcast
 | ) |

Todo:
check for LSRR option and replace ip->source with actual source-address burried in option (ref. RFC-1122)

handle compressed IP (use zlib)

Definition at line 33 of file IP4_IN.C.

References _bsd_socket_hook(), _tcp_handler(), _udp_handler(), block_ip, in_Header::destination, DWORD, in_Header::frag_ofs, icmp_handler(), icmp_send_unreach(), in_Header::proto, sock_type::tcp, and WORD.

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/IP4_OUT.C File Reference

SRC/IP4_OUT.C File Reference

Detailed Description

IPv4 output routines.

Definition in file IP4_OUT.C.

Go to the source code of this file.

Functions

WORD | _get_ip4_id (void)
Increment IPv4-identifier before returning it.
WORD | _get_this_ip4_id (void)
Return IPv4-identifier but don't increment it.
int | _ip4_output (in_Header *ip, DWORD src_ip, DWORD dst_ip, BYTE protocol, BYTE ttl, BYTE tos, WORD ip_id, int data_len, const void *sock, const char *file, unsigned line)
The IP4 packet transmitter.
__inline in_Header * | make_ip_pkt (DWORD host, BOOL first, char **data)
in_Header * | make_tcp_pkt (const _tcp_Socket *s, BOOL first, char **data)
__inline in_Header * | make_udp_pkt (const _udp_Socket *s, BOOL first, unsigned len, char **data)
int | _ip4_send_fragments (sock_type *s, BYTE proto, DWORD dest, const void *buf, unsigned len, const char *file, unsigned line)

Variables

BYTE | _default_tos = 0
int | _default_ttl = 254
int | _ip4_id_increment = 1
BOOL | _ip4_dont_frag = FALSE
WORD | ip4_id = 0

Function Documentation

WORD _get_ip4_id ( void )

Increment IPv4-identifier before returning it.

Note: Use _get_this_ip4_id() for sending IP fragments. Definition at line 64 of file IP4_OUT.C.

References _ip4_id_increment, and WORD.

int _ip4_output | ( | in_Header * | ip,
 |  | DWORD | src_ip,
 |  | DWORD | dst_ip,
 |  | BYTE | protocol,
 |  | BYTE | ttl,
 |  | BYTE | tos,
 |  | WORD | ip_id,
 |  | int | data_len,
 |  | const void * | sock,
 |  | const char * | file,
 |  | unsigned | line
 | ) |

The IP4 packet transmitter.

Return values:
'data_len | + sizeof(*ip)' on success.
0 | on fail.
Todo:
Handle IP-fragments here (call ip4_send_fragments() when needed)
Definition at line 85 of file IP4_OUT.C.

References _default_ttl, _eth_send(), _get_ip4_id(), _ip4_dont_frag, BYTE, in_Header::checksum, in_Header::destination, in_Header::frag_ofs, in_Header::hdrlen, in_Header::identification, in_Header::length, my_ip_addr, in_Header::proto, in_Header::source, in_Header::tos, in_Header::ttl, in_Header::ver, and WORD.

int _ip4_send_fragments | ( | sock_type * | s,
 |  | BYTE | proto,
 |  | DWORD | dest,
 |  | const void * | buf,
 |  | unsigned | len,
 |  | const char * | file,
 |  | unsigned | line
 | ) |

Todo:
Maybe send highest offset fragment first?

support sending raw IPv4 fragments

Definition at line 234 of file IP4_OUT.C.

References _get_ip4_id(), _ip4_output(), BYTE, in_Header::frag_ofs, in_Header::proto, _tcp_Socket::state, sock_type::tcp, tcp_tick(), sock_type::udp, and WORD.

Variable Documentation

BYTE _default_tos = 0

The default type-of-service for IP Definition at line 52 of file IP4_OUT.C.

int _default_ttl = 254

The default time-to-live for IP Definition at line 53 of file IP4_OUT.C.

BOOL _ip4_dont_frag = FALSE

Enable the IP_DF bit on output Definition at line 55 of file IP4_OUT.C.

int _ip4_id_increment = 1

The IP identifier increment Definition at line 54 of file IP4_OUT.C.

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/IP4_OUT.H File Reference

SRC/IP4_OUT.H File Reference

Detailed Description

Definition in file IP4_OUT.H.

Go to the source code of this file.

Functions

WORD | _get_ip4_id (void)
Increment IPv4-identifier before returning it.
WORD | _get_this_ip4_id (void)
Return IPv4-identifier but don't increment it.
int | _ip4_output (in_Header *ip, DWORD src_ip, DWORD dst_ip, BYTE protocol, BYTE ttl, BYTE tos, WORD ip_id, int data_len, const void *sock, const char *file, unsigned line)
The IP4 packet transmitter.
int | _ip4_send_fragments (sock_type *sk, BYTE proto, DWORD dest, const void *buf, unsigned len, const char *file, unsigned line)

Variables

BOOL | _ip4_dont_frag
int | _ip4_id_increment
int | _default_ttl
BYTE _default_tos

Function Documentation

WORD _get_ip4_id ( void )

Increment IPv4-identifier before returning it.

Note: Use _get_this_ip4_id() for sending IP fragments. Definition at line 64 of file IP4_OUT.C.

References _ip4_id_increment, and WORD.

int _ip4_output | ( | in_Header * | ip,
 |  | DWORD | src_ip,
 |  | DWORD | dst_ip,
 |  | BYTE | protocol,
 |  | BYTE | ttl,
 |  | BYTE | tos,
 |  | WORD | ip_id,
 |  | int | data_len,
 |  | const void * | sock,
 |  | const char * | file,
 |  | unsigned | line
 | ) |

The IP4 packet transmitter.

Return values:
'data_len | + sizeof(*ip)' on success.
0 | on fail.
Todo:
Handle IP-fragments here (call ip4_send_fragments() when needed)
Definition at line 85 of file IP4_OUT.C.

References _default_ttl, _eth_send(), _get_ip4_id(), _ip4_dont_frag, BYTE, in_Header::checksum, in_Header::destination, in_Header::frag_ofs, in_Header::hdrlen, in_Header::identification, in_Header::length, my_ip_addr, in_Header::proto, in_Header::source, in_Header::tos, in_Header::ttl, in_Header::ver, and WORD.

int _ip4_send_fragments | ( | sock_type * | s,
 |  | BYTE | proto,
 |  | DWORD | dest,
 |  | const void * | buf,
 |  | unsigned | len,
 |  | const char * | file,
 |  | unsigned | line
 | ) |

Todo:
Maybe send highest offset fragment first?

support sending raw IPv4 fragments

Definition at line 234 of file IP4_OUT.C.

References _get_ip4_id(), _ip4_output(), BYTE, in_Header::frag_ofs, in_Header::proto, _tcp_Socket::state, sock_type::tcp, tcp_tick(), sock_type::udp, and WORD.

Variable Documentation

BYTE _default_tos

The default type-of-service for IP Definition at line 52 of file IP4_OUT.C.

int _default_ttl

The default time-to-live for IP Definition at line 53 of file IP4_OUT.C.

BOOL _ip4_dont_frag

Enable the IP_DF bit on output Definition at line 55 of file IP4_OUT.C.

int _ip4_id_increment

The IP identifier increment Definition at line 54 of file IP4_OUT.C.

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/IP6_IN.C File Reference

SRC/IP6_IN.C File Reference

Detailed Description

IPv6 input routines.

Definition in file IP6_IN.C.

Go to the source code of this file.

Functions

int | _ip6_handler (const in6_Header *ip, BOOL broadcast)
int | _ip6_is_local_addr (const void *ip)
int | _ip6_is_addr_v4mapped (const void *ip)
int | _ip6_is_addr_loopback (const void *ip)
void | set_my_ip6 (const char *value)
void | ip6_config (const char *name, const char *value)
int | _ip6_init (void)
void | set_default_ip (void)
int | _ip6_pkt_init (void)
void | _ip6_post_init (void)

Variables

WORD | v4_prefix [6] = { 0,0,0,0,0,0xFFFF }
void(* | prev_hook )(const char *, const char *)=NULL

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/IP6_IN.H File Reference

SRC/IP6_IN.H File Reference

Detailed Description

Definition in file IP6_IN.H.

Go to the source code of this file.

Data Structures

struct | ip6_RouteHdr

Typedefs

typedef ip6_RouteHdr | ip6_RouteHdr

Functions

int | _ip6_handler (const in6_Header *ip, BOOL broadcast)
int | _ip6_init (void)
int | _ip6_pkt_init (void)
void | _ip6_post_init (void)
int | _ip6_is_local_addr (const void *ip)

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/IP6_OUT.C File Reference

SRC/IP6_OUT.C File Reference

Detailed Description

IPv6 output routines.

Definition in file IP6_OUT.C.

Go to the source code of this file.

Functions

int | _ip6_output (in6_Header *ip, ip6_address *src_ip, ip6_address *dst_ip, BYTE protocol, unsigned data_len, int hop_lim, const void *sock, const char *file, unsigned line)

Variables

in6_addr | in6addr_my_ip
const struct in6_addr | in6addr_loopback
const struct in6_addr | in6addr_any
const struct in6_addr | in6addr_all_1
const struct in6_addr | in6addr_alln_mc
const struct in6_addr | in6addr_allr_mc
const BYTE | in6addr_mapped [12] = { 0,0,0,0, 0,0,0,0, 0,0,0xFF,0xFF }
int | _default6_ttl = 255

Function Documentation

int _ip6_output | ( | in6_Header * | ip,
 |  | ip6_address * | src_ip,
 |  | ip6_address * | dst_ip,
 |  | BYTE | protocol,
 |  | unsigned | data_len,
 |  | int | hop_lim,
 |  | const void * | sock,
 |  | const char * | file,
 |  | unsigned | line
 | ) |

Todo:
: Support fragments
Definition at line 74 of file IP6_OUT.C.

References _eth_send(), BYTE, ip6_address, and WORD.

Variable Documentation

const struct in6_addr in6addr_all_1

Initial value:

 {{ 0xFF,0xFF,0xFF,0xFF,
                                            0xFF,0xFF,0xFF,0xFF,
                                            0xFF,0xFF,0xFF,0xFF,
                                            0xFF,0xFF,0xFF,0xFF }}
Definition at line 59 of file IP6_OUT.C.

const struct in6_addr in6addr_alln_mc

Initial value:

 {{ 0xFF,2,0,0,0,0,0,0,
                                            0,0,0,0,0,0,0,1 }}
Definition at line 64 of file IP6_OUT.C.

const struct in6_addr in6addr_allr_mc

Initial value:

 {{ 0xFF,2,0,0,0,0,0,0,
                                            0,0,0,0,0,0,0,2 }}
Definition at line 67 of file IP6_OUT.C.

const struct in6_addr in6addr_any

Initial value:

 {{ 0,0,0,0,0,0,0,0,
                                            0,0,0,0,0,0,0,0 }}
Definition at line 57 of file IP6_OUT.C.

const struct in6_addr in6addr_loopback

Initial value:

 {{ 0,0,0,0,0,0,0,0,
                                            0,0,0,0,0,0,0,1 }}
Definition at line 55 of file IP6_OUT.C.

struct in6_addr in6addr_my_ip

Initial value:

 {{ 0,0,0,0,0,0,0,0,
                                   0,0,0,0,0,0,0,0 }}
Definition at line 52 of file IP6_OUT.C.

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/IP6_OUT.H File Reference

SRC/IP6_OUT.H File Reference

Detailed Description

Definition in file IP6_OUT.H.

Go to the source code of this file.

Functions

int | _ip6_output (in6_Header *ip, ip6_address *src_ip, ip6_address *dst_ip, BYTE next_hdr, unsigned data_len, int hop_lim, const void *sock, const char *file, unsigned line)

Variables

W32_DATA struct in6_addr | in6addr_my_ip
const struct in6_addr | in6addr_all_1
const struct in6_addr | in6addr_alln_mc
const struct in6_addr | in6addr_allr_mc
const BYTE | in6addr_mapped [12]
int | _default6_ttl

Function Documentation

int _ip6_output | ( | in6_Header * | ip,
 |  | ip6_address * | src_ip,
 |  | ip6_address * | dst_ip,
 |  | BYTE | protocol,
 |  | unsigned | data_len,
 |  | int | hop_lim,
 |  | const void * | sock,
 |  | const char * | file,
 |  | unsigned | line
 | ) |

Todo:
: Support fragments
Definition at line 74 of file IP6_OUT.C.

References _eth_send(), BYTE, ip6_address, and WORD.

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/LANGUAGE.H File Reference

SRC/LANGUAGE.H File Reference

Detailed Description

Include file for WatTCP foreign language translation facility.

Based on idea from PGP, but totally rewritten (using flex)

Strings with _LANG() around them are found by the `mklang' tool and put into a text file to be translated into foreign language at run-time.

Definition in file LANGUAGE.H.

Go to the source code of this file.

Functions

void | lang_init (const char *value)
const char * | lang_xlate (const char *str)

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/LANGUAGE.L File Reference

SRC/LANGUAGE.L File Reference

Detailed Description

Foreign language lexical scanner for Waterloo TCP/IP.

Gisle Vanem 1997

Definition in file LANGUAGE.L.

Go to the source code of this file.

Functions

const char * | lang_xlate (const char *str)
void | Abort (const char *s1, const char *s2)
Print message and abort program.
void | error (const char *err)
Print error message for current line.
int | main (void)

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/LINKADDR.C File Reference

SRC/LINKADDR.C File Reference

Detailed Description

Definition in file LINKADDR.C.

Go to the source code of this file.

Functions

void | link_addr (const char *addr, struct sockaddr_dl *sdl)
char * | link_ntoa (const struct sockaddr_dl *sdl)

Variables

char | sccsid [] = "@(#)linkaddr.c 8.1 (Berkeley) 6/4/93"

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/LISTEN.C File Reference

SRC/LISTEN.C File Reference

Detailed Description

BSD listen().

Definition in file LISTEN.C.

Go to the source code of this file.

Functions

int W32_CALL | listen (int s, int backlog)
int | main (void)

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/LOOKUP.C File Reference

SRC/LOOKUP.C File Reference

Detailed Description

Host lookup function.

Copyright (c) 1997-2002 Gisle Vanem <giva@bgnett.no>

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. All advertising materials mentioning features or use of this software must display the following acknowledgement: This product includes software developed by Gisle Vanem Bergen, Norway.

THIS SOFTWARE IS PROVIDED BY ME (Gisle Vanem) AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL I OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

Definition in file LOOKUP.C.

Go to the source code of this file.

Functions

DWORD lookup_host (const char *host, char *ip_str)

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/LOOPBACK.C File Reference

SRC/LOOPBACK.C File Reference

Detailed Description

A simple loopback device.

Copyright (c) 1997-2002 Gisle Vanem <giva@bgnett.no>

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. All advertising materials mentioning features or use of this software must display the following acknowledgement: This product includes software developed by Gisle Vanem Bergen, Norway.

THIS SOFTWARE IS PROVIDED BY ME (Gisle Vanem) AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL I OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

----------------------------------------------------------------------------

A simple loopback device. At the moment it handles ICMP Echo-request and UDP sink/discard packets. It pased up the rest.

Add protocol handlers to `loopback_handler' pointer as required.

The modified (src/dst IP swapped) ip packet is enqueued to the IP receive queue after loopback_device() returns.

The return value is: -1 if IP-packet should not be enqueued to IP input queue >0 length of (modified) IP-packet

Gisle Vanem 10 Dec. 1997

Definition in file LOOPBACK.C.

Go to the source code of this file.

Functions

int | loopback_device (in_Header *ip)
int | icmp_loopback (ICMP_PKT *icmp, unsigned icmp_len)
int | udp_loopback (udp_Header *udp, unsigned udp_len)

Variables

WORD | loopback_mode = LBACK_MODE_ENABLE

Function Documentation

int icmp_loopback | ( | ICMP_PKT * | icmp,
 |  | unsigned | icmp_len
 | ) | [static]

Todo:
fall-through to another ICMP loopback handler
Definition at line 213 of file LOOPBACK.C.

References WORD.

int udp_loopback | ( | udp_Header * | udp,
 |  | unsigned | udp_len
 | ) | [static]

Todo:
UDP loopback handler should handle ECHO protocol

UDP loopback handler should handle DISCARD protocol

Definition at line 234 of file LOOPBACK.C.

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/LOOPBACK.H File Reference

SRC/LOOPBACK.H File Reference

Detailed Description

Definition in file LOOPBACK.H.

Go to the source code of this file.

Functions

int | loopback_device (in_Header *)

Variables

WORD | loopback_mode
int(* | loopback_handler )(in_Header *)

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/MISC.C File Reference

SRC/MISC.C File Reference

Detailed Description

Module for various things:
  • host/network order (little/big endian) swapping of bytes.
  • initialise PEEK/POKE macros.
  • allocate transfer buffer for DOSX targets.
  • address validation for DOSX targets.
  • simple range limited random routine.
  • ffs routine to find the first bit set.
  • initialise memory-debugger (Fortify/CrtDbg)
  • stack checker exit routine for Borland/Watcom.

Definition in file MISC.C.

Go to the source code of this file.

Data Structures

struct | on_exit
Register an on-exit function. More...
struct | cmd_block
Run a COMMAND.COM/4DOS external/internal command. More...

Functions

void | setup_dos_xfer_buf (void)
void | is_in_stack_init (void)
STATIC int | setup_stk_check (void)
void cdecl | _fatal_runtime_error (UINT stk)
void cdecl | _fatal_runtime_error_ (UINT stk)
void (__cdecl *_aaltstkovr)(void)
void | stk_overflow (void _far *where)
STATIC void | test_stk_check (void)
unsigned long cdecl | _w32_intel (unsigned long val)
Convert 32-bit big-endian (network order) to intel (host order) format.
unsigned short cdecl | _w32_intel16 (unsigned short val)
Convert 16-bit big-endian (network order) to intel (host order) format.
void | patch_with_bswap (void)
DWORD | get_day_num (void)
Simplified method of getting days since 1970-01-01.
BOOL | RDTSC_enabled (void)
BOOL | check_reg_struct (void)
void | init_misc (void)
Initialise various stuff.
FILE * | fopen_excl (const char *file, const char *mode)
WIN32: Open an existing file (or create) in share-mode but deny other processes to write to the file.
int | list_compare (const struct on_exit *a, const struct on_exit *b)
int | rundown_add (void(*func)(void), const char *name, int order, const char *file, unsigned line)
Register a function to be called from sock_exit().
void | rundown_run (void)
Run the registered and sorted exit_list[] functions.
void | rundown_dump (void)
Dump 'exit_list[]' list.
_CRTIMP _CRT_REPORT_HOOK __cdecl | _CrtSetReportHook2 (int, _CRT_REPORT_HOOK)
void __cdecl | crtdbg_exit (void)
const char * | report_name (int type)
void __cdecl | crtdbg_dump (const void *buf, size_t len)
int __cdecl | crtdbg_report (int type, char *message, int *ret_val)
void | memdbg_init (void)
void | fortify_report (void)
Report routine for Fortify.
void | assert_fail (const char *file, unsigned line, const char *what)
Print an assert fail and store the text for later.
unsigned | Random (unsigned a, unsigned b)
Returns a random integer in range [a..b].
void | RandomWait (unsigned a, unsigned b)
Wait for a random period in range [a..b] millisec.
void | Wait (unsigned msec)
Not all vendors have delay().
const char * | dos_extender_name (void)
void | os_yield (void)
BOOL | watt_check_break (void)
int | watt_kbhit (void)
A less CPU hogging kbhit().
const char * | list_lookup (DWORD type, const struct search_list *list, int num)
Search 'list' for 'type' and return it's name.
const char * | MAC_address (const void *addr)
Return hexa-decimal string for an 6/7 byte MAC-address.
void | unfinished (const char *func, const char *file, unsigned line)
const char * | dword_str (DWORD val)
Return nicely formatted string "xx,xxx,xxx" with thousand separators (left adjusted).
DWORD | get_ds_limit (void)
DWORD | get_cs_limit (void)
DWORD | get_ss_limit (void)
unsigned dj_end | asm ("end")
unsigned | get_frame_size (const char *x)
BOOL | is_in_stack (const void *ptr)
unsigned | used_stack (void)
BOOL | valid_addr (DWORD addr, unsigned len)
void | free_selector (void)
int | _w32_ffs (int i)
void | watt_large_check (const void *sock, int size, const char *file, unsigned line)
int | isbigendian (void)
BOOL | shell_exec (const char *cmd)
BOOL | get_mem_strat (BYTE *strat)
BOOL | set_mem_strat (BYTE strat)
void | _w32_intr (int int_no, IREGS *reg)
Microsoft/Digital Mars doesn't have intr() so we make our own.
STATIC void | stk_overflow (WORD ret_addr)
void | stk_overflow (UINT ret_addr)
int | stk_check_setup (void)
void | stk_overflow (WORD cs, UINT eip)
void | FATAL_HANDLER (UINT stk)
void | foo_10 (void)
void | foo_20 (void)
void | foo_30 (void)
void | foo_40 (void)
void | foo_50 (void)
void | foo_60 (void)
void | foo_70 (void)
int | main (void)

Variables

const char | hex_chars_lower [] = "0123456789abcdef"
const char | hex_chars_upper [] = "0123456789ABCDEF"
BOOL | win32_dos_box = FALSE
BOOL | _watt_fatal_error = FALSE
WORD | _watt_os_ver = 0x622
char | _watt_assert_buf [256]
int | _w32_errno = 0
int | __bss_count = 0
FARPTR | _watt_dosFp
_CPUID | lcc_cpuid
char cdecl | x86_type = 5
char cdecl | x86_vendor_id [13]
DWORD cdecl | x86_capability
char cdecl | __begtext
UINT cdecl | _x386_stacklow
char * | dummy_fatal_rte = (char*)&FATAL_HANDLER
const BYTE | bswap32 []
const BYTE | bswap16 []
on_exit | exit_list [40]
_CrtMemState | last_state
THREADLOCAL const char * | stack_bottom = 0
unsigned | _stklen
unsigned | __djgpp_stack_limit
REALPTR | _watt_dosTbr = 0
DWORD | _watt_dosTbSize = 0
WORD | rm_seg = 0
WORD | _watt_dosTbSeg = 0
WORD | _watt_dosTbSel = 0
WORD | _watt_dos_ds
int | __brklvl

Function Documentation

unsigned long cdecl _w32_intel ( unsigned long val )

Convert 32-bit big-endian (network order) to intel (host order) format.

Or vice-versa. These are cdecl incase we patch them. Definition at line 141 of file MISC.C.

unsigned short cdecl _w32_intel16 ( unsigned short val )

Convert 16-bit big-endian (network order) to intel (host order) format.

Or vice-versa Definition at line 153 of file MISC.C.

int __cdecl crtdbg_report | ( | int | type,
 |  | char * | message,
 |  | int * | ret_val
 | ) | [static]

<

Todo:
make a stack dumper
Definition at line 603 of file MISC.C.

FILE* fopen_excl | ( | const char * | file,
 |  | const char * | mode
 | ) |

WIN32: Open an existing file (or create) in share-mode but deny other processes to write to the file.

On Watcom, fopen() already seems to open with SH_DENYWR internally. DOS/Watcom: simply call fopen(). Definition at line 429 of file MISC.C.

void fortify_report ( void ) [static]

Report routine for Fortify.

Report memory statistics and leaks done in this scope (the core API level). BSD socket API sets it's own scope with reporting done in sock_fortify_exit(). Definition at line 672 of file MISC.C.

DWORD get_day_num ( void )

Simplified method of getting days since 1970-01-01.

Don't use time() since it will probably link in sprintf(). We don't need accuracy. Only a reference for sock_stats(). Definition at line 194 of file MISC.C.

References DWORD.

void init_misc ( void )

Initialise various stuff.

Todo:
Definition at line 318 of file MISC.C.

References _watt_assert_buf, _watt_dosFp, _watt_os_ver, DWORD, has_rdtsc, init_timers(), and win32_dos_box.

const char* MAC_address ( const void * addr )

Return hexa-decimal string for an 6/7 byte MAC-address.

Use 2 buffers in round-robin. Definition at line 905 of file MISC.C.

References _pktdevclass.

Variable Documentation

char _watt_assert_buf[256]

Print this in dbug_exit() Definition at line 55 of file MISC.C.

FARPTR _watt_dosFp

Todo:
detect program restarts
Definition at line 67 of file MISC.C.

BOOL _watt_fatal_error = FALSE

We're exiting via an exception handler Definition at line 53 of file MISC.C.

WORD _watt_os_ver = 0x622

True DOS/WinNT version MSB.LSB Definition at line 54 of file MISC.C.

const BYTE bswap16[] [static]

Initial value:

 {
             0x8B,0x44,0x24,0x04,
             0x0F,0xC8,
             0xC1,0xE8,0x10,
             0xC3
           }
Definition at line 165 of file MISC.C.

const BYTE bswap32[] [static]

Initial value:

 {
             0x8B,0x44,0x24,0x04,
             0x0F,0xC8,
             0xC3
           }
Definition at line 159 of file MISC.C.

BOOL win32_dos_box = FALSE

Running under Windows DOS-box Definition at line 52 of file MISC.C.

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/MISC.H File Reference

SRC/MISC.H File Reference

Detailed Description

Definition in file MISC.H.

Go to the source code of this file.

Data Structures

struct | search_list
struct | DPMI_regs
struct | IREGS

Typedefs

typedef DPMI_regs | IREGS
typedef INTR_PROTOTYPE(* | W32_IntrHandler )()

Functions

W32_FUNC void | init_misc (void)
Initialise various stuff.
W32_FUNC unsigned | Random (unsigned a, unsigned b)
Returns a random integer in range [a..b].
W32_FUNC void | RandomWait (unsigned msec_a, unsigned msec_b)
Wait for a random period in range [a..b] millisec.
W32_FUNC void | Wait (unsigned msec)
Not all vendors have delay().
W32_FUNC BOOL | valid_addr (DWORD addr, unsigned len)
W32_FUNC BOOL | is_in_stack (const void *ptr)
W32_FUNC unsigned | used_stack (void)
W32_FUNC void | os_yield (void)
W32_FUNC BOOL | watt_kbhit (void)
A less CPU hogging kbhit().
DWORD | get_day_num (void)
Simplified method of getting days since 1970-01-01.
BOOL | shell_exec (const char *cmd)
BOOL | get_mem_strat (BYTE *strat)
BOOL | set_mem_strat (BYTE strat)
void | memdbg_init (void)
int | rundown_add (void(*func)(void), const char *name, int order, const char *file, unsigned line)
Register a function to be called from sock_exit().
void | rundown_run (void)
Run the registered and sorted exit_list[] functions.
void | rundown_dump (void)
Dump 'exit_list[]' list.
FILE * | fopen_excl (const char *file, const char *mode)
WIN32: Open an existing file (or create) in share-mode but deny other processes to write to the file.
const char * | dos_extender_name (void)
void | assert_fail (const char *file, unsigned line, const char *what)
Print an assert fail and store the text for later.
const char * | dword_str (DWORD val)
Return nicely formatted string "xx,xxx,xxx" with thousand separators (left adjusted).
const char * | list_lookup (DWORD, const struct search_list *, int)
Search 'list' for 'type' and return it's name.
const char * | MAC_address (const void *addr)
Return hexa-decimal string for an 6/7 byte MAC-address.
void | unfinished (const char *func, const char *file, unsigned line)
void | watt_large_check (const void *sock, int size, const char *file, unsigned line)
BOOL | init_winmisc (void)
char * | win_strerror (DWORD err)
void | assert_fail_win (const char *file, unsigned line, const char *what)
BOOL | WinDnsQuery_A4 (const char *name, DWORD *ip4)
BOOL | WinDnsQuery_A6 (const char *name, void *ip6)
BOOL | WinDnsQuery_PTR4 (DWORD ip4, char *name, size_t size)
BOOL | WinDnsQuery_PTR6 (const void *ip6, char *name, size_t size)
BOOL | WinDnsCachePut_A4 (const char *name, DWORD ip4)
BOOL | WinDnsCachePut_A6 (const char *name, const void *ip6)
W32_FUNC int | tcp_cbreak (int mode)
Sets our break mode.
int | set_cbreak (int want_brk)
Sets normal and extended BREAK mode.
void MS_CDECL | sig_handler_watt (int sig)
SIGINT/SIGBREAK handler function.
int | GetCountryCode (void)
int | GetCodePage (void)
void | int24_init (void)
void | int24_restore (void)
void | dputch (char x)
void | dmsg (const char *s)
void | dhex1int (int x)
void | dhex2int (int x)
void | dhex4int (int x)
void | dhex8int (DWORD x)
W32_FUNC const char * | wattcpVersion (void)
W32_FUNC const char * | wattcpCapabilities (void)
BOOL | crc_init (void)
DWORD | crc_bytes (const char *buf, unsigned len)
const char * | short_strerror (int errnum)
void | intr (int int_no, IREGS *regs)
void | STACK_SET (void far *stack)
void | STACK_RESTORE (void)
void | PUSHF_CLI (void)
void | POPF (void)
void | STACK_SET (void *stack)
WORD | watcom_MY_CS (void)
WORD | watcom_MY_DS (void)
DWORD | GET_LIMIT (WORD sel)
DWORD | get_ds_limit (void)
DWORD | get_cs_limit (void)
DWORD | get_ss_limit (void)
typedef | void (cdecl interrupt *W32_IntrHandler)()
__inline__ WORD | get_fs_reg (void)
__inline__ WORD | get_gs_reg (void)
__inline__ void | set_fs_reg (WORD sel)
__inline__ void | set_gs_reg (WORD sel)
char * | strupr (char *)
char * | strlwr (char *)
char * | strdup (const char *)
int | stricmp (const char *, const char *)
int | strnicmp (const char *, const char *, size_t)
char * | itoa (int, char *, int)
void * | alloca (size_t)
int | gettimeofday (struct timeval *, struct timezone *)
int | fileno (FILE *)
int | isascii (int)
void | psignal (int, const char *)
int | vsscanf (const char *, const char *, va_list)

Variables

W32_DATA int | __bss_count
W32_DATA BOOL | win32_dos_box
W32_DATA BOOL | _watt_fatal_error
W32_DATA WORD | _watt_os_ver
W32_DATA char | _watt_assert_buf [256]
const char | hex_chars_lower []
const char | hex_chars_upper []
BOOL | _watt_is_win9x
W32_DATA WORD | _watt_handle_cbreak
W32_DATA volatile int | _watt_cbroke
BYTE | dbg_colour
WORD | dbg_scrpos
WORD | dbg_scrstart
W32_DATA const char * | wattcpCopyright
int | pull_neterr_module

Function Documentation

FILE* fopen_excl | ( | const char * | file,
 |  | const char * | mode
 | ) |

WIN32: Open an existing file (or create) in share-mode but deny other processes to write to the file.

On Watcom, fopen() already seems to open with SH_DENYWR internally. DOS/Watcom: simply call fopen(). Definition at line 429 of file MISC.C.

DWORD get_day_num ( void )

Simplified method of getting days since 1970-01-01.

Don't use time() since it will probably link in sprintf(). We don't need accuracy. Only a reference for sock_stats(). Definition at line 194 of file MISC.C.

References DWORD.

W32_FUNC void init_misc ( void )

Initialise various stuff.

Todo:
Definition at line 318 of file MISC.C.

const char* MAC_address ( const void * addr )

Return hexa-decimal string for an 6/7 byte MAC-address.

Use 2 buffers in round-robin. Definition at line 905 of file MISC.C.

References _pktdevclass.

int set_cbreak ( int want_brk )

Sets normal and extended BREAK mode.

  • want_brk 0x0000: no ^BREAK checking.
  • want_brk 0x0001: normal ^BREAK checks.
  • want_brk 0x0101: extended ^BREAK checks.
Return values:
normal BREAK state in LSB, extended BREAK state in MSB.
Definition at line 110 of file PC_CBRK.C.

References WORD.

W32_FUNC int tcp_cbreak ( int mode )

Sets our break mode.

  • `mode' is composed of the following flags
    • 0x01: disallow breakouts
    • 0x10: display a message upon ^C/^BREAK (default)
Definition at line 172 of file PC_CBRK.C.

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/NETADDR.C File Reference

SRC/NETADDR.C File Reference

Detailed Description

Provide some more BSD address functions. Gisle Vanem, Oct 12, 1995

inet_network() is Copyright (c) 1983, 1993 The Regents of the University of California. All rights reserved.

Version:
v0.0
Date:
Jan 11, 1991
Author:
E. Engelke
Version:
v0.2
Date:
Apr 10, 1995
Author:
G. Vanem, function priv_addr()
Version:
v0.3
Date:
Nov 12, 2003
Author:
G. Vanem, some functions moved from now obsolete udp_nds.c.

Definition in file NETADDR.C.

Go to the source code of this file.

Functions

char * | _inet_ntoa (char *s, DWORD ip)
Convert an IP-address 'ip' into a string.
DWORD | _inet_addr (const char *s)
Convert a string into an IP-address.
DWORD | aton (const char *str)
Converts [a.b.c.d] or a.b.c.d to 32 bit IPv4 address.
DWORD | aton_dotless (const char *str)
Converts `[dotless]' or `dotless' to 32 bit long (host order).
BOOL | isaddr (const char *str)
Check if 'str' is simply an ip address.
BOOL | isaddr_dotless (const char *str, DWORD *ip)
Check if 'str' is a dotless ip address.
char *W32_CALL | inet_ntoa (struct in_addr addr)
const char * | _inet_atoeth (const char *src, eth_address *p_eth)
Parse string "ether-addr, ip-addr".
char *W32_CALL | inet_ntoa_r (struct in_addr addr, char *buf, int buflen)
int W32_CALL | inet_aton (const char *name, struct in_addr *addr)
u_long W32_CALL | inet_addr (const char *addr)
u_long W32_CALL | inet_network (const char *name)
u_int32_t W32_CALL | inet_netof (struct in_addr addr)
Return the network number from an internet address; handles class A/B/C network #'s.
u_long W32_CALL | inet_lnaof (struct in_addr addr)
Return the local network address portion of an internet address; handles class A/B/C network number formats only.
in_addr W32_CALL | inet_makeaddr (u_long net, u_long host)
Formulate an Internet address from network + host (with subnet address).
const char * | _inet6_ntoa (const void *ip)
Convert an IPv6-address 'ip' into a string.
const ip6_address * | _inet6_addr (const char *str)
Convert a string 'str' into an IPv6-address.
BOOL | priv_addr (DWORD ip)
int | check_mask (DWORD mask)
int | check_mask2 (const char *mask)

Function Documentation

const ip6_address* _inet6_addr ( const char * str )

Convert a string 'str' into an IPv6-address.

Return values:
static | buffer for address.
NULL | 'str' isn't a valid IPv6 address.
Definition at line 410 of file NETADDR.C.

References inet_pton(), and ip6_address.

const char* _inet6_ntoa ( const void * ip )

Convert an IPv6-address 'ip' into a string.

Return values:
static string.
Warning:
Not reentrant.
Definition at line 392 of file NETADDR.C.

References inet_ntop().

DWORD _inet_addr ( const char * s )

Convert a string into an IP-address.

Return values:
address | on host order.
0 | string isn't a (dotless) address.
Definition at line 65 of file NETADDR.C.

References aton(), DWORD, isaddr(), and isaddr_dotless().

const char* _inet_atoeth | ( | const char * | src,
 |  | eth_address * | p_eth
 | ) |

Parse string "ether-addr, ip-addr".

DOSX == 0: Assumes 'src' contain only legal hex-codes and ':' separators. Doesn't waste precious memory using sscanf() if DOSX==0.

Read 'src', dump to ethernet buffer ('*p_eth') and return pointer to "ip-addr". Definition at line 201 of file NETADDR.C.

References atox(), BYTE, eth_address, and strltrim().

char* _inet_ntoa | ( | char * | s,
 |  | DWORD | ip
 | ) |

Convert an IP-address 'ip' into a string.

Return values:
's'.
Note:
'ip' is on host order.
Definition at line 40 of file NETADDR.C.

DWORD aton ( const char * str )

Converts [a.b.c.d] or a.b.c.d to 32 bit IPv4 address.

Return values:
0 | on error (safer than -1)
IPv4 | address (host order)
Definition at line 82 of file NETADDR.C.

References DWORD.

DWORD aton_dotless ( const char * str )

Converts `[dotless]' or `dotless' to 32 bit long (host order).

Return values:
0 on error (safer than -1)
Definition at line 111 of file NETADDR.C.

References DWORD, and isaddr_dotless().

u_long W32_CALL inet_lnaof ( struct in_addr addr )

Return the local network address portion of an internet address; handles class A/B/C network number formats only.

Note:
return value is host-order.
Definition at line 351 of file NETADDR.C.

struct in_addr W32_CALL inet_makeaddr | ( | u_long | net,
 |  | u_long | host
 | ) |

Formulate an Internet address from network + host (with subnet address).

Note:
'net' is on host-order.
Definition at line 368 of file NETADDR.C.

References inet_makeaddr().

BOOL isaddr ( const char * str )

Check if 'str' is simply an ip address.

Accepts 'a.b.c.d' or '[a.b.c.d]' forms.

Return values:
TRUE if 'str' is an IPv4 address.
Definition at line 124 of file NETADDR.C.

BOOL isaddr_dotless | ( | const char * | str,
 |  | DWORD * | ip
 | ) |

Check if 'str' is a dotless ip address.

Accept "[ 0-9\[\]]+". Doesn't accept octal base.

Return values:
TRUE if 'str' is a dotless address.
Definition at line 144 of file NETADDR.C.

References DWORD.

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/NETADDR.H File Reference

SRC/NETADDR.H File Reference

Detailed Description

Definition in file NETADDR.H.

Go to the source code of this file.

Functions

W32_FUNC DWORD | aton (const char *str)
Converts [a.b.c.d] or a.b.c.d to 32 bit IPv4 address.
W32_FUNC BOOL | isaddr (const char *text)
Check if 'str' is simply an ip address.
W32_FUNC int | priv_addr (DWORD ip)
W32_FUNC DWORD | aton_dotless (const char *str)
Converts `[dotless]' or `dotless' to 32 bit long (host order).
W32_FUNC BOOL | isaddr_dotless (const char *str, DWORD *ip)
Check if 'str' is a dotless ip address.
W32_FUNC char * | _inet_ntoa (char *s, DWORD x)
Convert an IP-address 'ip' into a string.
W32_FUNC DWORD | _inet_addr (const char *s)
Convert a string into an IP-address.
W32_FUNC const char * | _inet_atoeth (const char *src, eth_address *eth)
Parse string "ether-addr, ip-addr".
W32_FUNC const char * | _inet6_ntoa (const void *ip)
Convert an IPv6-address 'ip' into a string.
W32_FUNC const ip6_address * | _inet6_addr (const char *str)
Convert a string 'str' into an IPv6-address.

Function Documentation

W32_FUNC const ip6_address* _inet6_addr ( const char * str )

Convert a string 'str' into an IPv6-address.

Return values:
static | buffer for address.
NULL | 'str' isn't a valid IPv6 address.
Definition at line 410 of file NETADDR.C.

References inet_pton(), and ip6_address.

W32_FUNC const char* _inet6_ntoa ( const void * ip )

Convert an IPv6-address 'ip' into a string.

Return values:
static string.
Warning:
Not reentrant.
Definition at line 392 of file NETADDR.C.

References inet_ntop().

W32_FUNC DWORD _inet_addr ( const char * s )

Convert a string into an IP-address.

Return values:
address | on host order.
0 | string isn't a (dotless) address.
Definition at line 65 of file NETADDR.C.

W32_FUNC const char* _inet_atoeth | ( | const char * | src,
 |  | eth_address * | p_eth
 | ) |

Parse string "ether-addr, ip-addr".

DOSX == 0: Assumes 'src' contain only legal hex-codes and ':' separators. Doesn't waste precious memory using sscanf() if DOSX==0.

Read 'src', dump to ethernet buffer ('*p_eth') and return pointer to "ip-addr". Definition at line 201 of file NETADDR.C.

References atox(), BYTE, eth_address, and strltrim().

W32_FUNC char* _inet_ntoa | ( | char * | s,
 |  | DWORD | ip
 | ) |

Convert an IP-address 'ip' into a string.

Return values:
's'.
Note:
'ip' is on host order.
Definition at line 40 of file NETADDR.C.

W32_FUNC DWORD aton ( const char * str )

Converts [a.b.c.d] or a.b.c.d to 32 bit IPv4 address.

Return values:
0 | on error (safer than -1)
IPv4 | address (host order)
Definition at line 82 of file NETADDR.C.

W32_FUNC DWORD aton_dotless ( const char * str )

Converts `[dotless]' or `dotless' to 32 bit long (host order).

Return values:
0 on error (safer than -1)
Definition at line 111 of file NETADDR.C.

References DWORD, and isaddr_dotless().

W32_FUNC BOOL isaddr ( const char * str )

Check if 'str' is simply an ip address.

Accepts 'a.b.c.d' or '[a.b.c.d]' forms.

Return values:
TRUE if 'str' is an IPv4 address.
Definition at line 124 of file NETADDR.C.

W32_FUNC BOOL isaddr_dotless | ( | const char * | str,
 |  | DWORD * | ip
 | ) |

Check if 'str' is a dotless ip address.

Accept "[ 0-9\[\]]+". Doesn't accept octal base.

Return values:
TRUE if 'str' is a dotless address.
Definition at line 144 of file NETADDR.C.

References DWORD.

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/NETBACK.C File Reference

SRC/NETBACK.C File Reference

Detailed Description

Deprecated:
Background ISR.

Definition in file NETBACK.C.

Go to the source code of this file.

Functions

void | backgroundon (void)
INTR_PROTOTYPE | newinterrupt (void)
void | backgroundoff (void)
void | backgroundfn (void(*fn)(void))

Variables

void(* | user_routine )(void)=NULL
int | inside = 0
W32_IntrHandler | oldinterrupt

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/NETERR.C File Reference

SRC/NETERR.C File Reference

Detailed Description

sys_errlist[] with BSD-socket support.

Copyright (c) 1997-2002 Gisle Vanem <giva@bgnett.no>

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. All advertising materials mentioning features or use of this software must display the following acknowledgement: This product includes software developed by Gisle Vanem Bergen, Norway.

THIS SOFTWARE IS PROVIDED BY ME (Gisle Vanem) AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL I OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

05.jan 1998 (GV) - Created

This module tries to add network related errno/strerror/perror for all supported Watt-32 targets.

Definition in file NETERR.C.

Go to the source code of this file.

Functions

void MS_CDECL | perror (const char *str)
char *MS_CDECL | strerror (int errnum)
int __stdcall | WSAGetLastError (void)
void __stdcall | WSASetLastError (int err)
const char * | short_strerror (int errnum)
char * | strerror_s (int err) ALIAS(strerror)
void | perror_s (const char *str)

Variables

char | __syserr00 [] = "No Error"
char | __syserr37 [] = "No Error"
int | pull_neterr_module = 0
int | _w32_sys_nerr = 120
int * | _sys_nerr_dll = &_w32_sys_nerr
int * | _imp___sys_nerr = &_w32_sys_nerr
int DATA_MOD | SYS_NERR = DIM(SYS_ERRLIST)

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/NETTIME.C File Reference

SRC/NETTIME.C File Reference

Detailed Description

Counts user/system time.

Definition in file NETTIME.C.

Go to the source code of this file.

Functions

void | _sock_start_timer (void)
void | _sock_stop_timer (void)
DWORD | sys_time (void)
DWORD | usr_time (void)
unsigned long | net_times (struct tms *tms)

Variables

DWORD | sock_sys_time
DWORD | start

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/NOCHKSTK.H File Reference

SRC/NOCHKSTK.H File Reference

Detailed Description

pragmas to disable stack-checking

Definition in file NOCHKSTK.H.

Go to the source code of this file.

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/NSAPADDR.C File Reference

SRC/NSAPADDR.C File Reference

Detailed Description

inet_nsap_addr(), inet_nsap_ntoa().

Definition in file NSAPADDR.C.

Go to the source code of this file.

Functions

__inline char | xtob (int c)
u_int W32_CALL | inet_nsap_addr (const char *ascii, u_char *binary, int maxlen)
char *W32_CALL | inet_nsap_ntoa (int binlen, const u_char *binary, char *ascii)

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/OLDSTUFF.C File Reference

SRC/OLDSTUFF.C File Reference

Detailed Description

Some old functions are collected here.

Definition in file OLDSTUFF.C.

Go to the source code of this file.

Functions

int | tcp_cbrk (int mode)
unsigned long | set_ttimeout (unsigned ticks)
void | psocket (const sock_type *s)
void | sock_sturdy (sock_type *s, int level)
Keep the socket open inspite of receiving "ICMP Unreachable" For UDP or TCP socket.
int | resolve_ip (DWORD ip, char *name, size_t len)
Resolve an IP-address to a name.
time_t | dostounix (struct date *d, struct time *t)
void | unixtodos (time_t time, struct date *d, struct time *t)
WORD | inchksum (const void *ptr, int len)
WORD | _w32_inchksum (const void *ptr, int len)
DWORD | intel (DWORD val)
WORD | intel16 (WORD val)
int | main (void)

Function Documentation

unsigned long set_ttimeout ( unsigned ticks )

Deprecated:
Not needed in Watt-32. Return timeout from ticks.
Definition at line 34 of file OLDSTUFF.C.

References DWORD, has_8254, and set_timeout().

int tcp_cbrk ( int mode )

Deprecated:
Actually simply a macro in <tcp.h>
Definition at line 25 of file OLDSTUFF.C.

References tcp_cbreak().

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/PC_CBRK.C File Reference

SRC/PC_CBRK.C File Reference

Detailed Description

Ctrl-C, Ctrl-Break handling.

Definition in file PC_CBRK.C.

Go to the source code of this file.

Functions

pragma | Alias (_mwstack_limit,"_mwstack_limit")
void MS_CDECL | sig_handler_watt (int sig)
SIGINT/SIGBREAK handler function.
int | set_cbreak (int want_brk)
Sets normal and extended BREAK mode.
int | tcp_cbreak (int mode)
Sets our break mode.
void | usage (char *argv0)
int | main (int argc, char **argv)

Variables

UINT | _mwstack_limit [2]
WORD | _watt_handle_cbreak = 0
Turn off stack-checking here because stack may be out of bounds.
volatile int | _watt_cbroke = 0
int | cbreak_mode
jmp_buf | sig_jmp
int | old_brk = -1

Function Documentation

int set_cbreak ( int want_brk )

Sets normal and extended BREAK mode.

  • want_brk 0x0000: no ^BREAK checking.
  • want_brk 0x0001: normal ^BREAK checks.
  • want_brk 0x0101: extended ^BREAK checks.
Return values:
normal BREAK state in LSB, extended BREAK state in MSB.
Definition at line 110 of file PC_CBRK.C.

References WORD.

int tcp_cbreak ( int mode )

Sets our break mode.

  • `mode' is composed of the following flags
    • 0x01: disallow breakouts
    • 0x10: display a message upon ^C/^BREAK (default)
Definition at line 172 of file PC_CBRK.C.

References set_cbreak(), sig_handler_watt(), sock_sig_exit(), and win32_dos_box.

Variable Documentation

volatile int _watt_cbroke = 0

increment on SIGINT catch Definition at line 47 of file PC_CBRK.C.

WORD _watt_handle_cbreak = 0

Turn off stack-checking here because stack may be out of bounds.

changes operation of the break stuff Definition at line 46 of file PC_CBRK.C.

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/PCARP.C File Reference

SRC/PCARP.C File Reference

Detailed Description

Address Resolution Protocol.

2002-09 Gundolf von Bachhaus: 90% rewrite - Optional non-blocking ARP lookup & redirect handling Gateway / Route / ARP data stored & accessed sererately Module encapsulated - no global variables

Definition in file PCARP.C.

Go to the source code of this file.

Data Structures

struct | route_entry
ROUTE (& REDIRECT) HANDLING. More...

Functions

BOOL | LAN_lookup (DWORD ip, eth_address *eth)
Lookup host in fixed/dynamic list.
BOOL | is_on_LAN (DWORD ip)
This should probably go in pcconfig.c.
void | arp_daemon (void)
ARP "background" daemon.
int | _arp_list_gateways (struct gate_entry *gw, int max)
Gateway functions.
int | ping_gateway (DWORD host, void *eth)
void | check_dead_gw (void)
BOOL | _arp_add_gateway (const char *config_string, DWORD ip)
Add a gateway to the routing table.
void | _arp_kill_gateways (void)
Delete all gateways.
BOOL | _arp_have_default_gw (void)
Check if we have at least one default gateway.
__inline BOOL | arp_send (const arp_Header *arp, unsigned line)
Low-level ARP send function.
BOOL | arp_send_request (DWORD ip)
Send broadcast ARP request.
BOOL | _arp_reply (const void *mac_dst, DWORD src_ip, DWORD dst_ip)
Send unicast/broadcast ARP reply.
__inline void | arp_move_entry (int to_index, int from_index)
Move an ARP entry from from_index to to_index.
BOOL | LAN_start_lookup (DWORD ip)
Start a host lookup on the LAN.
BOOL | LAN_lookup_pending (DWORD ip)
Lookup host in pending list.
void | arp_check_timeouts (BOOL check_dynamic_entries)
Check ARP entries for timeout.
__inline void | route_move_entry (int to_index, int from_index)
BOOL | route_makeNewSlot (DWORD host_ip, DWORD gate_ip)
BOOL | _arp_register (DWORD use_this_gateway_ip, DWORD for_this_host_ip)
ICMP redirection.
BOOL | route_lookup (DWORD host_ip, eth_address *eth)
Gets MAC of gateway needed to reach the given host.
BOOL | route_lookup_pending (DWORD host_ip)
Returns TRUE if the lookup of the gateway (assigned to the supplied host) is still pending.
BOOL | route_start_lookup (DWORD host_ip)
Start a route lookup.
void | route_check_timeouts (BOOL check_dynamic_entries)
Periodic route checker.
BOOL | arp_start_lookup (DWORD ip)
New non-blocking functions, GvB 2002-09.
BOOL | arp_lookup (DWORD ip, eth_address *eth)
Lookup MAC-address of 'ip'.
BOOL | arp_lookup_pending (DWORD ip)
An ARP-lookup timeout check.
BOOL | arp_lookup_fixed (DWORD ip, eth_address *eth)
Lookup fixed MAC-address of 'ip'.
BOOL | _arp_resolve (DWORD ip, eth_address *eth)
Blocking ARP resolve functions.
BOOL | _arp_add_cache (DWORD ip, const void *eth, BOOL expires)
ARP cache functions.
BOOL | _arp_delete_cache (DWORD ip)
Delete given 'ip' address from ARP-cache (dynamic or fixed).
void | arp_parse (const char *name, const char *value)
void | arp_alloc (void)
void | _arp_init (void)
'Internal' interface to pctcp.c & others.
BOOL | _arp_handler (const arp_Header *ah, BOOL brdcast)
Receive ARP handler.
BOOL | _arp_check_own_ip (eth_address *other_guy)
Used by DHCP initialisation.
int | _arp_list_cache (struct arp_entry *arp, int max)
Return contents of ARP cache.
BOOL | _arp_check_gateways (void)
Check for multiple default gateways.
void | _arp_debug_dump (void)
Debug-dump of configured gateways, route table and ARP cache.

Variables

int(* | _sarp_recv_hook )(const struct sarp_Packet *)=NULL
int(* | _sarp_xmit_hook )(struct sarp_Packet *)=NULL
int | arp_timeout = 2
int | arp_alive = 300
int | arp_rexmit_to = 250
int | arp_num_cache = 64
BOOL | dead_gw_detect = FALSE
BOOL | arp_gratiotous = FALSE
int | gate_top = 0
gate_entry | gate_list [gate_top_of_cache]
WORD | icmp_id = 0
Send a ping (with ttl=1) to a gateway.
WORD | icmp_seq = 0
int | arp_first_pending = arp_top_pending
int | arp_first_free = 0
int | arp_first_dynamic = 0
arp_entry | arp_list [arp_top_of_cache]
int | route_first_pending = route_top_pending
int | route_first_free = 0
route_entry | route_list [route_top_of_cache]
void(* | prev_cfg_hook )(const char *, const char *)
Parser for "\c ARP.xx" keywords in "\c WATTCP.CFG".
void(* | prev_post_hook )(void)

Function Documentation

BOOL _arp_add_cache | ( | DWORD | ip,
 |  | const void * | eth,
 |  | BOOL | expires
 | ) |

ARP cache functions.

Note:
'ip' is on host order.
Definition at line 1206 of file PCARP.C.

References _arp_delete_cache(), arp_move_entry(), arp_entry::ip, is_on_LAN(), my_ip_addr, and set_timeout().

BOOL _arp_add_gateway | ( | const char * | config_string,
 |  | DWORD | ip
 | ) |

Add a gateway to the routing table.

The format of 'config_string' is: IP-address [, subnet] , mask]]

If 'config_string' is NULL, simply add 'ip' with zero mask and subnet. Definition at line 188 of file PCARP.C.

References aton(), DWORD, and gate_entry::gate_ip.

BOOL _arp_check_gateways ( void )

Check for multiple default gateways.

Return FALSE if we have none or more than 1. Definition at line 1614 of file PCARP.C.

References _arp_reply(), my_ip_addr, and gate_entry::subnet.

BOOL _arp_check_own_ip ( eth_address * other_guy )

Used by DHCP initialisation.

Do an ARP resolve on our own IP address to check if someone else is replying. Return non-zero if someone replied.

Note:
Blocks waiting for reply or timeout.
Definition at line 1564 of file PCARP.C.

References _arp_resolve(), DWORD, eth_address, and my_ip_addr.

void _arp_debug_dump ( void )

Debug-dump of configured gateways, route table and ARP cache.

Redone + moved here from pcdbug.c for encapsulation reasons GvB 2002-09 Definition at line 1641 of file PCARP.C.

References _inet_ntoa(), DWORD, MAC_address(), set_timeout(), and sin_mask.

BOOL _arp_delete_cache ( DWORD ip )

Delete given 'ip' address from ARP-cache (dynamic or fixed).

Note:
'ip' is on host order.
Definition at line 1270 of file PCARP.C.

References arp_move_entry(), arp_entry::flags, and arp_entry::ip.

BOOL _arp_handler | ( | const arp_Header * | ah,
 |  | BOOL | brdcast
 | ) |

Receive ARP handler.

This processes incoming 'raw' ARP packets supplied by tcp_tick(). Definition at line 1421 of file PCARP.C.

References _arp_add_cache(), _arp_reply(), _eth_addr, _eth_brdcast, _eth_get_hwtype(), _eth_mac_len, _inet_ntoa(), _pkt_rxmode, arp_move_entry(), arp_Header::dstIPAddr, DWORD, eth_address, arp_entry::expiry, arp_entry::flags, arp_Header::hwAddrLen, arp_Header::hwType, arp_entry::ip, MAC_address(), my_ip_addr, arp_Header::opcode, arp_Header::protoAddrLen, arp_Header::protType, RXMODE_BROADCAST, set_timeout(), arp_Header::srcEthAddr, arp_Header::srcIPAddr, and WORD.

int _arp_list_cache | ( | struct arp_entry * | arp,
 |  | int | max
 | ) |

Return contents of ARP cache.

'max' entries are returned in 'arp[]' buffers. Only entries in-use are returned. Definition at line 1590 of file PCARP.C.

References eth_address, arp_entry::expiry, arp_entry::flags, arp_entry::hardware, and arp_entry::ip.

int _arp_list_gateways | ( | struct gate_entry * | gw,
 |  | int | max
 | ) |

Gateway functions.

Note:
Max 'num' gateways is returned in 'gw[]' buffer.
Definition at line 80 of file PCARP.C.

References gate_entry::echo_pending, gate_entry::gate_ip, gate_entry::is_dead, gate_entry::mask, and gate_entry::subnet.

BOOL _arp_register | ( | DWORD | use_this_gateway_ip,
 |  | DWORD | for_this_host_ip
 | ) |

ICMP redirection.

Called on ICMP-redirects.

Redirects are sent from a gateway/router, telling us that a different gateway is better suited to connect to the specified host than the one we were using. Definition at line 727 of file PCARP.C.

References route_entry::gate_ip, is_on_LAN(), LAN_lookup(), and LAN_start_lookup().

BOOL _arp_reply | ( | const void * | mac_dst,
 |  | DWORD | src_ip,
 |  | DWORD | dst_ip
 | ) |

Send unicast/broadcast ARP reply.

'src_ip' and 'dst_ip' on network order. Definition at line 418 of file PCARP.C.

References _eth_addr, _eth_brdcast, _eth_formatpacket(), _eth_get_hwtype(), arp_send(), arp_Header::dstEthAddr, arp_Header::dstIPAddr, arp_Header::hwAddrLen, arp_Header::hwType, arp_Header::opcode, arp_Header::protoAddrLen, arp_Header::protType, arp_Header::srcEthAddr, and arp_Header::srcIPAddr.

BOOL _arp_resolve | ( | DWORD | ina,
 |  | eth_address * | eth
 | ) |

Blocking ARP resolve functions.

Doesn't return until success or time-out. Definition at line 1117 of file PCARP.C.

References _eth_addr, _pktserial, arp_daemon(), DWORD, eth_address, is_on_LAN(), LAN_lookup(), LAN_lookup_pending(), LAN_start_lookup(), route_lookup(), route_lookup_pending(), route_start_lookup(), tcp_tick(), and WORD.

void arp_check_timeouts ( BOOL check_dynamic_entries ) [static]

Check ARP entries for timeout.

This function runs through the 'pending' section of the ARP table and checks for entries that have either expired or require a re-send. The 'dynamic' entries are checked for expiry if requested. Definition at line 560 of file PCARP.C.

References arp_move_entry(), arp_send_request(), chk_timeout(), arp_entry::flags, and set_timeout().

void arp_daemon ( void ) [static]

ARP "background" daemon.

Calls timeout-checks / retransmitters.

We don't check the dynamic entries for a timeout on every call, once a second is plenty enough. Definition at line 1332 of file PCARP.C.

References _arp_have_default_gw(), arp_check_timeouts(), chk_timeout(), DWORD, route_check_timeouts(), and set_timeout().

BOOL arp_lookup | ( | DWORD | ip,
 |  | eth_address * | eth
 | ) |

Lookup MAC-address of 'ip'.

Return values:
TRUE MAC for 'ip' is known.
Definition at line 1038 of file PCARP.C.

References _eth_addr, _pktserial, eth_address, is_on_LAN(), LAN_lookup(), and route_lookup().

BOOL arp_lookup_fixed | ( | DWORD | ip,
 |  | eth_address * | eth
 | ) |

Lookup fixed MAC-address of 'ip'.

Return values:
TRUE Supplied 'ip' has a fixed MAC entry.
Definition at line 1083 of file PCARP.C.

References _pktserial, eth_address, arp_entry::ip, and is_on_LAN().

BOOL arp_lookup_pending ( DWORD ip )

An ARP-lookup timeout check.

Return values:
TRUE | The lookup is currently underway ("pending").
FALSE | The IP has either been resolved (arp_lookup() == TRUE), or the lookup has timed out, i.e. the host is unreachable.
Definition at line 1070 of file PCARP.C.

References is_on_LAN(), LAN_lookup_pending(), and route_lookup_pending().

BOOL arp_start_lookup ( DWORD ip )

New non-blocking functions, GvB 2002-09.

This is called by 'higher' routines to start an ARP request. This function is non-blocking, i.e. returns 'immediately'. Definition at line 1021 of file PCARP.C.

References _pktserial, is_on_LAN(), LAN_start_lookup(), and route_start_lookup().

BOOL LAN_start_lookup ( DWORD ip ) [static]

Start a host lookup on the LAN.

This is called by 'higher' routines to start an ARP request. This function is non-blocking, i.e. returns 'immediately'. Definition at line 455 of file PCARP.C.

References arp_send_request(), arp_entry::ip, and set_timeout().

void route_check_timeouts ( BOOL check_dynamic_entries ) [static]

Periodic route checker.

Run through all pending entries and check if an attempt to reach a gateway was successfull, or has timed-out. If the attempt timed-out, we try the next fitting gateway. If there are no more fitting gateways to try, the connect has failed Definition at line 902 of file PCARP.C.

References gate_entry::gate_ip, is_on_LAN(), LAN_lookup(), LAN_lookup_pending(), and LAN_start_lookup().

Variable Documentation

WORD icmp_id = 0 [static]

Send a ping (with ttl=1) to a gateway.

Ref. RFC-1122. Definition at line 104 of file PCARP.C.

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/PCARP.H File Reference

SRC/PCARP.H File Reference

Detailed Description

ARP handler module.

Definition in file PCARP.H.

Go to the source code of this file.

Data Structures

struct | gate_entry
struct | arp_entry

Functions

W32_FUNC int | _arp_list_gateways (struct gate_entry *gw, int max)
Gateway functions.
BOOL | _arp_add_gateway (const char *config_string, DWORD ip)
Add a gateway to the routing table.
BOOL | _arp_check_gateways (void)
Check for multiple default gateways.
BOOL | _arp_have_default_gw (void)
Check if we have at least one default gateway.
void | _arp_kill_gateways (void)
Delete all gateways.
W32_FUNC BOOL | _arp_resolve (DWORD ina, eth_address *eth)
Blocking ARP resolve functions.
W32_FUNC BOOL | _arp_check_own_ip (eth_address *eth)
Used by DHCP initialisation.
BOOL | arp_start_lookup (DWORD ip)
New non-blocking functions, GvB 2002-09.
BOOL | arp_lookup (DWORD ip, eth_address *eth)
Lookup MAC-address of 'ip'.
BOOL | arp_lookup_fixed (DWORD ip, eth_address *eth)
Lookup fixed MAC-address of 'ip'.
BOOL | arp_lookup_pending (DWORD ip)
An ARP-lookup timeout check.
BOOL | _arp_add_cache (DWORD ip, const void *eth, BOOL expire)
ARP cache functions.
BOOL | _arp_delete_cache (DWORD ip)
Delete given 'ip' address from ARP-cache (dynamic or fixed).
W32_FUNC int | _arp_list_cache (struct arp_entry *arp, int max)
Return contents of ARP cache.
void | _arp_init (void)
'Internal' interface to pctcp.c & others.
BOOL | _arp_reply (const void *mac_dst, DWORD src_ip, DWORD dst_ip)
Send unicast/broadcast ARP reply.
BOOL | _arp_handler (const arp_Header *arp, BOOL brdcast)
Receive ARP handler.
BOOL | _arp_register (DWORD use_this_gateway_ip, DWORD for_this_host_ip)
ICMP redirection.
W32_FUNC void | _arp_debug_dump (void)
Debug-dump of configured gateways, route table and ARP cache.

Variables

W32_DATA BOOL(* | _sarp_recv_hook )(const struct sarp_Packet *sarp)
W32_DATA BOOL(* | _sarp_xmit_hook )(struct sarp_Packet *sarp)

Function Documentation

BOOL _arp_add_cache | ( | DWORD | ip,
 |  | const void * | eth,
 |  | BOOL | expires
 | ) |

ARP cache functions.

Note:
'ip' is on host order.
Definition at line 1206 of file PCARP.C.

References _arp_delete_cache(), arp_move_entry(), arp_entry::ip, is_on_LAN(), my_ip_addr, and set_timeout().

BOOL _arp_add_gateway | ( | const char * | config_string,
 |  | DWORD | ip
 | ) |

Add a gateway to the routing table.

The format of 'config_string' is: IP-address [, subnet] , mask]]

If 'config_string' is NULL, simply add 'ip' with zero mask and subnet. Definition at line 188 of file PCARP.C.

References aton(), DWORD, and gate_entry::gate_ip.

BOOL _arp_check_gateways ( void )

Check for multiple default gateways.

Return FALSE if we have none or more than 1. Definition at line 1614 of file PCARP.C.

References _arp_reply(), my_ip_addr, and gate_entry::subnet.

W32_FUNC BOOL _arp_check_own_ip ( eth_address * other_guy )

Used by DHCP initialisation.

Do an ARP resolve on our own IP address to check if someone else is replying. Return non-zero if someone replied.

Note:
Blocks waiting for reply or timeout.
Definition at line 1564 of file PCARP.C.

References _arp_resolve(), DWORD, eth_address, and my_ip_addr.

W32_FUNC void _arp_debug_dump ( void )

Debug-dump of configured gateways, route table and ARP cache.

Redone + moved here from pcdbug.c for encapsulation reasons GvB 2002-09 Definition at line 1641 of file PCARP.C.

References _inet_ntoa(), DWORD, MAC_address(), set_timeout(), and sin_mask.

BOOL _arp_delete_cache ( DWORD ip )

Delete given 'ip' address from ARP-cache (dynamic or fixed).

Note:
'ip' is on host order.
Definition at line 1270 of file PCARP.C.

References arp_move_entry(), arp_entry::flags, and arp_entry::ip.

BOOL _arp_handler | ( | const arp_Header * | ah,
 |  | BOOL | brdcast
 | ) |

Receive ARP handler.

This processes incoming 'raw' ARP packets supplied by tcp_tick(). Definition at line 1421 of file PCARP.C.

References _arp_add_cache(), _arp_reply(), _eth_addr, _eth_brdcast, _eth_get_hwtype(), _eth_mac_len, _inet_ntoa(), _pkt_rxmode, arp_move_entry(), arp_Header::dstIPAddr, DWORD, eth_address, arp_entry::expiry, arp_entry::flags, arp_Header::hwAddrLen, arp_Header::hwType, arp_entry::ip, MAC_address(), my_ip_addr, arp_Header::opcode, arp_Header::protoAddrLen, arp_Header::protType, RXMODE_BROADCAST, set_timeout(), arp_Header::srcEthAddr, arp_Header::srcIPAddr, and WORD.

W32_FUNC int _arp_list_cache | ( | struct arp_entry * | arp,
 |  | int | max
 | ) |

Return contents of ARP cache.

'max' entries are returned in 'arp[]' buffers. Only entries in-use are returned. Definition at line 1590 of file PCARP.C.

References eth_address, arp_entry::expiry, arp_entry::flags, arp_entry::hardware, and arp_entry::ip.

W32_FUNC int _arp_list_gateways | ( | struct gate_entry * | gw,
 |  | int | max
 | ) |

Gateway functions.

Note:
Max 'num' gateways is returned in 'gw[]' buffer.
Definition at line 80 of file PCARP.C.

References gate_entry::echo_pending, gate_entry::gate_ip, gate_entry::is_dead, gate_entry::mask, and gate_entry::subnet.

BOOL _arp_register | ( | DWORD | use_this_gateway_ip,
 |  | DWORD | for_this_host_ip
 | ) |

ICMP redirection.

Called on ICMP-redirects.

Redirects are sent from a gateway/router, telling us that a different gateway is better suited to connect to the specified host than the one we were using. Definition at line 727 of file PCARP.C.

BOOL _arp_reply | ( | const void * | mac_dst,
 |  | DWORD | src_ip,
 |  | DWORD | dst_ip
 | ) |

Send unicast/broadcast ARP reply.

'src_ip' and 'dst_ip' on network order. Definition at line 418 of file PCARP.C.

References _eth_addr, _eth_brdcast, _eth_formatpacket(), _eth_get_hwtype(), arp_send(), arp_Header::dstEthAddr, arp_Header::dstIPAddr, arp_Header::hwAddrLen, arp_Header::hwType, arp_Header::opcode, arp_Header::protoAddrLen, arp_Header::protType, arp_Header::srcEthAddr, and arp_Header::srcIPAddr.

W32_FUNC BOOL _arp_resolve | ( | DWORD | ina,
 |  | eth_address * | eth
 | ) |

Blocking ARP resolve functions.

Doesn't return until success or time-out. Definition at line 1117 of file PCARP.C.

BOOL arp_lookup | ( | DWORD | ip,
 |  | eth_address * | eth
 | ) |

Lookup MAC-address of 'ip'.

Return values:
TRUE MAC for 'ip' is known.
Definition at line 1038 of file PCARP.C.

References _eth_addr, _pktserial, eth_address, is_on_LAN(), LAN_lookup(), and route_lookup().

BOOL arp_lookup_fixed | ( | DWORD | ip,
 |  | eth_address * | eth
 | ) |

Lookup fixed MAC-address of 'ip'.

Return values:
TRUE Supplied 'ip' has a fixed MAC entry.
Definition at line 1083 of file PCARP.C.

References _pktserial, eth_address, arp_entry::ip, and is_on_LAN().

BOOL arp_lookup_pending ( DWORD ip )

An ARP-lookup timeout check.

Return values:
TRUE | The lookup is currently underway ("pending").
FALSE | The IP has either been resolved (arp_lookup() == TRUE), or the lookup has timed out, i.e. the host is unreachable.
Definition at line 1070 of file PCARP.C.

References is_on_LAN(), LAN_lookup_pending(), and route_lookup_pending().

BOOL arp_start_lookup ( DWORD ip )

New non-blocking functions, GvB 2002-09.

This is called by 'higher' routines to start an ARP request. This function is non-blocking, i.e. returns 'immediately'. Definition at line 1021 of file PCARP.C.

References _pktserial, is_on_LAN(), LAN_start_lookup(), and route_start_lookup().

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/PCBOOTP.C File Reference

SRC/PCBOOTP.C File Reference

Detailed Description

BOOTP - Boot Protocol (RFC 854/951/1048).

These extensions get called if _bootp_on is set.

Version:
0.3: Feb 1, 1992 : J. Dent - patched up various things.

0.2: May 22, 1991 : E.J. Sutcliffe - added RFC_1048 vendor fields.

0.1: May 9, 1991 : E. Engelke - made part of the library.

0.0: May 3, 1991 : E. Engelke - original program as an application.

Definition in file PCBOOTP.C.

Go to the source code of this file.

Functions

int | bootp_xmit (struct bootp *bootp_out)
BOOL | bootp_recv (struct bootp *bootp_out, struct bootp *bootp_in)
void | bootp_parse (const struct bootp *bootp_in, int len)
int | BOOTP_do_boot (void)
Main BOOTP initialisation.

Variables

DWORD | _bootp_host = IP_BCAST_ADDR
int | _bootp_timeout = 15
sock_type * | boot_sock

Function Documentation

int BOOTP_do_boot ( void )

Main BOOTP initialisation.

Checks global variables _bootp_timeout, _bootp_host. If no host specified, use the broadcast address.

Return values:
1 | success, local IP address set.
0 | something failed.
Note:
Doesn't retry the bootp_xmit() on timeout.
Definition at line 58 of file PCBOOTP.C.

References bootp::bp_yiaddr, DWORD, my_ip_addr, sock_close(), sock_type::udp, and udp_open().

Generated on Wed Jan 25 15:42:41 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/PCBOOTP.H File Reference

SRC/PCBOOTP.H File Reference

Detailed Description

Bootstrap Protocol (BOOTP). Based on RFC 951.

Definition in file PCBOOTP.H.

Go to the source code of this file.

Data Structures

struct | bootp
struct | bootp_vend

Enumerations

enum BOOTP_Options {
BOOTP_OPT_PAD = 0,
BOOTP_OPT_SUBNET_MASK = 1,
BOOTP_OPT_TIME_OFFSET = 2,
BOOTP_OPT_ROUTERS_ON_SNET = 3,
BOOTP_OPT_TIME_SRV = 4,
BOOTP_OPT_NAME_SRV = 5,
BOOTP_OPT_DNS_SRV = 6,
BOOTP_OPT_LOG_SRV = 7,
BOOTP_OPT_COOKIE_SRV = 8,
BOOTP_OPT_LPR_SRV = 9,
BOOTP_OPT_IMPRESS_SRV = 10,
BOOTP_OPT_RES_LOCATION_SRV = 11,
BOOTP_OPT_HOST_NAME = 12,
BOOTP_OPT_BOOT_FSIZE = 13,
BOOTP_OPT_DOMAIN_NAME = 15,
BOOTP_OPT_NON_LOCAL_SRC_ROUTE = 20,
BOOTP_OPT_POLICY_FILTER = 21,
BOOTP_OPT_MAX_DGRAM_REASM_SIZE = 22,
BOOTP_OPT_IP_DEFAULT_TTL = 23,
BOOTP_OPT_PATH_MTU_AGING_TIMEOUT = 24,
BOOTP_OPT_PATH_MTU_PLATEAU_TABLE = 25,
BOOTP_OPT_IF_MTU = 26,
BOOTP_OPT_ALL_SUBNETS_LOCAL = 27,
BOOTP_OPT_BROADCAST_ADDR = 28,
BOOTP_OPT_PERFORM_MASK_DISCOVERY = 29,
BOOTP_OPT_MASK_SUPPLIER = 30,
BOOTP_OPT_PERFORM_ROUTER_DISCOVERY = 31,
BOOTP_OPT_ROUTER_SOLICITATION_ADDR = 32,
BOOTP_OPT_STATIC_ROUTE = 33,
BOOTP_OPT_TRAILER_ENCAPSULATION = 34,
BOOTP_OPT_ARP_CACHE_TIMEOUT = 35,
BOOTP_OPT_ETHERNET_ENCAPSULATION = 36,
BOOTP_OPT_END = 255
}

Functions

int | BOOTP_do_boot (void)
Main BOOTP initialisation.

Variables

W32_DATA DWORD | _bootp_host
W32_DATA int | _bootp_timeout

Function Documentation

int BOOTP_do_boot ( void )

Main BOOTP initialisation.

Checks global variables _bootp_timeout, _bootp_host. If no host specified, use the broadcast address.

Return values:
1 | success, local IP address set.
0 | something failed.
Note:
Doesn't retry the bootp_xmit() on timeout.
Definition at line 58 of file PCBOOTP.C.

References bootp::bp_yiaddr, DWORD, my_ip_addr, sock_close(), sock_type::udp, and udp_open().

Generated on Wed Jan 25 15:42:42 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/PCBUF.C File Reference

SRC/PCBUF.C File Reference

Detailed Description

Status of Rx/tx buffers.

Definition in file PCBUF.C.

Go to the source code of this file.

Functions

int | num_free_raw (const _raw_Socket *raw)
int | num_free_raw6 (const _raw6_Socket *raw)
size_t | sock_rbsize (const sock_type *s)
size_t | sock_rbused (const sock_type *s)
size_t | sock_rbleft (const sock_type *s)
size_t | sock_tbsize (const sock_type *s)
size_t | sock_tbleft (const sock_type *s)
size_t | sock_tbused (const sock_type *s)
size_t | sock_setbuf (sock_type *s, BYTE *rx_buf, size_t rx_len)
void | _sock_check_tcp_buffers (const _tcp_Socket *tcp)
void | _sock_check_udp_buffers (const _udp_Socket *udp)
size_t | sock_preread (const sock_type *s, BYTE *buf, size_t len)
int | _chk_socket (const sock_type *s)
const char * | sockerr (const sock_type *s)
void | sockerr_clear (sock_type *s)
const char * | sockstate (const sock_type *s)
const _raw_Socket * | find_oldest_raw (const _raw_Socket *raw)
const _raw6_Socket * | find_oldest_raw6 (const _raw6_Socket *raw)

Generated on Wed Jan 25 15:42:42 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/PCBUF.H File Reference

SRC/PCBUF.H File Reference

Detailed Description

Definition in file PCBUF.H.

Go to the source code of this file.

Enumerations

enum TCP_SIMPLE_STATE {
TCP_CLOSED,
TCP_LISTENING,
TCP_OPENING,
TCP_OPEN,
TCP_CLOSING
}

Functions

W32_FUNC size_t | sock_rbsize (const sock_type *s)
W32_FUNC size_t | sock_rbused (const sock_type *s)
W32_FUNC size_t | sock_rbleft (const sock_type *s)
W32_FUNC size_t | sock_tbsize (const sock_type *s)
W32_FUNC size_t | sock_tbused (const sock_type *s)
W32_FUNC size_t | sock_tbleft (const sock_type *s)
W32_FUNC size_t | sock_setbuf (sock_type *s, BYTE *buf, size_t len)
W32_FUNC size_t | sock_preread (const sock_type *s, BYTE *buf, size_t len)
W32_FUNC const char * | sockerr (const sock_type *s)
W32_FUNC void | sockerr_clear (sock_type *s)
W32_FUNC const char * | sockstate (const sock_type *s)
W32_FUNC int | _chk_socket (const sock_type *s)
W32_FUNC void | sock_debugdump (const sock_type *s)
W32_FUNC enum TCP_SIMPLE_STATE | tcp_simple_state (const _tcp_Socket *s)
void | _sock_check_tcp_buffers (const _tcp_Socket *tcp)
void | _sock_check_udp_buffers (const _udp_Socket *udp)
const _raw_Socket * | find_oldest_raw (const _raw_Socket *raw)
const _raw6_Socket * | find_oldest_raw6 (const _raw6_Socket *raw)

Generated on Wed Jan 25 15:42:42 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/PCCONFIG.C File Reference

SRC/PCCONFIG.C File Reference

Detailed Description

WatTCP config file handling.

Definition in file PCCONFIG.C.

Go to the source code of this file.

Enumerations

enum ParseMode {
ModeKeyword = 0,
ModeValue,
ModeComment
}

Functions

void | deprecated_key (const char *old_key, const char *new_key)
void | keyword_not_found (const char *key, const char *value)
This function eventually gets called if no keyword was matched.
void | set_debug_on (const char *value)
void | set_ethip (const char *value)
Add an "ether, IPv4-address" pair to the static ARP-cache.
void | _add_server (WORD *counter, WORD max, DWORD *array, DWORD value)
const char * | ExpandVarStr (const char *str)
Return a string with a environment variable expanded (only one).
BOOL | set_value (BOOL is_hex, const char *value, void *arg, int size)
Parse and store ARG_ATOX_B, ARG_ATOX_W or ARG_ATOI value.
int | parse_config_table (const struct config_table *tab, const char *section, const char *name, const char *value)
Parse the config-table and if a match is found for ('section'+'.'+)'name' either store variable to 'value' or call function with 'value'.
void | set_my_ip (const char *value)
void | set_hostname (const char *value)
void | set_gateway (const char *value)
void | set_nameserv (const char *value)
void | set_cookie (const char *value)
void | set_eaddr (const char *value)
Set new ether-address from "ether" value.
void | set_domain (const char *value)
void | depr_set_domain1 (const char *value)
void | depr_set_domain2 (const char *value)
void | do_print (const char *str)
void | depr_dns_timeout1 (const char *value)
void | depr_dns_timeout2 (const char *value)
void | depr_dns_recurse (const char *value)
long | do_include_file (const char *value, int len)
Open and parse an include file.
const char * | get_argv0 (void)
Return argv[0] as passed to main().
void | set_recv_win (const char *value)
void | tcp_set_debug_state (WORD x)
Used when DEBUG=x is defined in the config file Moved from pctcp.c.
void | tcp_inject_config_direct (const struct config_table *cfg, const char *key, const char *value)
Called from config-file parser after "key = value" is found.
void | tcp_inject_config (const struct config_table *cfg, const char *key, const char *value)
Callable from a user application to inject config values before the normal WATTCP.CFG is loaded and parsed.
long | tcp_parse_file (WFILE f, const struct config_table *cfg)
int | tcp_config_name (char *name, int max)
long | tcp_config (const char *path)
int | netdb_init (void)
Called from most <netdb.h> functions in case watt_sock_init() wasn't called first to initialise things.
void | netdb_warn (const char *fname)
void | not_found2 (const char *key, const char *value)
long | my_injector (int pass, const struct config_table *cfg)
void | Usage (void)
int | main (int argc, char **argv)

Variables

int | debug_on = 0
int | ctrace_on = 0
int | sock_delay = 30
int | sock_inactive = 0
int | sock_data_timeout = 0
WORD | multihomes = 0
BOOL | dynamic_host = 0
DWORD | cookies [MAX_COOKIES]
WORD | last_cookie = 0
void(* | print_hook )(const char *)=NULL
void(* | usr_init )(const char *, const char *)=keyword_not_found
void(* | usr_post_init )(void)=NULL
Hook to a function called after we're initialised.
char * | config_name = "WATTCP.CFG"
char * | current_file = NULL
UINT | current_line = 0
BOOL | got_eol = FALSE
const char * | environ_names []
const struct config_table | normal_cfg []
const struct config_table * | watt_init_cfg = normal_cfg
const char * | cfg_file

Function Documentation

long do_include_file | ( | const char * | value,
 |  | int | len
 | ) | [static]

Open and parse an include file.

Syntax: "include = [?]<file>". If '?' prefix is used, the parser will not warn if the file isn't found. Definition at line 571 of file PCCONFIG.C.

References UINT.

const char* ExpandVarStr ( const char * str )

Return a string with a environment variable expanded (only one).

E.g. if environment variable ETC is "c:\network\watt\bin", "$(ETC)\hosts" becomes "c:\network\watt\bin\hosts" If ETC isn't defined, "$(ETC)\hosts" becomes "\hosts".

Todo:
support several in one line and malloc the result.
Definition at line 187 of file PCCONFIG.C.

void keyword_not_found | ( | const char * | key,
 |  | const char * | value
 | ) | [static]

This function eventually gets called if no keyword was matched.

Prints a warning (file+line) in debug-mode >= 2. Definition at line 224 of file PCCONFIG.C.

void set_ethip ( const char * value ) [static]

Add an "ether, IPv4-address" pair to the static ARP-cache.

Add an "ether, IPv6-address" pair to the static ND-cache. Definition at line 132 of file PCCONFIG.C.

References _arp_add_cache(), _eth_real_addr, _inet6_addr(), _inet_addr(), _inet_atoeth(), DWORD, and eth_address.

BOOL set_value | ( | BOOL | is_hex,
 |  | const char * | value,
 |  | void * | arg,
 |  | int | size
 | ) | [static]

Parse and store ARG_ATOX_B, ARG_ATOX_W or ARG_ATOI value.

Accept "0x" or "x" prefix for ATOX types only. Accept ATOX values without a prefix too. Definition at line 236 of file PCCONFIG.C.

References atox(), BYTE, DWORD, and WORD.

void tcp_inject_config | ( | const struct config_table * | cfg,
 |  | const char * | key,
 |  | const char * | value
 | ) |

Callable from a user application to inject config values before the normal WATTCP.CFG is loaded and parsed.

See '_watt_user_config' in sock_ini.c. Definition at line 848 of file PCCONFIG.C.

References strntrimcpy(), tcp_inject_config_direct(), and UINT.

void tcp_inject_config_direct | ( | const struct config_table * | cfg,
 |  | const char * | key,
 |  | const char * | value
 | ) | [static]

Called from config-file parser after "key = value" is found.

Take 'value' and possibly expand any in it. Pass key/value to config_table parser. Definition at line 819 of file PCCONFIG.C.

References ExpandVarStr(), and parse_config_table().

Variable Documentation

const char* environ_names[] [static]

Initial value:

 {
                  "WATTCP.CFG",
                  "WATTCP_CFG"
                }
Definition at line 83 of file PCCONFIG.C.

Generated on Wed Jan 25 15:42:42 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/PCCONFIG.H File Reference

SRC/PCCONFIG.H File Reference

Detailed Description

Definition in file PCCONFIG.H.

Go to the source code of this file.

Data Structures

struct | config_table

Typedefs

typedef FILE * | WFILE
typedef long(* | WattUserConfigFunc )(int pass, const struct config_table *cfg)

Enumerations

enum config_tab_types {
ARG_ATOI,
ARG_ATOB,
ARG_ATOW,
ARG_ATOIP,
ARG_ATOX_B,
ARG_ATOX_W,
ARG_ATOX_D,
ARG_STRDUP,
ARG_STRCPY,
ARG_RESOLVE,
ARG_FUNC
}
Convert 'arg_func' below to this type. More...

Functions

const char * | get_argv0 (void)
Return argv[0] as passed to main().
void | _add_server (WORD *counter, WORD max, DWORD *array, DWORD value)
int | netdb_init (void)
Called from most <netdb.h> functions in case watt_sock_init() wasn't called first to initialise things.
void | netdb_warn (const char *fname)
W32_FUNC int | tcp_config_name (char *name, int max)
W32_FUNC long | tcp_config (const char *path)
W32_FUNC void | tcp_set_debug_state (WORD x)
Used when DEBUG=x is defined in the config file Moved from pctcp.c.
W32_FUNC int | parse_config_table (const struct config_table *tab, const char *section, const char *name, const char *value)
Parse the config-table and if a match is found for ('section'+'.'+)'name' either store variable to 'value' or call function with 'value'.
W32_FUNC const char * | ExpandVarStr (const char *str)
Return a string with a environment variable expanded (only one).
long | tcp_parse_file (WFILE f, const struct config_table *cfg)
void | tcp_inject_config (const struct config_table *cfg, const char *key, const char *value)
Callable from a user application to inject config values before the normal WATTCP.CFG is loaded and parsed.
W32_FUNC WattUserConfigFunc | _watt_user_config (WattUserConfigFunc fn)
A user application may call the `_watt_user_config()' function prior to calling sock_init() to inject its own configuration values into the tcp_config() parser.

Variables

W32_DATA int | sock_inactive
W32_DATA int | sock_data_timeout
W32_DATA int | sock_delay
W32_DATA WORD | multihomes
W32_DATA void(* | print_hook )(const char *)
W32_DATA void(* | usr_init )(const char *, const char *)
W32_DATA void(* | usr_post_init )(void)
W32_DATA DWORD | cookies [MAX_COOKIES]
W32_DATA WORD | last_cookie
W32_DATA int | debug_on
W32_DATA int | ctrace_on
W32_DATA BOOL | dynamic_host
const struct config_table * | watt_init_cfg
WattUserConfigFunc | _watt_user_config_fn

Enumeration Type Documentation

enum config_tab_types

Convert 'arg_func' below to this type.

Enumeration values:
ARG_ATOI | convert to int
ARG_ATOB | convert to 8-bit byte
ARG_ATOW | convert to 16-bit word
ARG_ATOIP | convert to ip-address (host order)
ARG_ATOX_B | convert to hex-byte
ARG_ATOX_W | convert to hex-word
ARG_ATOX_D | convert to hex-dword
ARG_STRDUP | duplicate string value
ARG_STRCPY | copy string value
ARG_RESOLVE | resolve host to IPv4-address
ARG_FUNC | call convertion function
Definition at line 14 of file PCCONFIG.H.

Function Documentation

W32_FUNC WattUserConfigFunc _watt_user_config ( WattUserConfigFunc fn )

A user application may call the `_watt_user_config()' function prior to calling sock_init() to inject its own configuration values into the tcp_config() parser.

Useful when running diskless and setting `_watt_no_config = 0'.

Example:

  • 'pass' is 1 for first pass (PKTDRVR/WinPcap configuration), 2 for second pass.
  • 'cfg' is a pointer to the configuration table and must be passed to tcp_inject_config() as-is.

In most cases 'pass' can probably be ignored.

static long my_config_fn (int pass, const struct config_table *cfg) { // Keyword case is not significant (tcp_inject_config will convert // all keys to uppercase)

tcp_inject_config (cfg, "My_IP", "192.168.0.98"); tcp_inject_config (cfg, "NetMask", "255.255.255.0"); tcp_inject_config (cfg, "Gateway", "192.168.0.1"); (void)pass; return (1); // Returning 0 would make tcp_config() return 0 too, // as if the config file was not found }

int main (void) { _watt_no_config = 1; _watt_user_config (my_config_fn); if (sock_init()) return (-1); ... }

Never called inside Watt-32. Definition at line 184 of file SOCK_INI.C.

W32_FUNC const char* ExpandVarStr ( const char * str )

Return a string with a environment variable expanded (only one).

E.g. if environment variable ETC is "c:\network\watt\bin", "$(ETC)\hosts" becomes "c:\network\watt\bin\hosts" If ETC isn't defined, "$(ETC)\hosts" becomes "\hosts".

Todo:
support several in one line and malloc the result.
Definition at line 187 of file PCCONFIG.C.

void tcp_inject_config | ( | const struct config_table * | cfg,
 |  | const char * | key,
 |  | const char * | value
 | ) |

Callable from a user application to inject config values before the normal WATTCP.CFG is loaded and parsed.

See '_watt_user_config' in sock_ini.c. Definition at line 848 of file PCCONFIG.C.

Generated on Wed Jan 25 15:42:42 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/PCDBUG.C File Reference

SRC/PCDBUG.C File Reference

Detailed Description

WatTCP protocol debugger. Writes to `debug.file' specified in config-file. File may be stdout/stderr/nul.

Most functions are prefixed with `dbug_', variables with `dbg_'.

Definition in file PCDBUG.C.

Go to the source code of this file.

Data Structures

struct | token
struct | DNS_Hdr
Debug of DNS (udp) records. More...
struct | pcap_file_header
struct | pcap_pkt_header

Enumerations

enum ncp_codes {
CONFREQ = 1,
CONFACK = 2,
CONFNAK = 3,
CONFREJ = 4,
TERMREQ = 5,
TERMACK = 6,
CODEREJ = 7,
PROTREJ = 8,
ECHOREQ = 9,
ECHOREP = 10,
DISCARD = 11
}
enum lcp_options {
LCP_RESERVED = 0,
LCP_MRU = 1,
LCP_ASYNCMAP = 2,
LCP_AUTHPROTO = 3,
LCP_QUALPROTO = 4,
LCP_MAGICNUM = 5,
LCP_PCOMP = 7,
LCP_ACFCOMP = 8,
LCP_CALLBACK = 13
}
enum ipcp_options {
IPCP_RESERVED = 0,
IPCP_ADDRS = 1,
IPCP_COMPRTYPE = 2,
IPCP_ADDR = 3,
IPCP_MS_DNS1 = 129,
IPCP_MS_WINS1 = 130,
IPCP_MS_DNS2 = 131,
IPCP_MS_WINS2 = 132
}

Functions

const char * | tcpStateName (UINT state)
void | dbug_init (void)
void | dbug_exit (void)
Print ARP-cache and statistics counters to one of the debug-files.
void | dbug_close (void)
void | dbug_flush (void)
void | dump_options (const void *opt, int len, DWORD ack, BOOL is_ip)
DWORD | dump_data (const void *data, UINT datalen)
int | udp_dump (const _udp_Socket *sock, const in_Header *ip)
int | tcp_dump (const _tcp_Socket *sock, const in_Header *ip)
unsigned | dns_dump (const BYTE *, unsigned, unsigned)
const BYTE * | dns_resource (const BYTE *, const BYTE *, const BYTE *)
const BYTE * | dns_labels (const BYTE *, const BYTE *, const BYTE *)
int | write_pcap_header (void)
int | write_pcap_packet (const void *pkt, BOOL out)
unsigned | ccp_dump (const BYTE *bp)
unsigned | lcp_dump (const BYTE *bp)
unsigned | ipcp_dump (const BYTE *bp)
int | udp6_dump (const _udp_Socket *sock, const in6_Header *ip)
FILE * | dbug_file (void)
void | dbug_open (void)
__inline BOOL | MAC_is_mcast (const void *addr)
__inline BOOL | MAC_is_bcast (const void *addr)
__inline BOOL | is_looped (const in_Header *ip)
__inline BOOL | MatchLinkDestination (const void *addr)
__inline BOOL | MatchArpRarp (const arp_Header *arp)
__inline BOOL | MatchIp4Dest (const in_Header *ip)
__inline BOOL | MatchIp6Dest (const in6_Header *ip)
__inline const char * | DoCheckSum (WORD value, const void *p, int len)
__inline const char * | LinkProtocol (WORD type)
__inline const char * | IpProtocol (BYTE prot)
const char * | TypeOfService (BYTE tos)
__inline const char * | RTT_str (DWORD rtt, DWORD now)
__inline const char * | ArpOpcode (WORD code)
void | dump_addr_port (const char *proto, const void *sock, const in_Header *ip)
__inline void | ip6_addr_type (char *ret, const void *addr)
void | dump_addr6_port (const char *proto, const void *sock, const in6_Header *ip)
void | link_head_dump (const union link_Packet *pkt)
int | arp_dump (const arp_Header *arp)
int | rarp_dump (const rarp_Header *rarp)
void | ip4_dump (const in_Header *ip)
int | ip4_orig_dump (const in_Header *this_ip, const in_Header *orig_ip, int icmp_len)
int | icmp4_dump (const in_Header *ip)
int | igmp_dump (const in_Header *ip)
unsigned | ip4_payload_dump (const void *sock, const in_Header *ip)
const char * | ip6_next_hdr (BYTE nxt)
const char * | icmp6_options (const BYTE *opt, int tot_len)
int | icmp6_dump (const in6_Header *ip)
int | ip6_header_dump (const in6_Header *ip)
unsigned | ip6_payload_dump (const void *sock, const in6_Header *ip)
const char * | tok2str (const struct token *lp, const char *fmt, int v)
const char * | pppoe_get_tag (const BYTE *tag)
const char * | pppoe_get_code (WORD code)
__inline int | pppoe_head_dump (const struct pppoe_Packet *pppoe, const char *proto)
int | pppoe_disc_dump (const struct pppoe_Packet *pppoe)
int | pppoe_sess_dump (const void *sock, const struct pppoe_Packet *pppoe)
const char * | udp_tcp_checksum (const in_Header *ip, const udp_Header *udp, const tcp_Header *tcp)
const char * | udp_checksum (const in6_Header *ip, const udp_Header *udp)
const char * | tcp_checksum (const in6_Header *ip, const tcp_Header *tcp)
__inline BOOL | is_dns_packet (WORD src_port, WORD dst_port)
BOOL | dbug_filter (void)
const char * | pkt_driver_ver (void)
const char * | pkt_api_ver (void)
void | dbug_dump (const void *sock, const in_Header *ip, const char *fname, unsigned line, BOOL out)
void | dbug_send (const void *sock, const in_Header *ip, const char *fname, unsigned line)
void | dbug_recv (const void *sock, const in_Header *ip, const char *fname, unsigned line)
void | set_debug_file (const char *value)
void | set_debug_mode (const char *value)
void | set_debug_filter (const char *value)
void | set_debug_proto (const char *value)
void | ourinit (const char *name, const char *value)
int MS_CDECL | dbug_printf (const char *format,...)
int | dbug_write (const char *buf)
int | db_write_raw (const char *buf)
void | dbug_dump_arp_cache (int pfx_chr)
__inline const char * | dns_query (WORD type)

Variables

DebugProc | _dbugxmit = NULL
DebugProc | _dbugrecv = NULL
jmp_buf | dbg_jmp
void(* | prev_hook )(const char *, const char *)=NULL
char | dbg_name [MAX_PATHLEN+1] = "WATTCP.DBG"
BOOL | dbg_linebuf = FALSE
BOOL | pcap_mode = FALSE
DWORD | now
BOOL | outbound
BOOL | in_dbug_dump
BOOL | use_gzip
char | ip4_src [20]
char | ip4_dst [20]
union {
FILE * stream
void * gz_stream
} dbg_file
int | frag_status
char | ip6_src [50]
char | ip6_dst [50]
struct {
char MAC
char ARP
char RARP
char IP
char BCAST
char MCAST
char LOOP
char NONE
} filter
struct {
char MAC
char LLC
char ARP
char RARP
char IP
char UDP
char TCP
char ICMP
char IGMP
} debug
BOOL | dbg_mode_all = 1
These are public so they can be set by application if running without a config-file.
BOOL | dbg_print_stat = 1
BOOL | dbg_dns_details = 1
DWORD | bytes_raw = 0UL
token | ppp_type2str []
const char * | dns_opcodes [16]
const char * | dns_responses [16]
const struct token | ncp_code2str []
const struct token | lcp_option2str []
const struct token | ipcp_option2str []
const struct token | lcpauth2str []
const struct token | lcpqual2str []
const struct token | lcpchap2str []

Function Documentation

void dbug_exit ( void ) [static]

Print ARP-cache and statistics counters to one of the debug-files.

Called from tcp_shutdown() after DHCP_release() and _tcp_abort() but before _eth_release() is called. pkt-drop counters are not reliable once _eth_release() has been called. Definition at line 2579 of file PCDBUG.C.

References _watt_assert_buf, _watt_fatal_error, and DWORD.

int icmp4_dump ( const in_Header * ip ) [static]

Todo:
Handle debugging of these
Definition at line 837 of file PCDBUG.C.

References _inet_ntoa(), BYTE, in_Header::length, and WORD.

__inline BOOL MatchIp6Dest ( const in6_Header * ip ) [static]

Todo:
needs work
Definition at line 356 of file PCDBUG.C.

References in6_Header::destination.

Variable Documentation

BOOL dbg_mode_all = 1

These are public so they can be set by application if running without a config-file.

Todo:
make them static.
Definition at line 175 of file PCDBUG.C.

const char* dns_opcodes[16] [static]

Initial value:

 {
            "standard",
            "inverse",
            "server status",
            "op 3??",
            "op 4??",
            "update",
            "op 6??",
            "op 7??",
            "op 8??",
            "op 9??",
            "op 10??",
            "op 11??",
            "op 12??",
            "op 13??",
            "op 14??",
            "op 15??"
          }
Definition at line 2672 of file PCDBUG.C.

const char* dns_responses[16] [static]

Initial value:

 {
            "no error",
            "format error",
            "server error",
            "NXDOMAIN",
            "not implemented",
            "service refused",
            "resp 6??",
            "resp 7??",
            "resp 8??",
            "resp 9??",
            "resp 10??",
            "resp 11??",
            "resp 12??",
            "resp 13??",
            "resp 14??",
            "resp 15??"
          }
Definition at line 2691 of file PCDBUG.C.

const struct token ipcp_option2str[] [static]

Initial value:

 {
                    { IPCP_RESERVED, "reserved" },
                    { IPCP_ADDRS,    "Addrs"    },
                    { IPCP_COMPRTYPE,"Compr"    },
                    { IPCP_ADDR,     "Addr"     },
                    { IPCP_MS_DNS1,  "DNS1"     },
                    { IPCP_MS_WINS1, "Wins1"    },
                    { IPCP_MS_DNS2,  "DNS2"     },
                    { IPCP_MS_WINS2, "Win2"     },
                    { 0,             NULL       }
                  }
Definition at line 3098 of file PCDBUG.C.

const struct token lcp_option2str[] [static]

Initial value:

 {
                    { LCP_RESERVED, "reserved" },
                    { LCP_MRU,      "MRU"      },
                    { LCP_ASYNCMAP, "AsyncMap" },
                    { LCP_AUTHPROTO,"AUTH"     },
                    { LCP_QUALPROTO,"QUAL"     },
                    { LCP_MAGICNUM, "MAGIC"    },
                    { LCP_PCOMP,    "PCOMP"    },
                    { LCP_ACFCOMP,  "ACFcomp"  },
                    { LCP_CALLBACK, "CallBack" },
                    { 0,            NULL       }
                  }
Definition at line 3085 of file PCDBUG.C.

const struct token lcpauth2str[] [static]

Initial value:

 {
                    { 0xc023, "PAP"  },
                    { 0xc223, "CHAP" },
                    { 0,       NULL  }
                  }
Definition at line 3110 of file PCDBUG.C.

const struct token lcpchap2str[] [static]

Initial value:

 {
                    { 0x05, "MD5" },
                    { 0x80, "MS"  },
                    { 0,    NULL  }
                  }
Definition at line 3121 of file PCDBUG.C.

const struct token lcpqual2str[] [static]

Initial value:

 {
                    { 0xc025, "LQR" },
                    { 0,      NULL  }
                  }
Definition at line 3116 of file PCDBUG.C.

const struct token ncp_code2str[] [static]

Initial value:

 {
                    { CONFREQ, "ConfReq" },
                    { CONFACK, "ConfAck" },
                    { CONFNAK, "ConfNak" },
                    { CONFREJ, "ConfRej" },
                    { TERMREQ, "TermReq" },
                    { TERMACK, "TermAck" },
                    { CODEREJ, "CodeRej" },
                    { PROTREJ, "ProtRej" },
                    { ECHOREQ, "EchoReq" },
                    { ECHOREP, "EchoRep" },
                    { DISCARD, "Discard" },
                    { 0,       NULL      }
                  }
Definition at line 3070 of file PCDBUG.C.

struct token ppp_type2str[]

Initial value:

 {
             { PPP_IP,    "IP"    },
             { PPP_IPV6,  "IP6"   },
             { PPP_IPX,   "IPX"   },
             { PPP_VJC,   "VJC"   },
             { PPP_VJNC,  "VJNC"  },
             { PPP_IPCP,  "IPCP"  },
             { PPP_IPXCP, "IPXCP" },
             { PPP_LCP,   "LCP"   },
             { PPP_LQR,   "LQR"   },
             { PPP_CCP,   "CCP"   },
             { PPP_PAP,   "PAP"   },
             { PPP_CHAP,  "CHAP"  },
             { PPP_CBCP,  "CBCP"  },
             { PPP_COMP,  "COMP"  },
             { 0,         NULL    }
           }
Definition at line 1220 of file PCDBUG.C.

Generated on Wed Jan 25 15:42:42 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/PCDBUG.H File Reference

SRC/PCDBUG.H File Reference

Detailed Description

Definition in file PCDBUG.H.

Go to the source code of this file.

Typedefs

typedef void(* | DebugProc )(const void *sock, const in_Header *ip, const char *file, unsigned line)

Functions

const char * | tcpStateName (UINT state)
W32_FUNC void | dbug_init (void)
void | dbug_open (void)
FILE * | dbug_file (void)
int | dbug_write (const char *)
int MS_CDECL | dbug_printf (const char *fmt,...) ATTR_PRINTF(1
const char * | pppoe_get_code (WORD code)

Variables

W32_DATA DebugProc | _dbugxmit
W32_DATA DebugProc | _dbugrecv
BOOL | dbg_mode_all
These are public so they can be set by application if running without a config-file.
BOOL | dbg_print_stat
BOOL | dbg_dns_details

Variable Documentation

BOOL dbg_mode_all

These are public so they can be set by application if running without a config-file.

Todo:
make them static.
Definition at line 175 of file PCDBUG.C.

Generated on Wed Jan 25 15:42:42 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/PCDHCP.C File Reference

SRC/PCDHCP.C File Reference

Detailed Description

Dynamic Host Configuration Protocol (RFC 1541/2131/2132). These extensions gets called if "MY_IP" is set to "DHCP" or if no WATTCP.CFG file is found.

Definition in file PCDHCP.C.

Go to the source code of this file.

Functions

void | DHCP_state_INIT (int event)
DHCP state machine: state INIT.
void | DHCP_state_BOUND (int event)
DHCP state machine: state BOUND.
void | DHCP_state_RENEWING (int event)
DHCP state machine: state RENEWING.
void | DHCP_state_REQUESTING (int event)
DHCP state machine: state REQUESTING.
void | DHCP_state_SELECTING (int event)
DHCP state machine: state SELECTING.
void | DHCP_state_REBINDING (int event)
DHCP state machine: state REBINDING.
void | dhcp_fsm (void)
DHCP state machine: the event driver.
void | dhcp_options_add (const BYTE *opt, unsigned max)
Add options from a DHCP_OPT_OVERLOAD tag to 'extra_options' list.
void | dhcp_set_timers (void)
Set all timers required by the DHCP state machine.
void | change_ip_addr (void)
Change my_ip_addr of all tcp/udp sockets.
BYTE * | put_request_list (BYTE *opt, int filled)
Append options from 'request_list' to 'opt'.
int | write_config (void)
Write the transient DHCP configuration, either to file or via user-defined function.
void | erase_config (void)
Erase the transient configuration.
const char * | state_name (void)
Return name of current DHCP state function.
const char * | period (DWORD sec)
Return nicely formatted string for a time-period.
BYTE * | make_boot_header (void)
Format a BOOTP header.
BYTE * | put_hardware_opt (BYTE *opt)
Fill in the hardware type/len in Client ID option tag.
int | DHCP_discover (void)
Send a DHCP discover message.
int | DHCP_request (BOOL renew)
Send a DHCP request message.
int | DHCP_release_decline (int msg_type, const char *msg)
Send a DHCP release or decline message.
BOOL | DHCP_arp_check (DWORD my_ip)
Send an ARP reply to announce our new IP-address.
int | DHCP_offer (const struct dhcp *in)
Parse DHCP offer reply.
int | DHCP_is_ack (void)
Return TRUE if DHCP message is an ACK.
int | DHCP_is_nack (void)
Return TRUE if DHCP message is a NACK.
void | DHCP_release (BOOL force)
Possibly send a DHCP release.
DWORD | DHCP_get_server (void)
Return current DHCP server address.
sock_type * | dhcp_open (const char *msg, BOOL use_broadcast)
Allocate and open a UDP socket for DHCP message exchange.
void | arp_add_server (void)
Add MAC address of DHCP sever to our ARP cache.
void | DHCP_state_REBOOTING (int event)
DHCP state machine: Combined BOOT and BOOTING state.
int | DHCP_do_boot (void)
Our first time (booting) DHCP handler.
int | set_request_list (char *options)
Parse a list of DHCP-request options from config-file.
int | set_user_class (const char *value)
Parse user-class as specified in config-file.
int | set_vend_class (const char *value)
Set vendor class option.
void | DHCP_cfg_hook (const char *name, const char *value)
Parser for DHCP configuration.
void | DHCP_exit (void)
Free allocated memory.
void | DHCP_init (void)
Initialises the DHCP config-parser.
void | set_my_ip (const char *value)
Functions called by config-file parser while reading C:.TMP.
void | set_netmask (const char *value)
void | set_gateway (const char *value)
void | set_nameserv (const char *value)
void | set_server (const char *value)
void | set_domain (const char *value)
void | set_lease (const char *value)
void | set_renew (const char *value)
void | set_rebind (const char *value)
BOOL | eval_timers (void)
Check timers read from config-file and set state according to following rules: now < renewal => BOUND now > renewal && now < rebind => RENEWING now >= rebind && now < lease-end => REBINDING now >= lease-end => INIT-REBOOT.
const char * | get_config_file (void)
void | std_erase_config (void)
int | std_read_config (void)
int | std_write_config (void)
Write the transient DHCP configuration to file.
void | usr_erase_config (void)
int | usr_read_config (void)
int | usr_write_config (void)
int | DHCP_read_config (void)
Called from watt_sock_init() after "\c WATTCP.CFG" has been parsed.
WattDHCPConfigFunc | dhcp_set_config_func (WattDHCPConfigFunc fn)
Sets up an application hook for doing DHCP operations (DHCP_config_op).

Variables

BOOL | dhcp_did_gratuitous_arp = FALSE
WattDHCPConfigFunc | config_func = NULL
DWORD | exchange_id
DWORD | router
DWORD | nameserver
DWORD | dhcp_server = 0
DWORD | dhcp_renewal = 0
DWORD | dhcp_rebind = 0
DWORD | dhcp_iplease = 0
DWORD | suggest_lease = 0
DWORD | old_ip_addr = 0
BOOL | bcast_flag = TRUE
BOOL | got_offer = FALSE
BOOL | configured = FALSE
BOOL | arp_check_ip = FALSE
BOOL | cfg_read = FALSE
BOOL | cfg_saved = FALSE
int | dhcp_timeout = 10
int | max_retries = 3
int | discover_loops = 0
dhcp dhcp_in | dhcp_out
void(* | DHCP_state )(int)=NULL
time_t | renewal_timeout
time_t | rebind_timeout
time_t | lease_timeout
DWORD | send_timeout
BOOL | trace_on = FALSE
char | config_file [MAX_VALUELEN+1] = ""
sock_type * | sock = NULL
const BYTE | default_request_list []
DHCP_list | request_list
DHCP_list | extra_options = { NULL, 0 }
DHCP_list | user_class = { NULL, 0 }
DHCP_list | vend_class = { (BYTE*)"Watt-32", 7 }
void(* | prev_hook )(const char *, const char *)=NULL
time_t | cfg_dhcp_iplease
time_t | cfg_dhcp_renewal
time_t | cfg_dhcp_rebind
const struct config_table | transient_cfg []
Open and parse Wattcp transient configuration.

Function Documentation

BOOL DHCP_arp_check ( DWORD my_ip ) [static]

Send an ARP reply to announce our new IP-address.

This is in order to fill ARP cache of other hosts (gratuitous ARP).

Optionally (if arp_check_ip is TRUE), send an ARP request to check if our assigned IP-address is really vacant. Definition at line 405 of file PCDHCP.C.

References _arp_check_own_ip(), _arp_reply(), _pktserial, DWORD, eth_address, MAC_address(), and sin_mask.

void DHCP_cfg_hook | ( | const char * | name,
 |  | const char * | value
 | ) | [static]

Parser for DHCP configuration.

Matches all "\c DHCP.xx" values from WATTCP.CFG file and make appropriate actions. Definition at line 1300 of file PCDHCP.C.

References ARG_ATOI, ARG_FUNC, ARG_RESOLVE, ARG_STRCPY, parse_config_table(), set_request_list(), set_user_class(), and set_vend_class().

int DHCP_do_boot ( void )

Our first time (booting) DHCP handler.

Only called if:

  • we don't have a WATTCP.CFG file
  • or we specified "MY_IP = DHCP".
  • or reading a previous W32DHCP.TMP file with transient config failed.

It doesn't hurt that it is blocking. Definition at line 1025 of file PCDHCP.C.

References addwattcpd(), dhcp_fsm(), dhcp_open(), DHCP_state_BOUND(), DHCP_state_INIT(), erase_config(), my_ip_addr, set_timeout(), sin_mask, tcp_tick(), and write_config().

int DHCP_offer ( const struct dhcp * in ) [static]

Parse DHCP offer reply.

Note:
May be called recursively.

Todo:
make a hook for SMB-lib
Definition at line 443 of file PCDHCP.C.

References _arp_add_gateway(), _arp_kill_gateways(), _default_ttl, _inet_ntoa(), BYTE, defaultdomain, dhcp::dh_file, dhcp::dh_opt, dhcp::dh_sname, dhcp_options_add(), DWORD, hostname, period(), setdomainname(), sin_mask, StrLcpy(), and tcp_keep_intvl.

int DHCP_read_config ( void )

Called from watt_sock_init() after "\c WATTCP.CFG" has been parsed.

Open and parse transient configuration from 'config_file' or call user-defined function to read transient configuration. Definition at line 1727 of file PCDHCP.C.

References dhcp_open(), dhcp_set_timers(), eval_timers(), and sock_type::udp.

void DHCP_release ( BOOL force )

Possibly send a DHCP release.

  • force If TRUE, release unconditionally.
    Note:
    Send release if we are configured and remaining lease is below minimum lease (DHCP_MIN_LEASE = 10 sec).
Definition at line 690 of file PCDHCP.C.

References delwattcpd(), dhcp_fsm(), DHCP_release_decline(), and sock_close().

int DHCP_release_decline | ( | int | msg_type,
 |  | const char * | msg
 | ) | [static]

Send a DHCP release or decline message.

  • msg_type DHCP_RELEASE or DHCP_DECLINE.
  • msg Optional message describing the cause.
Definition at line 367 of file PCDHCP.C.

References BYTE, dhcp::dh_opt, DWORD, make_boot_header(), and set_timeout().

void DHCP_state_BOUND ( int event ) [static]

DHCP state machine: state BOUND.

  • Awaits T1-TIMEOUT and enter RENEWING state.
Definition at line 778 of file PCDHCP.C.

References DHCP_request(), DHCP_state_RENEWING(), and my_ip_addr.

void DHCP_state_INIT ( int event ) [static]

DHCP state machine: state INIT.

  • Awaits SEND-TIMEOUT, send discover and enter SELECTING state.
Definition at line 928 of file PCDHCP.C.

References DHCP_discover(), DHCP_state_SELECTING(), and set_timeout().

void DHCP_state_REBINDING ( int event ) [static]

DHCP state machine: state REBINDING.

  • Awaits ACK and enter BOUND state.
  • Awaits NAK and enter INIT state.
Definition at line 838 of file PCDHCP.C.

References change_ip_addr(), dhcp_set_timers(), DHCP_state_BOUND(), DHCP_state_INIT(), my_ip_addr, Random(), and set_timeout().

void DHCP_state_RENEWING ( int event ) [static]

DHCP state machine: state RENEWING.

  • Awaits SEND-TIMEOUT and send request.
  • Awaits T2-TIMEOUT and send request, enter REBINDING state.
  • Awaits ACK and enter BOUND state.
  • Awaits NAK and enter INIT state.
Definition at line 862 of file PCDHCP.C.

References change_ip_addr(), DHCP_request(), dhcp_set_timers(), DHCP_state_BOUND(), DHCP_state_INIT(), DHCP_state_REBINDING(), my_ip_addr, Random(), and set_timeout().

void DHCP_state_REQUESTING ( int event ) [static]

DHCP state machine: state REQUESTING.

  • Awaits SEND-TIMEOUT and send request.
  • Awaits ACK and do ARP check. Enter BOUND if successful.
  • Awaits NAK and enter INIT.
Definition at line 797 of file PCDHCP.C.

References arp_add_server(), DHCP_arp_check(), DHCP_release_decline(), DHCP_request(), dhcp_set_timers(), DHCP_state_BOUND(), DHCP_state_INIT(), my_ip_addr, Random(), and set_timeout().

void DHCP_state_SELECTING ( int event ) [static]

DHCP state machine: state SELECTING.

  • Awaits OFFER, set SEND_TIMER and enter REQUESTING state.
  • Awaits SEND-TIMEOUT, enter INIT state and resend discover.
Definition at line 897 of file PCDHCP.C.

References dhcp::dh_yiaddr, DHCP_offer(), DHCP_state_INIT(), DHCP_state_REQUESTING(), my_ip_addr, Random(), and set_timeout().

BOOL eval_timers ( void ) [static]

Check timers read from config-file and set state according to following rules: now < renewal => BOUND now > renewal && now < rebind => RENEWING now >= rebind && now < lease-end => REBINDING now >= lease-end => INIT-REBOOT.

  • * - * - * -
    Return values:
    FALSE | if lease times expired.
    TRUE | otherwise.
Definition at line 1422 of file PCDHCP.C.

References DHCP_state_BOUND(), and DHCP_state_RENEWING().

int set_request_list ( char * options ) [static]

Parse a list of DHCP-request options from config-file.

e.g DHCP_REQ_LIST = 1,23,24,28,36 Definition at line 1156 of file PCDHCP.C.

References BYTE.

int set_user_class ( const char * value ) [static]

Parse user-class as specified in config-file.

Format is: "DHCP.USERCLASS = value1,value2,...". Build up user_class.data along the way. Definition at line 1222 of file PCDHCP.C.

References BYTE, and dhcp::dh_opt.

int set_vend_class ( const char * value ) [static]

Set vendor class option.

Todo:
Support setting vendor class
Definition at line 1277 of file PCDHCP.C.

int std_write_config ( void ) [static]

Write the transient DHCP configuration to file.

Append to file if found, else create the file.

Note:
"ifdef USE_BUFFERED_IO" ignored here.
Definition at line 1538 of file PCDHCP.C.

References _default_ttl, _inet_ntoa(), DWORD, hostname, my_ip_addr, sin_mask, and tcp_keep_intvl.

Variable Documentation

const BYTE default_request_list[] [static]

Initial value:

 {
             DHCP_OPT_SUBNET_MASK,
             DHCP_OPT_ROUTERS_ON_SNET,
             DHCP_OPT_DNS_SRV,
             DHCP_OPT_COOKIE_SRV,
             DHCP_OPT_LPR_SRV,
             DHCP_OPT_HOST_NAME,
             DHCP_OPT_DOMAIN_NAME,
             DHCP_OPT_IP_DEFAULT_TTL,
             DHCP_OPT_IF_MTU,
             DHCP_OPT_ARP_CACHE_TIMEOUT,
             DHCP_OPT_ETHERNET_ENCAPSULATION,
             DHCP_OPT_TCP_DEFAULT_TTL,
#if defined(USE_BSD_API)
             DHCP_OPT_LOG_SRV,
             DHCP_OPT_NBIOS_NAME_SRV,
             DHCP_OPT_NBIOS_NODE_TYPE,
             DHCP_OPT_NBIOS_SCOPE,
#endif
#if defined(USE_TFTP)
             DHCP_OPT_TFTP_SERVER,
             DHCP_OPT_BOOT_FILENAME
#endif
           }
Definition at line 140 of file PCDHCP.C.

struct DHCP_list request_list [static]

Initial value:

 {
                        (BYTE*) &default_request_list,
                        sizeof (default_request_list)
                      }
Definition at line 165 of file PCDHCP.C.

const struct config_table transient_cfg[] [static]

Initial value:

 {
           { "DHCP.LEASE",    ARG_FUNC,   (void*)set_lease        },
           { "DHCP.RENEW",    ARG_FUNC,   (void*)set_renew        },
           { "DHCP.REBIND",   ARG_FUNC,   (void*)set_rebind       },
           { "DHCP.MY_IP",    ARG_FUNC,   (void*)set_my_ip        },
           { "DHCP.NETMASK",  ARG_FUNC,   (void*)set_netmask      },
           { "DHCP.GATEWAY",  ARG_FUNC,   (void*)set_gateway      },
           { "DHCP.NAMESERV", ARG_FUNC,   (void*)set_nameserv     },
           { "DHCP.SERVER",   ARG_FUNC,   (void*)set_server       },
           { "DHCP.DOMAIN",   ARG_FUNC,   (void*)set_domain       },
           { "DHCP.HOSTNAME", ARG_STRCPY, (void*)hostname         },
#if defined(USE_BSD_API)
           { "DHCP.LOGHOST",  ARG_STRCPY, (void*)&syslog_hostName },
#endif
           { "DHCP.DEF_TTL",  ARG_ATOI,   (void*)&_default_ttl    },
           { "DHCP.TCP_KEEP", ARG_ATOI,   (void*)&tcp_keep_intvl  },
           { NULL,            0,          NULL                    }
         }
Open and parse Wattcp transient configuration.

i.e. values that must be known between consecutive runs of an Watt application. We should write the configured values to this file, and read back on next run to avoid doing DHCP boot/release for every program. Definition at line 1473 of file PCDHCP.C.

Generated on Wed Jan 25 15:42:42 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/PCDHCP.H File Reference

SRC/PCDHCP.H File Reference

Detailed Description

Definition in file PCDHCP.H.

Go to the source code of this file.

Data Structures

struct | DHCP_list
struct | dhcp
struct | DHCP_config

Typedefs

typedef int(* | WattDHCPConfigFunc )(enum DHCP_config_op op, struct DHCP_config *cfg)

Enumerations

enum DHCP_MsgTypes {
DHCP_DISCOVER = 1,
DHCP_OFFER,
DHCP_REQUEST,
DHCP_DECLINE,
DHCP_ACK,
DHCP_NAK,
DHCP_RELEASE,
DHCP_INFORM
}
enum DHCP_Events {
EVENT_OFFER = 1,
EVENT_SEND_TIMEOUT,
EVENT_T1_TIMEOUT,
EVENT_T2_TIMEOUT,
EVENT_ACK,
EVENT_NAK
}
enum DHCP_Options {
DHCP_OPT_PAD = 0,
DHCP_OPT_SUBNET_MASK = 1,
DHCP_OPT_TIME_OFFSET = 2,
DHCP_OPT_ROUTERS_ON_SNET = 3,
DHCP_OPT_TIME_SRV = 4,
DHCP_OPT_NAME_SRV = 5,
DHCP_OPT_DNS_SRV = 6,
DHCP_OPT_LOG_SRV = 7,
DHCP_OPT_COOKIE_SRV = 8,
DHCP_OPT_LPR_SRV = 9,
DHCP_OPT_IMPRESS_SRV = 10,
DHCP_OPT_RES_LOCATION_SRV = 11,
DHCP_OPT_HOST_NAME = 12,
DHCP_OPT_BOOT_FSIZE = 13,
DHCP_OPT_MERIT_DUMPFILE = 14,
DHCP_OPT_DOMAIN_NAME = 15,
DHCP_OPT_SWAP_SRV = 16,
DHCP_OPT_ROOT_PATH = 17,
DHCP_OPT_EXTENTIONS_PATH = 18,
DHCP_OPT_IP_FORWARDING = 19,
DHCP_OPT_NON_LOCAL_SRC_ROUTE = 20,
DHCP_OPT_POLICY_FILTER = 21,
DHCP_OPT_MAX_DGRAM_REASM_SIZE = 22,
DHCP_OPT_IP_DEFAULT_TTL = 23,
DHCP_OPT_PATH_MTU_AGING_TIMEOUT = 24,
DHCP_OPT_PATH_MTU_PLATEAU_TABLE = 25,
DHCP_OPT_IF_MTU = 26,
DHCP_OPT_ALL_SUBNETS_LOCAL = 27,
DHCP_OPT_BROADCAST_ADDR = 28,
DHCP_OPT_PERFORM_MASK_DISCOVERY = 29,
DHCP_OPT_MASK_SUPPLIER = 30,
DHCP_OPT_PERFORM_ROUTER_DISCOVERY = 31,
DHCP_OPT_ROUTER_SOLICITATION_ADDR = 32,
DHCP_OPT_STATIC_ROUTE = 33,
DHCP_OPT_TRAILER_ENCAPSULATION = 34,
DHCP_OPT_ARP_CACHE_TIMEOUT = 35,
DHCP_OPT_ETHERNET_ENCAPSULATION = 36,
DHCP_OPT_TCP_DEFAULT_TTL = 37,
DHCP_OPT_TCP_KEEPALIVE_INTERVAL = 38,
DHCP_OPT_TCP_KEEPALIVE_GARBAGE = 39,
DHCP_OPT_NIS_DOMAIN_NAME = 40,
DHCP_OPT_NIS_SRVS = 41,
DHCP_OPT_NTP_SRVS = 42,
DHCP_OPT_VENDOR_SPECIFIC_INFO = 43,
DHCP_OPT_NBIOS_NAME_SRV = 44,
DHCP_OPT_NBIOS_DGRAM_DIST_SRV = 45,
DHCP_OPT_NBIOS_NODE_TYPE = 46,
DHCP_OPT_NBIOS_SCOPE = 47,
DHCP_OPT_XFONT_SRV = 48,
DHCP_OPT_XDISPLAY_MANAGER = 49,
DHCP_OPT_REQUESTED_IP_ADDR = 50,
DHCP_OPT_IP_ADDR_LEASE_TIME = 51,
DHCP_OPT_OVERLOAD = 52,
DHCP_OPT_MSG_TYPE = 53,
DHCP_OPT_SRV_IDENTIFIER = 54,
DHCP_OPT_PARAM_REQUEST = 55,
DHCP_OPT_MSG = 56,
DHCP_OPT_MAX_MSG_SIZE = 57,
DHCP_OPT_T1_VALUE = 58,
DHCP_OPT_T2_VALUE = 59,
DHCP_OPT_CLASS_ID = 60,
DHCP_OPT_CLIENT_ID = 61,
DHCP_OPT_NIS_DOMAIN = 64,
DHCP_OPT_NIS_SRV_OPT = 65,
DHCP_OPT_TFTP_SERVER = 66,
DHCP_OPT_BOOT_FILENAME = 67,
DHCP_OPT_MOBIP_HOME_AGENTS = 68,
DHCP_OPT_SMTP_SRVS = 69,
DHCP_OPT_POP3_SRVS = 70,
DHCP_OPT_NNTP_SRVS = 71,
DHCP_OPT_WWW_SRVS = 72,
DHCP_OPT_FINGER_SRVS = 73,
DHCP_OPT_IRC_SRVS = 74,
DHCP_OPT_STREET_TALK_SRVS = 75,
DHCP_OPT_STDA_SRVS = 76,
DHCP_OPT_USER_CLASS = 77,
DHCP_OPT_GRUB_MENU = 150,
DHCP_OPT_END = 255
}
enum DHCP_config_op {
DHCP_OP_READ = 0,
DHCP_OP_WRITE = 1,
DHCP_OP_ERASE = 2
}

Functions

WattDHCPConfigFunc | dhcp_set_config_func (WattDHCPConfigFunc fn)
Sets up an application hook for doing DHCP operations (DHCP_config_op).
int | DHCP_do_boot (void)
Our first time (booting) DHCP handler.
void | DHCP_init (void)
Initialises the DHCP config-parser.
W32_FUNC void | DHCP_release (BOOL force)
Possibly send a DHCP release.
W32_FUNC int | DHCP_read_config (void)
Called from watt_sock_init() after "\c WATTCP.CFG" has been parsed.
W32_FUNC DWORD | DHCP_get_server (void)
Return current DHCP server address.

Variables

const BOOL | dhcp_did_gratuitous_arp

Function Documentation

int DHCP_do_boot ( void )

Our first time (booting) DHCP handler.

Only called if:

  • we don't have a WATTCP.CFG file
  • or we specified "MY_IP = DHCP".
  • or reading a previous W32DHCP.TMP file with transient config failed.

It doesn't hurt that it is blocking. Definition at line 1025 of file PCDHCP.C.

References addwattcpd(), dhcp_fsm(), dhcp_open(), DHCP_state_BOUND(), DHCP_state_INIT(), erase_config(), my_ip_addr, set_timeout(), sin_mask, tcp_tick(), and write_config().

W32_FUNC int DHCP_read_config ( void )

Called from watt_sock_init() after "\c WATTCP.CFG" has been parsed.

Open and parse transient configuration from 'config_file' or call user-defined function to read transient configuration. Definition at line 1727 of file PCDHCP.C.

References dhcp_open(), dhcp_set_timers(), eval_timers(), and sock_type::udp.

W32_FUNC void DHCP_release ( BOOL force )

Possibly send a DHCP release.

  • force If TRUE, release unconditionally.
    Note:
    Send release if we are configured and remaining lease is below minimum lease (DHCP_MIN_LEASE = 10 sec).
Definition at line 690 of file PCDHCP.C.

References delwattcpd(), dhcp_fsm(), DHCP_release_decline(), and sock_close().

Generated on Wed Jan 25 15:42:42 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/PCICMP.C File Reference

SRC/PCICMP.C File Reference

Detailed Description

ICMP for IPv4 (RFC 792).

Definition in file PCICMP.C.

Go to the source code of this file.

Data Structures

struct | _pkt

Functions

void | icmp_print (int dbg_lvl, const char *msg, DWORD src)
void | icmp_bogus (const in_Header *ip, int type, const char *msg)
Print info about bogus and possibly dangerous ICMP messages.
BOOL | icmp_check (const in_Header *ip, int type)
Check if ip-source is a (directed) broadcast address.
int | icmp_send (struct _pkt *pkt, DWORD src, DWORD dest, int length)
Format and send a ICMP packet.
int | icmp_send_unreach (const in_Header *ip, int code)
Send an ICMP destination/protocol unreachable back to 'ip->source'.
int | icmp_send_timexceed (const in_Header *ip, const void *mac_dest)
Send an "ICMP Time Exceeded" (reassebly timeout) back to 'ip->source'.
int | icmp_send_mask_req (void)
int | icmp_echo_reply (const in_Header *ip, const union ICMP_PKT *req, unsigned len)
void | icmp_redirect (const union ICMP_PKT *icmp, const in_Header *ip, const in_Header *orig_ip, int code)
Handle ICMP_REDIRECT messages.
void | icmp_handler (const in_Header *ip, BOOL broadcast)
Handler for incoming ICMP packets.
void | icmp_doredirect (const char *value)
Determine which protocols we shall act upon when ICMP redirect is received.

Variables

const char * | icmp_type_str [ICMP_MAXTYPE+1]
const char * | icmp_unreach_str [16]
const char * | icmp_redirect_str [4]
const char * | icmp_exceed_str [2]
struct {
char icmp
char igmp
char udp
char tcp
} do_redirect
WORD | addr_mask_id = 0
Send an ICMP Address Mask Request as link-layer + IP broadcast.
WORD | addr_mask_seq = 0

Function Documentation

void icmp_bogus | ( | const in_Header * | ip,
 |  | int | type,
 |  | const char * | msg
 | ) | [static]

Print info about bogus and possibly dangerous ICMP messages.

e.g. "ICMP: (144.133.122.111) Bogus Redirect; GW = 111.110.109.108" Definition at line 127 of file PCICMP.C.

References in_Header::source.

BOOL icmp_check | ( | const in_Header * | ip,
 |  | int | type
 | ) | [static]

Check if ip-source is a (directed) broadcast address.

Some hacker may try to create a broadcast storm. Also check for null source address (0.0.0.0). Broadcast destination is already filtered out by icmp_handler(). Definition at line 144 of file PCICMP.C.

References in_Header::destination, DWORD, icmp_bogus(), sin_mask, and in_Header::source.

void icmp_handler | ( | const in_Header * | ip,
 |  | BOOL | broadcast
 | ) |

Handler for incoming ICMP packets.

Todo:
Handle cancelling raw sockets

send reply?

should store

send reply

send reply upwards

<

<

<

< Definition at line 377 of file PCICMP.C.

References _do_mask_req, _tcp_cancel(), _udp_cancel(), add_ping(), addr_mask_id, block_icmp, BYTE, in_Header::destination, DWORD, icmp_bogus(), icmp_redirect(), in_Header::length, in_Header::proto, set_timeout(), sin_mask, in_Header::source, UINT, and WORD.

int icmp_send | ( | struct _pkt * | pkt,
 |  | DWORD | src,
 |  | DWORD | dest,
 |  | int | length
 | ) | [static]

Format and send a ICMP packet.

Note:
: src and dest are on network order.
Definition at line 180 of file PCICMP.C.

int icmp_send_unreach | ( | const in_Header * | ip,
 |  | int | code
 | ) |

Send an ICMP destination/protocol unreachable back to 'ip->source'.

Limit the rate of these to 20 per second. Ref. RFC-1812. Definition at line 195 of file PCICMP.C.

References _eth_formatpacket(), BYTE, chk_timeout(), DWORD, icmp_check(), icmp_send(), in_Header::length, and set_timeout().

Variable Documentation

WORD addr_mask_id = 0 [static]

Send an ICMP Address Mask Request as link-layer + IP broadcast.

Even if we know our address, we send with src = 0.0.0.0. Definition at line 259 of file PCICMP.C.

const char* icmp_exceed_str[2]

Initial value:

 {
      __LANG("TTL exceeded in transit"),
      __LANG("Frag ReAsm time exceeded")
    }
Definition at line 81 of file PCICMP.C.

const char* icmp_redirect_str[4]

Initial value:

 {
      __LANG("Redirect for Network"),
      __LANG("Redirect for Host"),
      __LANG("Redirect for TOS and Network"),
      __LANG("Redirect for TOS and Host")
    }
Definition at line 72 of file PCICMP.C.

const char* icmp_type_str[ICMP_MAXTYPE+1]

Initial value:

 {
      __LANG("Echo Reply"),  "1", "2",
      __LANG("Destination Unreachable"),
      __LANG("Source Quench"),
      __LANG("Redirect"),    "6", "7",
      __LANG("Echo Request"),
      __LANG("Router Advert"),
      __LANG("Router Solic"),
      __LANG("TTL exceeded"),
      __LANG("Param Problem"),
      __LANG("Timestamp Message"),
      __LANG("Timestamp Reply"),
      __LANG("Info Request"),
      __LANG("Info Reply"),
      __LANG("Mask Request"),
      __LANG("Mask Reply")
    }
Definition at line 31 of file PCICMP.C.

const char* icmp_unreach_str[16]

Initial value:

 {
      __LANG("Network Unreachable"),
      __LANG("Host Unreachable"),
      __LANG("Protocol Unreachable"),
      __LANG("Port Unreachable"),
      __LANG("Fragmentation needed and DF set"),
      __LANG("Source Route Failed"),
      __LANG("Network unknown"),
      __LANG("Host unknown"),
      __LANG("Source host isolated"),
      __LANG("Net-access denied"),
      __LANG("Host-access denied"),
      __LANG("Bad TOS for net"),
      __LANG("Bad TOS for host"),
      __LANG("Admin prohibited"),
      __LANG("Host precedence violation"),
      __LANG("Precedence cutoff")
    }
Definition at line 51 of file PCICMP.C.

Generated on Wed Jan 25 15:42:42 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/PCICMP.H File Reference

SRC/PCICMP.H File Reference

Detailed Description

Definition in file PCICMP.H.

Go to the source code of this file.

Data Structures

struct | ICMP_unused
struct | ICMP_pointer
struct | ICMP_ip
struct | ICMP_echo
struct | ICMP_timestamp
struct | ICMP_info
struct | ICMP_addr_mask
struct | ICMP_traceroute
struct | ICMP_needfrag
union | ICMP_PKT
struct | ping_pkt

Typedefs

typedef ICMP_PKT | ICMP_PKT

Functions

W32_FUNC DWORD | _chk_ping (DWORD host, DWORD *ping_num)
Check for ICMP echo reply in ping-cache.
void | icmp_handler (const in_Header *ip, BOOL broadcast)
Handler for incoming ICMP packets.
void | icmp_doredirect (const char *value)
Determine which protocols we shall act upon when ICMP redirect is received.
int | icmp_send_timexceed (const in_Header *ip, const void *mac_dest)
Send an "ICMP Time Exceeded" (reassebly timeout) back to 'ip->source'.
int | icmp_send_unreach (const in_Header *ip, int code)
Send an ICMP destination/protocol unreachable back to 'ip->source'.
int | icmp_send_mask_req (void)

Variables

const char * | icmp_type_str [ICMP_MAXTYPE+1]
const char * | icmp_unreach_str [16]
const char * | icmp_redirect_str [4]
const char * | icmp_exceed_str [2]

Function Documentation

W32_FUNC DWORD _chk_ping | ( | DWORD | host,
 |  | DWORD * | number
 | ) |

Check for ICMP echo reply in ping-cache.

Return values:
reply | time in system ticks.
(DWORD)-1 | on failure
Definition at line 172 of file PCPING.C.

void icmp_handler | ( | const in_Header * | ip,
 |  | BOOL | broadcast
 | ) |

Handler for incoming ICMP packets.

Todo:
Handle cancelling raw sockets

send reply?

should store

send reply

send reply upwards

<

<

<

< Definition at line 377 of file PCICMP.C.

References _do_mask_req, _tcp_cancel(), _udp_cancel(), add_ping(), addr_mask_id, block_icmp, BYTE, in_Header::destination, DWORD, icmp_bogus(), icmp_redirect(), in_Header::length, in_Header::proto, set_timeout(), sin_mask, in_Header::source, UINT, and WORD.

int icmp_send_unreach | ( | const in_Header * | ip,
 |  | int | code
 | ) |

Send an ICMP destination/protocol unreachable back to 'ip->source'.

Limit the rate of these to 20 per second. Ref. RFC-1812. Definition at line 195 of file PCICMP.C.

References _eth_formatpacket(), BYTE, chk_timeout(), DWORD, icmp_check(), icmp_send(), in_Header::length, and set_timeout().

Generated on Wed Jan 25 15:42:42 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/PCICMP6.C File Reference

SRC/PCICMP6.C File Reference

Detailed Description

ICMP routines for IPv6 (RFC-2461/2463).

Copyright (c) 1997-2002 Gisle Vanem <giva@bgnett.no>

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. All advertising materials mentioning features or use of this software must display the following acknowledgement: This product includes software developed by Gisle Vanem Bergen, Norway.

THIS SOFTWARE IS PROVIDED BY ME (Gisle Vanem) AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL I OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

Version

0.5 : Aug 01, 2002 : G. Vanem - created

Lot of works remains to get routing working.

Definition in file PCICMP6.C.

Go to the source code of this file.

Generated on Wed Jan 25 15:42:42 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/PCICMP6.H File Reference

SRC/PCICMP6.H File Reference

Detailed Description

Definition in file PCICMP6.H.

Go to the source code of this file.

Data Structures

struct | ICMP6_unused
struct | ICMP6_route_sol
struct | ICMP6_route_adv
struct | ICMP6_pointer
struct | ICMP6_MTU
struct | ICMP6_echo
struct | ICMP6_nd_adv
struct | ICMP6_nd_ra
struct | ICMP6_nd_sol
union | ICMP6_PKT
struct | icmp6_cache

Typedefs

typedef ICMP6_PKT | ICMP6_PKT

Enumerations

enum ND_cacheState {
ND_CACHE_UNUSED,
ND_CACHE_INCOMPLETE,
ND_CACHE_REACHABLE,
ND_CACHE_PROBE,
ND_CACHE_MAX
}

Functions

void | icmp6_handler (const in6_Header *ip)
void | icmp6_unreach (const in6_Header *ip, int code)
int | icmp6_neigh_solic (const void *addr, eth_address *eth)
int | icmp6_neighbor_advert (const eth_address *eth)
int | icmp6_router_solicitation (void)
BOOL | icmp6_add_gateway4 (void)
icmp6_cache * | icmp6_ncache_lookup (const void *ip)
icmp6_cache * | icmp6_ncache_insert (const void *ip, const void *eth)
icmp6_cache * | icmp6_ncache_insert_fix (const void *ip, const void *eth)

Variables

W32_DATA DWORD | icmp6_6to4_gateway

Generated on Wed Jan 25 15:42:42 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/PCINTR.C File Reference

SRC/PCINTR.C File Reference

Detailed Description

Background network ISR poller.

Add interrupt based processing, improve performance during disk slowdowns

  • wintr_init() - call once
  • wintr_shutdown() - called automatically
  • wintr_enable() - enable interrupt based calls
  • wintr_disable() - diable interrupt based calls (default)
  • (*wintr_chain)() - a place to chain in your own calls, must live within something like 1K stack

Definition in file PCINTR.C.

Go to the source code of this file.

Functions

void | find_DOS_flags (void)
BOOL | DOS_is_idle (void)
void | stack_probe (void)
BOOL | wintr_enable (void)
void | wintr_disable (void)
void | NewTimer (void)
void | wintr_shutdown (void)
void | wintr_init (void)
void | NewTimer (int sig)
void (__interrupt __far *oldint)()
void | NewTimerPre (void)

Variables

void(* | wintr_chain )(void)=NULL
BOOL | on_isr8
BOOL | inside_isr8 = FALSE
WORD | indos_flag_seg
WORD | indos_flag_ofs
WORD | crit_err_seg
WORD | crit_err_ofs
void(* | old_sigalrm )(int)
UINT | locstack [STK_SIZE]
REALPTR | oldint
REALPTR | timer_cb
RMC_BLK | rmRegs
WORD | our_ds

Generated on Wed Jan 25 15:42:42 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/PCMULTI.C File Reference

SRC/PCMULTI.C File Reference

Detailed Description

IP Multicasting extensions as per RFC 1112 (IGMP v1).

These extensions include routines to detect multicast addresses, transform Multicast IP addresses to Multicast Ethernet addresses, as well as a mechanism to join and leave multicast groups.

Jim Martin Rutgers University - RUCS-TD/NS jim@noc.rutgers.edu 6/6/93

Todo:
Support IGMP v3 (draft-ietf-idmr-igmp-v3-??.txt)

Definition in file PCMULTI.C.

Go to the source code of this file.

Data Structures

struct | IGMP_PKT

Functions

void | check_mcast_reports (void)
__inline BOOL | is_eth_multicast (const in_Header *ip)
int | multi_to_eth (DWORD ip, eth_address *mac)
int | join_mcast_group (DWORD ip)
int | leave_mcast_group (DWORD ip)
int | num_multicast_active (void)
void | igmp_handler (const in_Header *ip, BOOL broadcast)
int | igmp_report (DWORD ip)

Variables

int | _multicast_on = 0
int | _multicast_intvl = 0
MultiCast | mcast_list [IPMULTI_SIZE]
BOOL | daemon_on = FALSE

Generated on Wed Jan 25 15:42:42 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/PCMULTI.H File Reference

SRC/PCMULTI.H File Reference

Detailed Description

Definition in file PCMULTI.H.

Go to the source code of this file.

Data Structures

struct | MultiCast
Multicast internal structure. More...

Functions

int | join_mcast_group (DWORD ip)
int | leave_mcast_group (DWORD ip)
int | multi_to_eth (DWORD ip, eth_address *eth)
int | num_multicast_active (void)
void | igmp_handler (const in_Header *ip, BOOL brdcast)

Variables

int | _multicast_on
int | _multicast_intvl

Generated on Wed Jan 25 15:42:42 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/PCPING.C File Reference

SRC/PCPING.C File Reference

Detailed Description

Simple ping client.

Definition in file PCPING.C.

Go to the source code of this file.

Data Structures

struct | ping_cache

Functions

typedef | int (MS_CDECL *CmpFunc)(const void *
int | _ping (DWORD host, DWORD countnum, const BYTE *pattern, size_t len)
Format and send an ICMP echo request (ping).
int MS_CDECL | compare (const struct ping_cache *a, const struct ping_cache *b)
Compare two entries in ping-cache.
void | add_ping (DWORD host, DWORD time, DWORD number)
Add an ICMP echo reply to the ping-cache.
DWORD | _chk_ping (DWORD host, DWORD *number)
Check for ICMP echo reply in ping-cache.

Variables

ping_cache | pcache

Function Documentation

DWORD _chk_ping | ( | DWORD | host,
 |  | DWORD * | number
 | ) |

Check for ICMP echo reply in ping-cache.

Return values:
reply | time in system ticks.
(DWORD)-1 | on failure
Definition at line 172 of file PCPING.C.

References DWORD, ping_cache::host, ping_cache::number, and ping_cache::time.

int _ping | ( | DWORD | host,
 |  | DWORD | countnum,
 |  | const BYTE * | pattern,
 |  | size_t | len
 | ) |

Format and send an ICMP echo request (ping).

  • countnum is the ICMP index value.
  • pattern optional data that will be sent.
  • len length of pattern data.
    Return values:
    0 if ARP fails or error in lower layer.
    Note:
    if pattern or len is 0, only an 12 byte ICMP echo header will be sent.

    Sends fragments if needed.

Definition at line 48 of file PCPING.C.

Generated on Wed Jan 25 15:42:42 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/PCPING.H File Reference

SRC/PCPING.H File Reference

Detailed Description

Definition in file PCPING.H.

Go to the source code of this file.

Functions

W32_FUNC int | _ping (DWORD host, DWORD count, const BYTE *patt, size_t len)
Format and send an ICMP echo request (ping).
W32_FUNC DWORD | _chk_ping (DWORD host, DWORD *number)
Check for ICMP echo reply in ping-cache.
W32_FUNC void | add_ping (DWORD host, DWORD tim, DWORD number)
Add an ICMP echo reply to the ping-cache.

Function Documentation

W32_FUNC DWORD _chk_ping | ( | DWORD | host,
 |  | DWORD * | number
 | ) |

Check for ICMP echo reply in ping-cache.

Return values:
reply | time in system ticks.
(DWORD)-1 | on failure
Definition at line 172 of file PCPING.C.

W32_FUNC int _ping | ( | DWORD | host,
 |  | DWORD | countnum,
 |  | const BYTE * | pattern,
 |  | size_t | len
 | ) |

Format and send an ICMP echo request (ping).

  • countnum is the ICMP index value.
  • pattern optional data that will be sent.
  • len length of pattern data.
    Return values:
    0 if ARP fails or error in lower layer.
    Note:
    if pattern or len is 0, only an 12 byte ICMP echo header will be sent.

    Sends fragments if needed.

Definition at line 48 of file PCPING.C.

References _arp_resolve(), _default_tos, _eth_formatpacket(), _ping(), BYTE, eth_address, set_timeout(), sin_mask, and WORD.

Generated on Wed Jan 25 15:42:42 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/PCPKT.C File Reference

SRC/PCPKT.C File Reference

Detailed Description

Packet Driver interface for WatTCP/Watt-32.

Heavily modified and extended for DOSX by G.Vanem <giva@bgnett.no>

Definition in file PCPKT.C.

Go to the source code of this file.

Functions

void | get_init_stats (void)
void (__cdecl _far *pkt_enque_ptr)(BYTE _far *buf
int | setup_rmode_callback (void)
int | lock_code_and_data (void)
int | unlock_code_and_data (void)
int | find_vector (int first, int num)
int | setup_pkt_inf (void)
void | get_rmode_data (void *dest, unsigned size, WORD seg, WORD ofs)
Return PKTDRVR data at seg:ofs.
BOOL | pkt_api_entry (IREGS *reg, unsigned called_from_line)
The API entry to the network link-driver.
const char * | pkt_strerror (int code)
Return textual error representing error-code.
void | dump_asm4 (void)
void * | pkt_tx_buf (void)
Return address of DOS memory Tx-buffer.
int | pkt_set_access (void)
Setup the receiver upcall handler.
int | pkt_drvr_info (void)
Fetch the PKTDRVR information.
int | pkt_get_params (struct PktParameters *params)
Get PKTDRVR parameters (MTU, version etc.).
int | pkt_get_mtu (void)
Return PKTDRVR maximum-transmit-units (MTU).
int | pkt_get_mac_len (void)
Return length of MAC address.
int | pkt_get_api_ver (DWORD *ver)
Return version of spec.
int | pkt_get_drvr_ver (DWORD *ver)
Return version of PKTDRVR.
int | pkt_get_vector (void)
Return PKTDRVR vector.
int | pkt16_drvr_init (mac_address *mac_addr)
Called from pkt_eth_init() to search for PKTDRVR.
int | pkt_release_handle (WORD handle)
Release the allocated protocol handle.
int | pkt_reset_handle (WORD handle)
Reset the driver-state associated with handle.
void | release_callback (void)
void | release_real_mem (void)
Release allocated DOS memory.
int DTOR | pkt_release (void)
void | pkt_enqueue (unsigned rxBuf, WORD rxLen) static void __cdecl _far pkt_enqueue(BYTE _far *rxBuf
Enqueue a received packet into '_pkt_inf->pkt_queue'.
int | pkt_send (const void *tx, int length)
Send a link-layer frame.
int | pkt_get_addr (mac_address *eth)
Return the MAC address.
int | pkt_set_addr (const void *addr)
Set a new MAC source address.
int | pkt_get_stats (struct PktStats *stats, struct PktStats *total)
Get PKTDRVR statistics.
int | pkt_get_vjstats (struct slcompress *vjstats)
int | pkt_get_cstate (struct cstate *cs, WORD cstate_ofs)
int | pkt_buf_wipe (void)
Clear the receive queue.
void | pkt_free_pkt (const void *pkt)
Release a packet from the receive queue.
int | pkt_waiting (void)
Return number of packets waiting in queue.
DWORD | pkt_dropped (void)
Return number of packets dropped.
void | set_txmode (const char *value)
int | parse_config_pass_1 (void)
Search WATTCP.CFG file for "PKT.VECTOR = 0x??" etc.
int | pkt_eth_init (mac_address *addr)
Initialise Packet driver interface.
BOOL | check_intr_num (WORD intr_num)
Check a single interrupt vector for signature string "PKT DRVR".
void | _unlock (const void *addr, DWORD size)
int | pkt_set_rcv_mode (int mode)
Sets the receive mode of the interface.
int | pkt_get_rcv_mode (void)
Gets the receive mode of the interface (can never be mode 0).
int | pkt_get_multicast_list (mac_address *listbuf, int *lenp)
Gets the current list of multicast addresses from the PKTDRVR.
int | pkt_set_multicast_list (const void *listbuf, int len)
Sets the list of multicast addresses for which the PKTDRVR is responsible.

Variables

WORD | _pktdevclass = PDCLASS_UNKNOWN
Ethernet, Token, FDDI etc.
WORD | _pkt_ip_ofs = 0
ofs from link-layer head to ip
WORD | _pkt_type_ofs = 0
ofs from link-layer head to type
BOOL | _pktserial = FALSE
using serial driver, SLIP/PPP
BYTE | _pktdevlevel = 1
Device level.
int | _pkt_rxmode = RXMODE_BROADCAST
active receive mode
int | _pkt_rxmode0 = -1
startup receive mode
int | _pkt_errno = 0
error code set in pcpkt.c API
char * | pkt_error = NULL
int | _pkt_forced_rxmode = -1
char | _pktdrvrname [20] = "unknown"
pkt_info * | _pkt_inf = NULL
module data that will be locked
char | pkt_sign [] = "PKT DRVR"
WORD | pkt_interrupt = 0
DWORD | pkt_drop_cnt = 0
BYTE | pkt_txretries = 2
int | pkt_txwait = 0
BOOL | pkt_use_near = FALSE
BOOL | pkt_do_reset = FALSE
int | pkt_drvr_ver = 0
int | pkt_num_rx_bufs = RX_BUFS
PktStats | init_stats
PktParameters | pkt_params
BOOL | got_params = FALSE
BOOL | async_txmode = FALSE
int | async_txtime = -1
REALPTR | rm_base
_go32_dpmi_seginfo | rm_cb
WORD | pkt_inf_sel
WORD | len
WORD | cstate_dseg = 0
Get VJ-compression statistics from pkt-driver.

Function Documentation

int parse_config_pass_1 ( void ) [static]

Search WATTCP.CFG file for "PKT.VECTOR = 0x??" etc.

Accept "0x20 - 0xFF". Definition at line 1459 of file PCPKT.C.

References ARG_ATOB, ARG_ATOI, ARG_ATOX_B, and ARG_FUNC.

int pkt16_drvr_init ( mac_address * mac_addr ) [static]

Called from pkt_eth_init() to search for PKTDRVR.

  • Checks register struct size (for non-DOSX targets).
  • Searches for the PKTDRVR interrupt.
  • Allocates '_pkt_inf' structure.
  • Sets up a real-mode callback and lock code/data (DOSX targets).
  • Fetches PKTDRVR information.
  • Sets up driver to call our real-mode callback.
  • Fetches local MAC address.
  • Fetches parameters and initialise statistics.
Definition at line 548 of file PCPKT.C.

References _pkt_errno, _pkt_rxmode, _pkt_rxmode0, _pktdevlevel, _pktserial, pkt_drvr_info(), pkt_get_addr(), pkt_get_params(), pkt_get_rcv_mode(), pkt_release(), pkt_set_access(), pkt_set_rcv_mode(), pkt_strerror(), RXMODE_PROMISCOUS, and setup_pkt_inf().

BOOL pkt_api_entry | ( | IREGS * | reg,
 |  | unsigned | line
 | ) | [static]

The API entry to the network link-driver.

Use either protected mode interface via a call to dynamically loaded module (not yet) or issue an interrupt for the real-mode PKTDRVR.

Return TRUE if CARRY is clear, else set _pkt_errno and return FALSE.

Todo:
Use 32-bit API; accessing card via pmode driver
Definition at line 1946 of file PCPKT.C.

References _pkt_errno.

int pkt_drvr_info ( void ) [static]

Fetch the PKTDRVR information.

Device level, class and name. Definition at line 371 of file PCPKT.C.

References _pkt_errno, _pkt_inf, _pkt_ip_ofs, _pkt_type_ofs, _pktdevclass, _pktdevlevel, _pktserial, get_rmode_data(), pkt_info::is_serial, pkt_info::pkt_ip_ofs, and pkt_info::pkt_type_ofs.

void pkt_enqueue | ( | unsigned | rxBuf,
 |  | WORD | rxLen
 | ) | [static]

Enqueue a received packet into '_pkt_inf->pkt_queue'.

This routine is called from pkt_receiver_rm/_pm(). The packet has been copied to rx_buffer (in DOS memory) by the packet-driver. We now must copy it to correct queue. Interrupts are disabled on entry.

Note 1: For real-mode targets SS and SP have been setup to a small work stack in asmpkt.asm (SS = CS). The stack can only take 64 pushes, hence use few local variables here.

Note 2: The C-compiler must be told NOT to use register calling for this routine (MUST use __cdecl) because it's called from asmpkt.asm via `pkt_enque_ptr' function pointer.

Note 3: Watcom/DOS4GW targets doesn't use real->prot mode upcall (RMCB), but does the following in asmpkt4.asm instead.

Note 4: For DOSX targets, all code from pkt_enqueue() down to _pkt_end() must be locked in memory.

HACK: For real-mode targets this routine is called via the `pkt_enque_ptr' function pointer. This was the only way I could avoid a fixup error for small-model programs.

int pkt_eth_init ( mac_address * addr )

Initialise Packet driver interface.

First determine vector to use; if WATTCP.CFG specifies a "PKT.VECTOR = 0xNN", use that vector, else search for PKTDRVR between PKT_FIRST_VEC and PKT_LAST_VEC (0x60 - 0x80). If the driver is outside this range, user must specify one with "PKT.VECTOR = 0x??".

If DOSX, probe and initialise protected-mode driver (not operational). Call pkt16_drvr_init() to initialise API. Definition at line 1499 of file PCPKT.C.

void pkt_free_pkt ( const void * pkt )

Release a packet from the receive queue.

If USE_FAST_PKT, pkt has already been free'd. Just update drop count. Definition at line 1381 of file PCPKT.C.

int pkt_get_api_ver ( DWORD * ver )

Return version of spec.

this PKTDRVR conforms to.

Return values:
-1 on error. Return major version in upper 8 bit, minor in lower.
Definition at line 508 of file PCPKT.C.

int pkt_get_mac_len ( void )

Return length of MAC address.

Return values:
6 For Ethernet.
Definition at line 493 of file PCPKT.C.

References _pktdevclass, and arcnet_address.

int pkt_get_mtu ( void )

Return PKTDRVR maximum-transmit-units (MTU).

Note:
This includes length of MAC-header.
Definition at line 478 of file PCPKT.C.

int pkt_get_multicast_list | ( | mac_address * | listbuf,
 |  | int * | lenp
 | ) |

Gets the current list of multicast addresses from the PKTDRVR.

  • listbuf is the buffer into which the list is placed
  • len on input: length of listbuf on output: length of list returned
Return values:
0 | upon error - _pkt_errno is set
1 | if retrieval was successful,
Definition at line 2086 of file PCPKT.C.

int pkt_get_rcv_mode ( void )

Gets the receive mode of the interface (can never be mode 0).

Return values:
!0 | Okay - _pkt_errno is 0, _pkt_rxmode and retval is current mode.
0 | Error - _pkt_errno is set.
_pkt_rxmode is one of the following modes: (upon successful return)
  • 1 - turn off receiver
  • 2 - receive only packets sent to this interface
  • 3 - mode 2 plus broadcast packets (default)
  • 4 - mode 3 plus limited multicast packets
  • 5 - mode 3 plus all multicast packets
  • 6 - all packets (a.k.a promiscuous mode)
Definition at line 2048 of file PCPKT.C.

int pkt_get_stats | ( | struct PktStats * | stats,
 |  | struct PktStats * | total
 | ) |

Get PKTDRVR statistics.

Return both 'stats' for current session and 'total' statistics since driver loaded. Definition at line 1275 of file PCPKT.C.

int DTOR pkt_release ( void )

Todo:
We might be called between 1st and 2nd packet-driver upcall. Need to wait for 2nd upcall to finish or else freeing the RMCB too early could cause a crash or a stuck PKTDRVR.
Definition at line 808 of file PCPKT.C.

int pkt_send | ( | const void * | tx,
 |  | int | length
 | ) |

Send a link-layer frame.

For PPP/SLIP 'tx' contains no MAC-header. For EtherNet, Token-Ring, ARCNET and FDDI, 'tx' contains the complete frame.

Todo:
Change this so that we doesn't retry if the driver was stuck for "too long". I've seen drivers using approx. 100 msec on each iteration below. Retrying if the driver is stuck is not worth the time.

Todo:
estimate max time this should take
Definition at line 1060 of file PCPKT.C.

int pkt_set_access ( void ) [static]

Setup the receiver upcall handler.

The handler is called for all packets matching current receive mode. In mode 3 all broadcast and directed packets. Definition at line 321 of file PCPKT.C.

References _pkt_errno, _pkt_inf, _pktdevclass, pkt_info::handle, pkt_info::rm_seg, and WORD.

int pkt_set_multicast_list | ( | const void * | listbuf,
 |  | int | len
 | ) |

Sets the list of multicast addresses for which the PKTDRVR is responsible.

  • listbuf is the buffer containing the list
  • len is the length of listbuf
Return values:
0 | upon error - _pkt_errno is set
1 | if set was successful
Definition at line 2133 of file PCPKT.C.

int pkt_set_rcv_mode ( int mode )

Sets the receive mode of the interface.

mode is one of the following modes:

  • 1 - turn off receiver
  • 2 - receive only packets sent to this interface
  • 3 - mode 2 plus broadcast packets <default>
  • 4 - mode 3 plus limited multicast packets
  • 5 - mode 3 plus all multicast packets
  • 6 - all packets (AKA promiscuous mode)

Return values:
0 | - upon error - _pkt_errno is set
1 | - if the mode was set successfully
Definition at line 2004 of file PCPKT.C.

void * pkt_tx_buf ( void )

Return address of DOS memory Tx-buffer.

For DOS4GW/X32VM (and djgpp with near-ptrs) targets, return near address of transmit buffer located in DOS memory. Definition at line 291 of file PCPKT.C.

int setup_pkt_inf ( void ) [static]

Todo:
Make dynamic allocation based on 'pkt_num_rx_bufs'. Allocate multiple 64kB blocks if needed (would involve messy 16-bit coding in asmpkt.nas).
Definition at line 1853 of file PCPKT.C.

References _pkt_inf, pkt_info::dos_ds, pkt_ringbuf::dos_ofs, DWORD, pkt_info::pkt_queue, pkt_info::rx_buf, and pkt_info::use_near_ptr.

Variable Documentation

WORD cstate_dseg = 0 [static]

Get VJ-compression statistics from pkt-driver.

Only DOS-PPP ver 0.6+ supports the PD_GET_VJSTATS (0x81) call. Definition at line 1329 of file PCPKT.C.

Generated on Wed Jan 25 15:42:42 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/PCPKT.H File Reference

SRC/PCPKT.H File Reference

Detailed Description

Definition in file PCPKT.H.

Go to the source code of this file.

Data Structures

struct | PktStats
struct | PktParameters
struct | cstate
struct | slcompress
struct | async_iocb
struct | pkt_info
Placeholder for vital data accessed by capture thread. More...

Enumerations

enum ReceiveModes {
RXMODE_OFF = 1,
RXMODE_DIRECT = 2,
RXMODE_BROADCAST = 3,
RXMODE_MULTICAST1 = 4,
RXMODE_MULTICAST2 = 5,
RXMODE_PROMISCOUS = 6
}

Functions

W32_FUNC const char * | pkt_strerror (int code)
Return textual error representing error-code.
W32_FUNC DWORD | pkt_dropped (void)
Return number of packets dropped.
int | pkt_eth_init (mac_address *eth)
Initialise Packet driver interface.
int | pkt_release (void)
int | pkt_release_handle (WORD)
Release the allocated protocol handle.
int | pkt_reset_handle (WORD handle)
Reset the driver-state associated with handle.
int | pkt_send (const void *tx, int length)
Send a link-layer frame.
int | pkt_buf_wipe (void)
Clear the receive queue.
void | pkt_free_pkt (const void *pkt)
Release a packet from the receive queue.
int | pkt_waiting (void)
Return number of packets waiting in queue.
int | pkt_set_addr (const void *eth)
Set a new MAC source address.
int | pkt_get_addr (mac_address *eth)
Return the MAC address.
int | pkt_get_mtu (void)
Return PKTDRVR maximum-transmit-units (MTU).
int | pkt_get_drvr_ver (DWORD *ver)
Return version of PKTDRVR.
int | pkt_get_api_ver (DWORD *ver)
Return version of spec.
int | pkt_get_vector (void)
Return PKTDRVR vector.
int | pkt_set_rcv_mode (int mode)
Sets the receive mode of the interface.
int | pkt_get_rcv_mode (void)
Gets the receive mode of the interface (can never be mode 0).
int | pkt_get_multicast_list (mac_address *listbuf, int *len)
Gets the current list of multicast addresses from the PKTDRVR.
int | pkt_set_multicast_list (const void *listbuf, int len)
Sets the list of multicast addresses for which the PKTDRVR is responsible.
int | pkt_get_params (struct PktParameters *params)
Get PKTDRVR parameters (MTU, version etc.).
int | pkt_get_stats (struct PktStats *stats, struct PktStats *total)
Get PKTDRVR statistics.
int | pkt_get_vjstats (struct slcompress *vjstats)
int | pkt_get_cstate (struct cstate *cs, WORD cstate_ofs)
void * | pkt_tx_buf (void)
Return address of DOS memory Tx-buffer.
int | pkt_append_recv (const void *tx, unsigned len)
int | pkt_buffers_used (void)
int | pkt_test_upcall (void)
void | pkt_dump_real_mem (void)
pkt_rx_element * | pkt_poll_recv (void)
void | __dj_movedata (void)
void | __movedata (unsigned src_sel, unsigned src_ofs, unsigned dst_sel, unsigned dst_ofs, size_t bytes)

Variables

W32_DATA WORD | _pktdevclass
PKTDRVR class.
W32_DATA WORD | _pkt_ip_ofs
Offset from MAC-header to IP-header.
W32_DATA BOOL | _pktserial
Driver is a serial (SLIP/PPP) driver.
W32_DATA char | _pktdrvrname []
Name of PKDRVR.
W32_DATA int | _pkt_rxmode
Current PKTDRVR Rx-mode.
W32_DATA int | _pkt_rxmode0
Startup receive mode.
W32_DATA int | _pkt_forced_rxmode
Forced Rx-mode via WATTCP.CFG.
W32_DATA int | _pkt_errno
Last PKTDRVR error code.
BYTE _pktdevlevel
Device level.
pkt_info * _pkt_inf
module data that will be locked

Enumeration Type Documentation

enum ReceiveModes

Enumeration values:
RXMODE_OFF | turn off receiver
RXMODE_DIRECT | receive only to this interface
RXMODE_BROADCAST | DIRECT + broadcast packets.
RXMODE_MULTICAST1 | BROADCAST + limited multicast.
RXMODE_MULTICAST2 | BROADCAST + all multicast.
RXMODE_PROMISCOUS | receive all packets on network
Definition at line 125 of file PCPKT.H.

Function Documentation

int pkt_eth_init ( mac_address * mac_addr )

Initialise Packet driver interface.

<

Todo:
Support Win-9x too
Definition at line 1499 of file PCPKT.C.

void pkt_free_pkt ( const void * pkt )

Release a packet from the receive queue.

If USE_FAST_PKT, pkt has already been free'd. Just update drop count. Definition at line 1381 of file PCPKT.C.

int pkt_get_api_ver ( DWORD * ver )

Return version of spec.

this PKTDRVR conforms to.

Return values:
-1 on error. Return major version in upper 8 bit, minor in lower.
Definition at line 508 of file PCPKT.C.

int pkt_get_mtu ( void )

Return PKTDRVR maximum-transmit-units (MTU).

Note:
This includes length of MAC-header.
Definition at line 478 of file PCPKT.C.

int pkt_get_multicast_list | ( | mac_address * | listbuf,
 |  | int * | lenp
 | ) |

Gets the current list of multicast addresses from the PKTDRVR.

  • listbuf is the buffer into which the list is placed
  • len on input: length of listbuf on output: length of list returned
Return values:
0 | upon error - _pkt_errno is set
1 | if retrieval was successful,
Definition at line 2086 of file PCPKT.C.

int pkt_get_rcv_mode ( void )

Gets the receive mode of the interface (can never be mode 0).

Return values:
!0 | Okay - _pkt_errno is 0, _pkt_rxmode and retval is current mode.
0 | Error - _pkt_errno is set.
_pkt_rxmode is one of the following modes: (upon successful return)
  • 1 - turn off receiver
  • 2 - receive only packets sent to this interface
  • 3 - mode 2 plus broadcast packets (default)
  • 4 - mode 3 plus limited multicast packets
  • 5 - mode 3 plus all multicast packets
  • 6 - all packets (a.k.a promiscuous mode)
Definition at line 2048 of file PCPKT.C.

int pkt_get_stats | ( | struct PktStats * | stats,
 |  | struct PktStats * | total
 | ) |

Get PKTDRVR statistics.

Return both 'stats' for current session and 'total' statistics since driver loaded. Definition at line 1275 of file PCPKT.C.

int pkt_release ( void )

Todo:
We might be called between 1st and 2nd packet-driver upcall. Need to wait for 2nd upcall to finish or else freeing the RMCB too early could cause a crash or a stuck PKTDRVR.
Definition at line 808 of file PCPKT.C.

int pkt_send | ( | const void * | tx,
 |  | int | length
 | ) |

Send a link-layer frame.

For PPP/SLIP 'tx' contains no MAC-header. For EtherNet, Token-Ring, ARCNET and FDDI, 'tx' contains the complete frame.

Todo:
Change this so that we doesn't retry if the driver was stuck for "too long". I've seen drivers using approx. 100 msec on each iteration below. Retrying if the driver is stuck is not worth the time.

Todo:
estimate max time this should take
Definition at line 1060 of file PCPKT.C.

int pkt_set_multicast_list | ( | const void * | listbuf,
 |  | int | len
 | ) |

Sets the list of multicast addresses for which the PKTDRVR is responsible.

  • listbuf is the buffer containing the list
  • len is the length of listbuf
Return values:
0 | upon error - _pkt_errno is set
1 | if set was successful
Definition at line 2133 of file PCPKT.C.

int pkt_set_rcv_mode ( int mode )

Sets the receive mode of the interface.

mode is one of the following modes:

  • 1 - turn off receiver
  • 2 - receive only packets sent to this interface
  • 3 - mode 2 plus broadcast packets <default>
  • 4 - mode 3 plus limited multicast packets
  • 5 - mode 3 plus all multicast packets
  • 6 - all packets (AKA promiscuous mode)

Return values:
0 | - upon error - _pkt_errno is set
1 | - if the mode was set successfully
Definition at line 2004 of file PCPKT.C.

void* pkt_tx_buf ( void )

Return address of DOS memory Tx-buffer.

For DOS4GW/X32VM (and djgpp with near-ptrs) targets, return near address of transmit buffer located in DOS memory. Definition at line 291 of file PCPKT.C.

Generated on Wed Jan 25 15:42:42 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/PCPKT32.C File Reference

SRC/PCPKT32.C File Reference

Detailed Description

32-bit PKTDRVR interface.

Skeleton (not finished) for probing for the presence of network cards. All drivers should be put in a dynamically loaded module (DLL/DXE).

Copyright (c) 1997-2002 Gisle Vanem <giva@bgnett.no>

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. All advertising materials mentioning features or use of this software must display the following acknowledgement: This product includes software developed by Gisle Vanem Bergen, Norway.

THIS SOFTWARE IS PROVIDED BY ME (Gisle Vanem) AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL I OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

Definition in file PCPKT32.C.

Go to the source code of this file.

Functions

int | pkt32_drvr_probe (const PM_driver *drivers)
int | pkt32_drvr_init (int driver, mac_address *addr)
const char * | pkt32_drvr_name (int driver)

Variables

int(* | _pkt32_drvr )(IREGS *)=NULL
PM_driver | pm_driver_list []

Variable Documentation

struct PM_driver pm_driver_list[]

Initial value:

 {
                 { PM_DRVR_3C501,   "3c501"   },
                 { PM_DRVR_3C503,   "3c503"   },
                 { PM_DRVR_3C505,   "3c505"   },
                 { PM_DRVR_3C507,   "3c507"   },
                 { PM_DRVR_3C5x9,   "3c5x9"   },
                 { PM_DRVR_3C59x,   "3c59x"   },
                 { PM_DRVR_NE2000,  "NE2000"  },
                 { PM_DRVR_EEXPR,   "EthExp"  },
                 { PM_DRVR_RTL8139, "RTL8139" },
                 { 0,               NULL      }
               }
Definition at line 57 of file PCPKT32.C.

Generated on Wed Jan 25 15:42:42 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/PCPKT32.H File Reference

SRC/PCPKT32.H File Reference

Detailed Description

Definition in file PCPKT32.H.

Go to the source code of this file.

Data Structures

struct | PM_driver

Typedefs

typedef PM_driver | PM_driver

Functions

int | pkt32_drvr_probe (const PM_driver *drivers)
int | pkt32_drvr_init (int driver, mac_address *addr)
const char * | pkt32_drvr_name (int driver)

Variables

int(* | _pkt32_drvr )(IREGS *)
PM_driver | pm_driver_list []

Generated on Wed Jan 25 15:42:42 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/PCQUEUE.C File Reference

SRC/PCQUEUE.C File Reference

Detailed Description

Simple ring-buffer queue handler for reception of packets from network driver.

Copyright (c) 1997-2002 Gisle Vanem <giva@bgnett.no>

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. All advertising materials mentioning features or use of this software must display the following acknowledgement: This product includes software developed by Gisle Vanem Bergen, Norway.

THIS SOFTWARE IS PROVIDED BY ME (Gisle Vanem) AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL I OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

Created Jan-1998

Definition in file PCQUEUE.C.

Go to the source code of this file.

Functions

int | pktq_check (struct pkt_ringbuf *q)
int | pktq_init (struct pkt_ringbuf *q, int size, int num, char *buf)
int | pktq_inc_in (struct pkt_ringbuf *q)
int | pktq_inc_out (struct pkt_ringbuf *q)
int | pktq_in_index (struct pkt_ringbuf *q)
char * | pktq_in_buf (struct pkt_ringbuf *q)
char * | pktq_out_buf (struct pkt_ringbuf *q)
void | pktq_clear (struct pkt_ringbuf *q)
int | pktq_queued (struct pkt_ringbuf *q)
int | pktq_far_check (struct pkt_ringbuf *q)
int | pktq_far_init (int size, int num, DWORD real_base)

Variables

DWORD | asmpkt_rm_base

Generated on Wed Jan 25 15:42:42 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/PCQUEUE.H File Reference

SRC/PCQUEUE.H File Reference

Detailed Description

Definition in file PCQUEUE.H.

Go to the source code of this file.

Data Structures

struct | pkt_rx_element
struct | pkt_rx_element
struct | pkt_ringbuf

Functions

int | pktq_inc_in (struct pkt_ringbuf *q)
int | pktq_inc_out (struct pkt_ringbuf *q)
int | pktq_check (struct pkt_ringbuf *q)
void | pktq_clear (struct pkt_ringbuf *q)
int | pktq_init (struct pkt_ringbuf *q, int size, int num, char *buf)
int | pktq_in_index (struct pkt_ringbuf *q)
char * | pktq_in_buf (struct pkt_ringbuf *q)
char * | pktq_out_buf (struct pkt_ringbuf *q)
int | pktq_queued (struct pkt_ringbuf *q)
int | pktq_far_init (int size, int num, DWORD asmpkt_real_base)
int | pktq_far_queued (void)
int | pktq_far_check (struct pkt_ringbuf *q)

Variables

DWORD | asmpkt_rm_base

Generated on Wed Jan 25 15:42:42 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/PCRARP.C File Reference

SRC/PCRARP.C File Reference

Detailed Description

RARP - Boot Protocol (RFC 903).

These extensions get called if MY_IP is set to RARP in wattcp.cfg

Version

0.0 : Sept 6, 1996 : Copied from E. Engelke's pcbootp.c by Dan Kegel 0.1 : Febr 9, 1997 : Modified, removed debug printing, G. Vanem

Definition in file PCRARP.C.

Go to the source code of this file.

Functions

int | _rarp_request (void)
BOOL | _rarp_handler (const rarp_Header *rh, BOOL brdcast)
Handle incoming RARP packets.
int | _dorarp (void)

Variables

WORD | _rarptimeout = 5

Generated on Wed Jan 25 15:42:42 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/PCRARP.H File Reference

SRC/PCRARP.H File Reference

Detailed Description

Definition in file PCRARP.H.

Go to the source code of this file.

Functions

int | _dorarp (void)

Variables

WORD | _rarptimeout

Generated on Wed Jan 25 15:42:42 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/PCRECV.C File Reference

SRC/PCRECV.C File Reference

Detailed Description

Alternative socket receive handlers (see Waterloo manual).

Definition in file PCRECV.C.

Go to the source code of this file.

Functions

int | sock_recvdaemon (sock_type *s, const void *data, unsigned len, const tcp_PseudoHeader *ph, const udp_Header *udp)
int | sock_recv_used (const sock_type *s)
int | sock_recv_init (sock_type *s, void *space, unsigned len)
int | sock_recv_from (sock_type *s, void *hisip, WORD *hisport, void *buffer, unsigned len, int peek)
int | sock_recv (sock_type *s, void *buffer, unsigned len)

Variables

long | seq_num = 0

Generated on Wed Jan 25 15:42:42 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/PCRECV.H File Reference

SRC/PCRECV.H File Reference

Detailed Description

Definition in file PCRECV.H.

Go to the source code of this file.

Data Structures

struct | recv_data
struct | recv_buf

Typedefs

typedef recv_data | recv_data
typedef recv_buf | recv_buf

Functions

int | sock_recv_init (sock_type *s, void *space, unsigned len)
int | sock_recv_used (const sock_type *s)
int | sock_recv (sock_type *s, void *buffer, unsigned len)
int | sock_recv_from (sock_type *s, void *hisip, WORD *hisport, void *buffer, unsigned len, int peek)

Generated on Wed Jan 25 15:42:42 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/PCSARP.C File Reference

SRC/PCSARP.C File Reference

Detailed Description

Secure ARP client.

March 2004-09: created. Partly based on Linux version by Albero Ornaghi <alor@blackhats.it> http://alor.antifork.org/projects/s-arp/ http://www.acsac.org/2003/papers/111.pdf

This is mostly an excersise in OpenSSL programming. Don't expect it to make sense since S-ARP is completely non-standard (no RFC). Only Linux has a kernel patch to use S-ARP.

Definition in file PCSARP.C.

Go to the source code of this file.

Data Structures

struct | host_list

Functions

void | sarp_parse (const char *name, const char *value)
Parser for "SEC_ARP.xx" keywords in WATTCP.CFG (or SARP.CFG).
int | sarp_receive (const struct sarp_Packet *sarp)
int | sarp_transmit (struct sarp_Packet *sarp)
int | sarp_init (void)
Application must call this *before* sock_init() so we don't link in OpenSSL libs by default.
int | read_ca_keyfile (const char *value)
int | read_priv_keyfile (const char *value)
BOOL | crypto_load_sarp_file (const char *pem_file, DSA **dsa)
int | set_secure_host (const char *value)
int | set_known_host (const char *value, int value_len)
__inline BOOL | is_secure_host (DWORD ip)
Check if host should use secure ARP.
__inline BOOL | is_known_host (DWORD ip)
Check if host is among the known hosts.
int | make_auth_Header (struct sarp_Packet *sarp)
void | _sarp_debug_dump (void)
Secure-ARP debug dump.

Variables

void(* | prev_cfg_hook )(const char *, const char *)
char * | ca_keyfile = NULL
char * | priv_keyfile = NULL
int | sarp_debug = 0
host_list * | known_hosts = NULL
host_list * | secure_hosts = NULL

Function Documentation

int sarp_receive ( const struct sarp_Packet * sarp ) [static]

Todo:
Definition at line 253 of file PCSARP.C.

References DWORD, is_known_host(), and is_secure_host().

Generated on Wed Jan 25 15:42:42 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/PCSARP.H File Reference

SRC/PCSARP.H File Reference

Detailed Description

Secure ARP handler module.

Definition in file PCSARP.H.

Go to the source code of this file.

Data Structures

struct | sarp_Auth
struct | sarp_Packet

Functions

int | sarp_init (void)
Application must call this *before* sock_init() so we don't link in OpenSSL libs by default.

Generated on Wed Jan 25 15:42:42 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/PCSED.C File Reference

SRC/PCSED.C File Reference

Detailed Description

Ethernet Driver Routines.

The TCP code uses Ethernet constants for protocol numbers and 48 bits for address. Also, 0xFF:FF:FF:FF:FF:FF is assumed to be a broadcast. Except for ARCNET where broadcast is 0x00.

If you need to write a new driver, implement it at this level and use the above mentioned constants as this program's constants, not device dependant constants.

The packet driver or WinPcap interface code lies below this module.

Definition in file PCSED.C.

Go to the source code of this file.

Functions

void * | _eth_formatpacket (const void *mac_dest, WORD eth_type)
_eth_format_packet() places the next packet to be transmitted into the above link-layer output packet.
int | send_loopback (link_Packet pkt, BOOL is_ip6, unsigned *err_line)
Enqueue a link-layer frame (IPv4/v6 only) to the internal loopback device.
int | _eth_send (WORD len, const void *sock, const char *file, unsigned line)
_eth_send() does the actual transmission once we are complete with filling the buffer.
void * | eth_mac_format (void *mac_buf, const void *mac_dest, WORD type)
Format the MAC-header for Ethernet.
void * | tok_mac_format (void *mac_buf, const void *mac_dest, WORD type)
Format the MAC-header for Token-Ring.
void * | fddi_mac_format (void *mac_buf, const void *mac_dest, WORD type)
Format the MAC-header for FDDI.
void * | arcnet_mac_format (void *mac_buf, const void *mac_dest, WORD type)
Format the MAC-header for ARCNET.
void * | null_mac_format (void *mac_buf, const void *mac_dest, WORD type)
Format MAC-header for protocols without MAC-headers.
int | eth_mac_xmit (const void *buf, WORD len)
Functions called via function pointer `mac_transmit' to actually send the data.
int | fddi_mac_xmit (const void *buf, WORD len)
int | arcnet_mac_xmit (const void *buf, WORD len)
int | tok_mac_xmit (const void *buf, WORD len)
int | null_mac_xmit (const void *buf, WORD len)
int | _eth_init (void)
Initialize the network driver interface.
int | _eth_set_addr (const void *addr)
Sets a new MAC address for our interface.
BYTE | _eth_get_hwtype (BYTE *hwtype, BYTE *hwlen)
Fill in hardware address type/length for BOOTP/DHCP packets.
void | _eth_free (const void *pkt)
Free an input buffer once it is no longer needed.
void | fix_tok_head (tok_Header **trp)
BOOL | fix_arc_head (const arcnet_Header *head, WORD *type)
link_Packet * | poll_recv_queue (WORD *type)
Poll the packet queue.
void | fix_llc_head (void **mac)
void * | _eth_arrived (WORD *type_ptr, BOOL *broadcast)
Poll for arrival of new packets (IP/ARP/RARP/PPPoE protocol).
void * | _eth_mac_hdr (const in_Header *ip)
Return pointer to MAC header start address of an IP packet.
void * | _eth_mac_dst (const in_Header *ip)
Return pointer to MAC destination address of an IP packet.
void * | _eth_mac_src (const in_Header *ip)
Return pointer to MAC source address of an IP packet.
WORD | _eth_mac_typ (const in_Header *ip)
Return value of protocol-type given an IP packet.
BOOL | _eth_join_mcast_group (const struct MultiCast *mc)
Joins a multicast group (at the physical layer).
BOOL | _eth_leave_mcast_group (const struct MultiCast *mc)
Leaves a multicast group (at the physical layer).
void | _eth_release (void)
Release the hardware driver.

Variables

mac_address | _eth_addr
Local link-layer source address.
mac_address | _eth_brdcast
Link-layer broadcast address.
mac_address | _eth_loop_addr
Link-layer loopback address.
mac_address | _eth_real_addr
Our real MAC address.
BYTE _eth_mac_len
Size of a MAC address.
BOOL | _eth_is_init = FALSE
we are initialised
BOOL | _ip_recursion = FALSE
avoid recursion in arp_resolve()
BOOL | _eth_ndis3pkt = FALSE
BOOL | _eth_SwsVpkt = FALSE
const char | _eth_not_init [] = "Packet driver not initialised"
_eth_last_info | _eth_last
Sizes and timestamps of last packet recv/sent.
void *(* | _eth_recv_hook )(WORD *type)=NULL
Pointer to functions that when set changes the behaviour of polling and send functions _eth_arrived() and _eth_send().
int(* | _eth_recv_peek )(void *mac_buf)=NULL
int(* | _eth_xmit_hook )(const void *mac_buf, unsigned len)=NULL
void *(* | mac_tx_format )(void *mac_buf, const void *mac_dest, WORD type)
Pointer to functions that does the filling of correct MAC-header and sends the link-layer packet.
int(* | mac_transmit )(const void *mac_buf, WORD len)
WORD | proto
void * | nw_pkt
link_Packet | outbuf

Function Documentation

void* _eth_arrived | ( | WORD * | type_ptr,
 |  | BOOL * | broadcast
 | ) |

Poll for arrival of new packets (IP/ARP/RARP/PPPoE protocol).

Sets protocol-type of packet received in 'type'.

For Ethernet/TokenRing-type drivers:

Return values:
Pointer past the MAC-header to the IP/ARP/RARP protocol header. Also check for link-layer broadcast.
For PPP/SLIP-type drivers (no MAC-headers):
Return values:
Pointer to the IP-packet itself. IP-protocol is assumed. Can never be link-layer broadcast.

<

Todo:
push back packet, else it's lost
Definition at line 1009 of file PCSED.C.

References _eth_brdcast, _eth_free(), _eth_is_init, _eth_recv_hook, _ip_recursion, _pktdevclass, _pktserial, BYTE, fix_llc_head(), macstat::num_ip_recurse, poll_recv_queue(), update_in_stat(), and WORD.

void* _eth_formatpacket | ( | const void * | mac_dest,
 |  | WORD | eth_type
 | ) |

_eth_format_packet() places the next packet to be transmitted into the above link-layer output packet.

Returns:
address of higher-level protocol (IP/RARP/RARP) header.
Definition at line 129 of file PCSED.C.

References WORD.

BYTE _eth_get_hwtype | ( | BYTE * | hwtype,
 |  | BYTE * | hwlen
 | ) |

Fill in hardware address type/length for BOOTP/DHCP packets.

Also used for ARP/RARP packets. Should never be called for PPP/SLIP. Definition at line 735 of file PCSED.C.

References _pktdevclass, arcnet_address, ax25_address, BYTE, eth_address, fddi_address, and tok_address.

int _eth_init ( void )

Initialize the network driver interface.

Returns:
0 okay.

error-code otherwise.

Definition at line 645 of file PCSED.C.

References _eth_addr, _eth_brdcast, _eth_get_hwtype(), _eth_is_init, _eth_loop_addr, _eth_mac_len, _eth_real_addr, _eth_release(), _pktdevclass, arcnet_mac_format(), eth_address, eth_mac_format(), eth_mac_xmit(), fddi_mac_format(), mac_tx_format, null_mac_format(), pkt_buf_wipe(), pkt_eth_init(), and tok_mac_format().

BOOL _eth_join_mcast_group ( const struct MultiCast * mc )

Joins a multicast group (at the physical layer).

Return values:
1 | The group was joined successfully.
0 | Attempt failed.
Definition at line 1231 of file PCSED.C.

References _pkt_errno, _pkt_rxmode, eth_address, MultiCast::ethaddr, pkt_get_multicast_list(), pkt_set_multicast_list(), pkt_set_rcv_mode(), RXMODE_MULTICAST1, RXMODE_MULTICAST2, and RXMODE_PROMISCOUS.

BOOL _eth_leave_mcast_group ( const struct MultiCast * mc )

Leaves a multicast group (at the physical layer).

Return values:
1 | The group was left successfully.
0 | Attempt failed.
Definition at line 1307 of file PCSED.C.

References _pkt_errno, _pkt_rxmode, eth_address, MultiCast::ethaddr, pkt_get_multicast_list(), pkt_set_multicast_list(), pkt_set_rcv_mode(), and RXMODE_MULTICAST2.

int _eth_send | ( | WORD | len,
 |  | const void * | sock,
 |  | const char * | file,
 |  | unsigned | line
 | ) |

_eth_send() does the actual transmission once we are complete with filling the buffer.

Do any last minute patches here, like fix the size. Send to "loopback" device if it's IP and destination matches loopback network (127.x.x.x.).

Return length of network-layer packet (not length of link-layer packet). Definition at line 300 of file PCSED.C.

References _eth_is_init, _eth_last, _pkt_ip_ofs, _pktdevclass, in_Header::destination, in6_Header::destination, has_rdtsc, send_loopback(), update_out_stat(), and WORD.

void fix_llc_head ( void ** mac ) [static]

Todo:
handle IEEE 802.3 encapsulation also.
Definition at line 983 of file PCSED.C.

References _eth_free().

void* null_mac_format | ( | void * | mac_buf,
 |  | const void * | mac_dest,
 |  | WORD | type
 | ) | [static]

Format MAC-header for protocols without MAC-headers.

Nothing done here. Definition at line 570 of file PCSED.C.

References WORD.

union link_Packet* poll_recv_queue ( WORD * type ) [static]

Poll the packet queue.

Return first packet in queue. Optionally do receiver profiling.

Return values:
pointer | to start of MAC-header.
NULL | no packets are queued.
Note:
Not used when e.g. libpcap has set the `_eth_recv_hook' to do it's own packet-polling.

'type' is always set.

Definition at line 877 of file PCSED.C.

References _eth_last, _pkt_inf, _pktdevclass, _pktserial, arcnet_Packet::data, fddi_Packet::head, arcnet_Packet::head, pkt_free_pkt(), pkt_info::pkt_queue, fddi_Header::type, tok_Header::type, uint64, and WORD.

int send_loopback | ( | link_Packet | pkt,
 |  | BOOL | is_ip6,
 |  | unsigned * | err_line
 | ) | [static]

Enqueue a link-layer frame (IPv4/v6 only) to the internal loopback device.

Note:
This function uses call-by-value. Thus `pkt' buffer can be modified by loopback_device() and loopback handler may send using _eth_send().

Loopback device cannot send to itself (potential recursion).

Definition at line 148 of file PCSED.C.

References _eth_addr, _eth_loop_addr, _pkt_inf, _pkt_ip_ofs, _pktserial, BYTE, pkt_ringbuf::num_buf, and pkt_info::pkt_queue.

Variable Documentation

void*(* _eth_recv_hook)(WORD *type)=NULL

Pointer to functions that when set changes the behaviour of polling and send functions _eth_arrived() and _eth_send().

_eth_recv_hook: If set, must point to a function that supplies frames ready to be received. Return NULL if no frame is ready. Otherwise points to a raw MAC frame. If not a serial-driver, must also set '*type'.

_eth_recv_peek: If set, must point to a function that gets a chance to peek at the raw received frame. It can modify it or even consume it by returning zero. To prevent recursion, this function cannot call tcp_tick(). It should return as fast as possible in order not to block reception of other frames waiting in the receive buffer.

_eth_xmit_hook: If set, must point to a function that should transmit all frames generated by Watt-32. Must return length of frame sent or <= 0 if it failed. Definition at line 86 of file PCSED.C.

void*(* mac_tx_format)(void *mac_buf, const void *mac_dest, WORD type) [static]

Pointer to functions that does the filling of correct MAC-header and sends the link-layer packet.

We store 'proto' between calls. Definition at line 94 of file PCSED.C.

Generated on Wed Jan 25 15:42:42 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/PCSED.H File Reference

SRC/PCSED.H File Reference

Detailed Description

Link-layer (DIX Ethernet, Token-Ring, ARCnet, FDDI and PPP/SLIP) Interface.

Definition in file PCSED.H.

Go to the source code of this file.

Data Structures

struct | eth_Header
struct | eth_Packet
struct | vlan_Header
struct | vlan_Packet
struct | tok_Header
struct | tok_Packet
struct | llc_Header
struct | fddi_Header
struct | fddi_Packet
struct | arcnet_Header
struct | arcnet_Packet
union | link_Packet
struct | _eth_last_info

Typedefs

typedef eth_Header | eth_Header
typedef eth_Packet | eth_Packet
typedef vlan_Header | vlan_Header
typedef vlan_Packet | vlan_Packet
typedef tok_Header | tok_Header
typedef tok_Packet | tok_Packet
typedef llc_Header | llc_Header
typedef fddi_Header | fddi_Header
typedef fddi_Packet | fddi_Packet
typedef arcnet_Header | arcnet_Header
typedef arcnet_Packet | arcnet_Packet
typedef link_Packet | link_Packet

Functions

W32_FUNC int | _eth_init (void)
Initialize the network driver interface.
W32_FUNC void | _eth_release (void)
Release the hardware driver.
W32_FUNC int | _eth_send (WORD len, const void *sock, const char *file, unsigned line)
_eth_send() does the actual transmission once we are complete with filling the buffer.
W32_FUNC int | _eth_set_addr (const void *addr)
Sets a new MAC address for our interface.
W32_FUNC void * | _eth_formatpacket (const void *mac_dest, WORD mac_type)
_eth_format_packet() places the next packet to be transmitted into the above link-layer output packet.
W32_FUNC void | _eth_free (const void *pkt)
Free an input buffer once it is no longer needed.
W32_FUNC void * | _eth_arrived (WORD *type, BOOL *brdcast)
Poll for arrival of new packets (IP/ARP/RARP/PPPoE protocol).
W32_FUNC BYTE | _eth_get_hwtype (BYTE *hwtype, BYTE *hwlen)
Fill in hardware address type/length for BOOTP/DHCP packets.
W32_FUNC BOOL | _eth_join_mcast_group (const struct MultiCast *mc)
Joins a multicast group (at the physical layer).
W32_FUNC BOOL | _eth_leave_mcast_group (const struct MultiCast *mc)
Leaves a multicast group (at the physical layer).
void * | _eth_mac_hdr (const in_Header *ip) ATTR_NORETURN()
Return pointer to MAC header start address of an IP packet.
void * | _eth_mac_dst (const in_Header *ip) ATTR_NORETURN()
Return pointer to MAC destination address of an IP packet.
void * | _eth_mac_src (const in_Header *ip) ATTR_NORETURN()
Return pointer to MAC source address of an IP packet.
WORD | _eth_mac_typ (const in_Header *ip) ATTR_NORETURN()
Return value of protocol-type given an IP packet.

Variables

_eth_last_info | _eth_last
Sizes and timestamps of last packet recv/sent.
BOOL | _ip_recursion
avoid recursion in arp_resolve()
BOOL | _eth_is_init
we are initialised
BOOL | _eth_ndis3pkt
BOOL | _eth_SwsVpkt
BYTE _eth_mac_len
Size of a MAC address.
const char | _eth_not_init []
W32_DATA mac_address | _eth_addr
W32_DATA mac_address | _eth_real_addr
W32_DATA mac_address | _eth_loop_addr
W32_DATA mac_address | _eth_brdcast
W32_DATA void *(* | _eth_recv_hook )(WORD *type)
W32_DATA int(* | _eth_recv_peek )(void *mac_buf)
W32_DATA int(* | _eth_xmit_hook )(const void *mac_buf, unsigned len)

Function Documentation

W32_FUNC void* _eth_arrived | ( | WORD * | type_ptr,
 |  | BOOL * | broadcast
 | ) |

Poll for arrival of new packets (IP/ARP/RARP/PPPoE protocol).

Sets protocol-type of packet received in 'type'.

For Ethernet/TokenRing-type drivers:

Return values:
Pointer past the MAC-header to the IP/ARP/RARP protocol header. Also check for link-layer broadcast.
For PPP/SLIP-type drivers (no MAC-headers):
Return values:
Pointer to the IP-packet itself. IP-protocol is assumed. Can never be link-layer broadcast.

<

Todo:
push back packet, else it's lost
Definition at line 1009 of file PCSED.C.

W32_FUNC void* _eth_formatpacket | ( | const void * | mac_dest,
 |  | WORD | eth_type
 | ) |

_eth_format_packet() places the next packet to be transmitted into the above link-layer output packet.

Returns:
address of higher-level protocol (IP/RARP/RARP) header.
Definition at line 129 of file PCSED.C.

W32_FUNC BYTE _eth_get_hwtype | ( | BYTE * | hwtype,
 |  | BYTE * | hwlen
 | ) |

Fill in hardware address type/length for BOOTP/DHCP packets.

Also used for ARP/RARP packets. Should never be called for PPP/SLIP. Definition at line 735 of file PCSED.C.

W32_FUNC int _eth_init ( void )

Initialize the network driver interface.

Returns:
0 okay.

error-code otherwise.

Definition at line 645 of file PCSED.C.

W32_FUNC BOOL _eth_join_mcast_group ( const struct MultiCast * mc )

Joins a multicast group (at the physical layer).

Return values:
1 | The group was joined successfully.
0 | Attempt failed.
Definition at line 1231 of file PCSED.C.

References _pkt_errno, _pkt_rxmode, eth_address, MultiCast::ethaddr, pkt_get_multicast_list(), pkt_set_multicast_list(), pkt_set_rcv_mode(), RXMODE_MULTICAST1, RXMODE_MULTICAST2, and RXMODE_PROMISCOUS.

W32_FUNC BOOL _eth_leave_mcast_group ( const struct MultiCast * mc )

Leaves a multicast group (at the physical layer).

Return values:
1 | The group was left successfully.
0 | Attempt failed.
Definition at line 1307 of file PCSED.C.

References _pkt_errno, _pkt_rxmode, eth_address, MultiCast::ethaddr, pkt_get_multicast_list(), pkt_set_multicast_list(), pkt_set_rcv_mode(), and RXMODE_MULTICAST2.

W32_FUNC int _eth_send | ( | WORD | len,
 |  | const void * | sock,
 |  | const char * | file,
 |  | unsigned | line
 | ) |

_eth_send() does the actual transmission once we are complete with filling the buffer.

Do any last minute patches here, like fix the size. Send to "loopback" device if it's IP and destination matches loopback network (127.x.x.x.).

Return length of network-layer packet (not length of link-layer packet). Definition at line 300 of file PCSED.C.

Generated on Wed Jan 25 15:42:42 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/PCSLIP.H File Reference

SRC/PCSLIP.H File Reference

Detailed Description

Deprecated:

Definition in file PCSLIP.H.

Go to the source code of this file.

Functions

int slip_init (void)

Generated on Wed Jan 25 15:42:42 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/PCSTAT.C File Reference

SRC/PCSTAT.C File Reference

Detailed Description

Input/output statistics.

Definition in file PCSTAT.C.

Go to the source code of this file.

Functions

int | sock_stats (sock_type *sock, DWORD *days, WORD *inactive, WORD *cwindow, DWORD *avg, DWORD *sd)
void | print_mac_stats (void)
void | print_vjc_stats (void)
void | print_pkt_stats (void)
void | print_ip4_stats (void)
void | print_ip6_stats (void)
void | print_icmp_stats (void)
void | print_icmp6_stats (void)
void | print_igmp_stats (void)
void | print_udp_stats (void)
void | print_tcp_stats (void)
void | print_all_stats (void)
void | reset_stats (void)
__inline void | show_stat (const char *name, DWORD num)
__inline void | show_stat64 (const char *name, uint64 num)
void | print_arp_stats (void)
void | print_rarp_stats (void)
void | print_pppoe_stats (void)
void | update_in_stat (void)
void | update_out_stat (void)

Variables

macstat | macstats
ipstat | ip4stats
ip6stat | ip6stats
udpstat | udpstats
tcpstat | tcpstats
icmpstat | icmpstats
icmp6stat | icmp6stats
igmpstat | igmpstats
pppoestat | pppoestats

Function Documentation

void update_in_stat ( void )

Todo:
Count PPP protocols LCP and IPCP

Count these IPv6 protocols

Definition at line 520 of file PCSTAT.C.

References _eth_addr, macstat::arp, BYTE, macstat::non_ip_recv, pppoestat::num_disc_recv, macstat::num_llc_frames, macstat::num_mac_loop, pppoestat::num_sess_recv, macstat::num_unk_type, arp_Header::opcode, macstat::rarp, eth_Header::source, and tok_Header::source.

void update_out_stat ( void )

Todo:
Count the PPP protocols LCP and IPCP

Count these IPv6 protocols

Definition at line 651 of file PCSTAT.C.

References macstat::arp, BYTE, DWORD, in_Header::frag_ofs, macstat::non_ip_sent, pppoestat::num_disc_sent, pppoestat::num_sess_sent, arp_Header::opcode, and macstat::rarp.

Generated on Wed Jan 25 15:42:42 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/PCSTAT.H File Reference

SRC/PCSTAT.H File Reference

Detailed Description

Definition in file PCSTAT.H.

Go to the source code of this file.

Data Structures

struct | macstat
struct | pppoestat

Functions

int | sock_stats (sock_type *sock, DWORD *days, WORD *inactive, WORD *cwindow, DWORD *avg, DWORD *sd)
void | print_mac_stats (void)
void | print_arp_stats (void)
void | print_pkt_stats (void)
void | print_vjc_stats (void)
void | print_pppoe_stats (void)
void | print_ip4_stats (void)
void | print_ip6_stats (void)
void | print_icmp_stats (void)
void | print_icmp6_stats (void)
void | print_igmp_stats (void)
void | print_udp_stats (void)
void | print_tcp_stats (void)
void | print_all_stats (void)
void | reset_stats (void)
void | update_in_stat (void)
void | update_out_stat (void)

Variables

macstat | macstats
ipstat | ip4stats
ip6stat | ip6stats
udpstat | udpstats
tcpstat | tcpstats
icmpstat | icmpstats
icmp6stat | icmp6stats
igmpstat | igmpstats
pppoestat | pppoestats

Function Documentation

void update_in_stat ( void )

Todo:
Count PPP protocols LCP and IPCP

Count these IPv6 protocols

Definition at line 520 of file PCSTAT.C.

References _eth_addr, macstat::arp, BYTE, macstat::non_ip_recv, pppoestat::num_disc_recv, macstat::num_llc_frames, macstat::num_mac_loop, pppoestat::num_sess_recv, macstat::num_unk_type, arp_Header::opcode, macstat::rarp, tok_Header::source, and eth_Header::source.

void update_out_stat ( void )

Todo:
Count the PPP protocols LCP and IPCP

Count these IPv6 protocols

Definition at line 651 of file PCSTAT.C.

References macstat::arp, BYTE, DWORD, in_Header::frag_ofs, macstat::non_ip_sent, pppoestat::num_disc_sent, pppoestat::num_sess_sent, arp_Header::opcode, and macstat::rarp.

Generated on Wed Jan 25 15:42:42 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/PCTCP.C File Reference

SRC/PCTCP.C File Reference

Detailed Description

Main TCP handler.

PCTCP, the true worker of Waterloo TCP.

  • contains all opens, closes, major read/write routines and basic IP handler for incomming packets
  • Note: much of the TCP/UDP/IP layering is done at the data structure level, not in separate routines or tasks

Definition in file PCTCP.C.

Go to the source code of this file.

Data Structures

struct | ip4_packet
struct | ip6_packet
struct | tcp_pkt
struct | tcp6_pkt

Functions

void *MS_CDECL * | _bsd_socket_hook (enum BSD_SOCKET_OPS op,...)=NULL
This hook is to prevent the BSD-socket API being linked in by default.
int | _tcp_fsm (_tcp_Socket **s, const in_Header *ip)
_tcp_Socket * | tcp_findseq (const in_Header *ip, const tcp_Header *tcp)
Find the TCP socket that matches the tripplet: DESTADDR=MYADDR, DESTPORT=MYPORT and ACKNUM=SEQNUM+1 Can only be one socket.
void | tcp_sockreset (_tcp_Socket *s, BOOL proxy)
Resets a TCP connection.
void | tcp_no_arp (_tcp_Socket *s)
Called for a TCP socket when ARP lookup fails.
void | tcp_rtt_win (_tcp_Socket *s)
Update retransmission timer, VJ algorithm and TCP windows.
void | tcp_upd_win (_tcp_Socket *s, unsigned line)
Check if receive window needs an update.
BOOL | tcp_checksum (const in_Header *ip, const tcp_Header *tcp, int len)
Verify the TCP header checksum.
void | run_daemons (void)
Waterloo "background" daemon processes.
void | udp_close (const _udp_Socket *s)
Since UDP is stateless, simply reclaim the local-port and unthread the socket from the list.
int | udp_listen (_udp_Socket *s, WORD lport, DWORD ip, WORD port, ProtoHandler handler)
UDP passive open.
int | udp_open (_udp_Socket *s, WORD lport, DWORD ip, WORD port, ProtoHandler handler)
UDP active open.
void | udp_SetTTL (_udp_Socket *s, BYTE ttl)
Set the TTL on an outgoing UDP datagram.
int | tcp_open (_tcp_Socket *s, WORD lport, DWORD ip, WORD rport, ProtoHandler handler)
Actively open a TCP connection.
int | tcp_listen (_tcp_Socket *s, WORD lport, DWORD ip, WORD port, ProtoHandler handler, WORD timeout)
Passively opens TCP a connection.
void | _tcp_close (_tcp_Socket *s)
Close a TCP connection.
_tcp_Socket * | _tcp_abort (_tcp_Socket *s, const char *file, unsigned line)
Abort a TCP connection.
int | _tcp_sendsoon (_tcp_Socket *s, char *file, unsigned line)
Schedule a transmission pretty soon.
_tcp_Socket * | _tcp_unthread (_tcp_Socket *ds, BOOL free_tx)
Unthread a socket from the tcp socket list, if it's there.
int | tcp_established (const _tcp_Socket *s)
Returns 1 if TCP connection is established.
_tcp_Socket * | _tcp_handler (const in_Header *ip, BOOL broadcast)
The main TCP input handler.
BOOL | udp_checksum (const in_Header *ip, const udp_Header *udp, int len)
Verify checksum for an UDP packet.
_udp_Socket * | udp_demux (const in_Header *ip, BOOL ip_bcast, DWORD destin, WORD srcPort, WORD dstPort, BOOL *udp_err)
Demultiplexer for incoming UDP packets.
_udp_Socket * | _udp_handler (const in_Header *ip, BOOL broadcast)
Handler for incoming UDP packets.
void | tcp_Retransmitter (BOOL force)
Called periodically to perform retransmissions.
WORD | tcp_tick (sock_type *s)
Must be called periodically by user application (or BSD socket API).
int | udp_write (_udp_Socket *s, const BYTE *data, int len)
Write an UDP packet.
int | udp_read (_udp_Socket *s, BYTE *buf, int maxlen)
Read from UDP socket.
void | sock_reduce_mss (sock_type *s, WORD MTU)
Reduce socket MSS upon receiving ICMP_UNREACH_NEEDFRAG.
void | _udp_cancel (const in_Header *ip, int icmp_type, int icmp_code, const char *msg, const void *arg)
Cancel an UDP socket.
BOOL | tcp_stress_test (_tcp_Socket *s, const char *msg)
void | _tcp_cancel (const in_Header *ip, int icmp_type, int icmp_code, const char *msg, const void *arg)
Cancel a TCP socket.
int | tcp_read (_tcp_Socket *s, BYTE *buf, int maxlen)
Read from a TCP socket.
int | tcp_write (_tcp_Socket *s, const BYTE *data, UINT len)
Write data to a TCP connection.
__inline int | tcp_opt_maxsegment (const _tcp_Socket *s, BYTE *opt)
Insert MSS option.
__inline int | tcp_opt_timestamp (_tcp_Socket *s, BYTE *opt, DWORD ts_echo)
Insert TimeStamp option.
__inline int | tcp_opt_md5_sign (BYTE *opt)
__inline void | finalise_md5_sign (const in_Header *ip, const tcp_Header *tcp, WORD tcp_len, const char *secret)
__inline int | tcp_opt_padding (BYTE *opt, int len)
Pad options to multiple of 4 bytes.
__inline int | tcp_opt_winscale (const _tcp_Socket *s, BYTE *opt)
__inline int | tcp_opt_sack_ok (const _tcp_Socket *s, BYTE *opt)
__inline int | tcp_opt_sack (const _tcp_Socket *s, BYTE *opt, const struct SACK_list *sack)
__inline int | tcp_options (_tcp_Socket *s, BYTE *opt, BOOL is_syn)
Append options to output TCP header.
int | _tcp_send (_tcp_Socket *s, char *file, unsigned line)
Format and send an outgoing TCP segment.
int | _tcp_send_reset (_tcp_Socket *s, const in_Header *his_ip, const tcp_Header *org_tcp, const char *file, unsigned line)
Format and send a reset (RST) tcp packet.
int | _tcp_keepalive (_tcp_Socket *tcp)
TCP keepalive transmission.
int | sock_keepalive (sock_type *s)
WORD | sock_mode (sock_type *s, WORD mode)
void(*)(void) | sock_yield (_tcp_Socket *s, void(*fn)(void))
Enable user defined yield function.
void | sock_abort (sock_type *s)
Abort a UDP/TCP/Raw socket.
int | raw_read (_raw_Socket *raw, BYTE *buf, int maxlen)
Read data from a raw-socket.
int | sock_read (sock_type *s, BYTE *buf, int maxlen)
Read a socket with maximum 'maxlen' bytes.
int | sock_fastread (sock_type *s, BYTE *buf, int len)
Read a socket with maximum 'len' bytes.
int | sock_write (sock_type *s, const BYTE *data, int len)
Writes data and returns length written.
int | sock_fastwrite (sock_type *s, const BYTE *data, int len)
Simpler, non-blocking (non-looping) version of sock_write().
int | sock_enqueue (sock_type *s, const BYTE *data, int len)
For UDP, this function is same as sock_write().
void | sock_noflush (sock_type *s)
Sets non-flush mode on next TCP write.
void | sock_flush (sock_type *s)
Send pending TCP data.
void | sock_flushnext (sock_type *s)
Causes next transmission to have a flush (PUSH bit set).
int | sock_close (sock_type *s)
Close a UDP/TCP socket.
int | addwattcpd (void(*func)(void))
Add a function to background daemon list.
int | delwattcpd (void(*func)(void))
Remove a function from background daemon list.
void | tcp_rtt_add (const _tcp_Socket *s, UINT rto, UINT MTU)
BOOL | tcp_rtt_get (const _tcp_Socket *s, UINT *rto, UINT *MTU)
void | tcp_rtt_clr (const _tcp_Socket *s)

Variables

char | hostname [MAX_HOSTLEN+1] = "random-pc"
Our configured hostname.
unsigned | _mss = ETH_MAX_DATA - TCP_OVERHEAD
unsigned | _mtu = ETH_MAX_DATA
BOOL | mtu_discover = 0
BOOL | mtu_blackhole = 0
BOOL | block_tcp = 0
when application handles TCP itself
BOOL | block_udp = 0
when application handles UDP itself
BOOL | block_icmp = 0
when application handles ICMP itself
BOOL | block_ip = 0
when application handles IP itself
DWORD | my_ip_addr = 0L
our IP address
DWORD | sin_mask = 0xFFFFFF00L
our net-mask, 255.255.255.0
_udp_Socket * | _udp_allsocs = NULL
list of udp-sockets
unsigned | tcp_OPEN_TO = DEF_OPEN_TO
Default open timeout.
unsigned | tcp_CLOSE_TO = DEF_CLOSE_TO
Default close timeout.
unsigned | tcp_RTO_ADD = DEF_RTO_ADD
Time added in RTO calculation.
unsigned | tcp_RTO_BASE = DEF_RTO_BASE
Base time for RTO calculation.
unsigned | tcp_RTO_SCALE = DEF_RTO_SCALE
Scaling used in RTO calculation.
unsigned | tcp_RST_TIME = DEF_RST_TIME
Don't generate RST too often.
unsigned | tcp_RETRAN_TIME = DEF_RETRAN_TIME
Default retransmission time.
unsigned | tcp_MAX_VJSA = DEF_MAX_VJSA
Default max VJ std.
unsigned | tcp_MAX_VJSD = DEF_MAX_VJSD
Default max VJ std.
BOOL | tcp_opt_ts = FALSE
TCP option config flags (RFC 1323).
BOOL | tcp_opt_wscale = FALSE
BOOL | tcp_opt_sack = FALSE
BOOL | tcp_nagle = TRUE
Nagle algo.
unsigned | tcp_keep_idle = 2*60
idle time before sending keepalive
unsigned | tcp_keep_intvl = 30
time between keepalive probes
unsigned | tcp_max_idle = 60
max idle time before kill
DWORD | tcp_recv_win = DEF_RECV_WIN
RWIN for BSD sockets only.
_tcp_Socket * | _tcp_allsocs = NULL
list of tcp-sockets
DWORD | daemon_timer = 0UL
When to run "background" processes.
void(* | system_yield )(void)=NULL
BYTE * sign_opt
Prepare to insert MD5 option.
struct {
void(* func )(void)
BOOL running
} MAX_DAEMONS
List of background processes.
tcp_rtt | rtt_cache [RTTCACHE]
Round-trip timing cache routines.

Function Documentation

void* MS_CDECL* _bsd_socket_hook | ( | enum BSD_SOCKET_OPS | op,
 |  |  | ...
 | ) |

This hook is to prevent the BSD-socket API being linked in by default.

It is only set from the BSD functions when needed.

void _tcp_cancel | ( | const in_Header * | ip,
 |  | int | icmp_type,
 |  | int | icmp_code,
 |  | const char * | msg,
 |  | const void * | arg
 | ) |

Cancel a TCP socket.

Called upon receiving ICMP errors: host/port UNREACH, REDIRECT, SOURCEQUENCH, TIMXCEED or PARAMPROB. See icmp_redirect() or icmp_handler().

Note: 'ip' is a small copy of the IP-packet originating the ICMP message. We may *not* have received a copy of the original TCP-header. But we probably won't do any harm if got less TCP-header data than needed. I.e. src_port/dst_port will be zero. Definition at line 1745 of file PCTCP.C.

References _arp_resolve(), _ip_recursion, _tcp_allsocs, BYTE, _tcp_Socket::cwindow, in_Header::destination, DWORD, _tcp_Socket::next, _tcp_Socket::rto, sock_reduce_mss(), _tcp_Socket::state, _tcp_Socket::vj_sa, _tcp_Socket::vj_sd, WORD, and _tcp_Socket::wwindow.

void _tcp_close ( _tcp_Socket * s )

Close a TCP connection.

Send a FIN on a particular port -- only works if it is open. Must still allow receives. Definition at line 464 of file PCTCP.C.

References _tcp_unthread(), _tcp_Socket::flags, _tcp_Socket::rtt_time, set_timeout(), _tcp_Socket::state, _tcp_Socket::timeout, _tcp_Socket::tx_datalen, and _tcp_Socket::unhappy.

_tcp_Socket* _tcp_handler | ( | const in_Header * | ip,
 |  | BOOL | broadcast
 | ) |

The main TCP input handler.

All TCP input processing is done from here. Definition at line 653 of file PCTCP.C.

References _ip6_tcp_checksum(), _tcp_allsocs, _tcp_Socket::adv_win, block_tcp, BYTE, in_Header::destination, in6_Header::destination, DWORD, _tcp_Socket::his6addr, _tcp_Socket::inactive_to, ip6_address, in6_Header::len, in_Header::length, _tcp_Socket::my6addr, _tcp_Socket::next, _tcp_Socket::recv_next, _tcp_Socket::safetysig, _tcp_Socket::safetytcp, set_timeout(), in_Header::source, in6_Header::source, tcp_checksum(), tcp_findseq(), tcp_rtt_win(), tcp_sockreset(), _tcp_Socket::unhappy, in_Header::ver, and WORD.

int _tcp_keepalive ( _tcp_Socket * tcp )

TCP keepalive transmission.

If connection is idle (tx_datalen == 0), force the peer to send us a segment by sending a keep-alive packet:

 *    <SEQ=SND.UNA-1><ACK=RCV.NXT><CTL=ACK>
 *
Definition at line 2708 of file PCTCP.C.

References BYTE, and DWORD.

int _tcp_send | ( | _tcp_Socket * | s,
 |  | char * | file,
 |  | unsigned | line
 | ) |

Format and send an outgoing TCP segment.

Several packets may be sent depending on peer's window. Definition at line 2349 of file PCTCP.C.

References _eth_formatpacket(), _ip4_output(), _ip6_checksum(), _ip6_output(), _pktserial, _tcp_Socket::adv_win, BYTE, tcp_PseudoHeader::checksum, _tcp_Socket::cwindow, tcp_PseudoHeader::dst, _tcp_Socket::flags, _tcp_Socket::his6addr, _tcp_Socket::karn_count, tcp_PseudoHeader::length, _tcp_Socket::max_seg, _tcp_Socket::my6addr, tcp_PseudoHeader::protocol, _tcp_Socket::recent, _tcp_Socket::recv_next, _tcp_Socket::rto, _tcp_Socket::rtt_lasttran, _tcp_Socket::rtt_time, _tcp_Socket::safetysig, _tcp_Socket::safetytcp, _tcp_Socket::secret, _tcp_Socket::send_next, _tcp_Socket::send_una, set_timeout(), tcp_PseudoHeader::src, tcp_options(), tcp_RTO_ADD, _tcp_Socket::tos, _tcp_Socket::tx_data, _tcp_Socket::tx_datalen, _tcp_Socket::tx_queue, _tcp_Socket::tx_queuelen, _tcp_Socket::unhappy, _tcp_Socket::vj_last, _tcp_Socket::window, and WORD.

int _tcp_send_reset | ( | _tcp_Socket * | s,
 |  | const in_Header * | his_ip,
 |  | const tcp_Header * | org_tcp,
 |  | const char * | file,
 |  | unsigned | line
 | ) |

Format and send a reset (RST) tcp packet.

Note:
We modify the orignal segment (orig_tcp) to use it for sending.
Definition at line 2565 of file PCTCP.C.

References _default_ttl, _eth_formatpacket(), _ip4_output(), _ip6_checksum(), _ip6_output(), tcp_Header::acknum, BYTE, chk_timeout(), in6_Header::destination, in_Header::destination, tcp_Header::dstPort, DWORD, tcp_Header::flags, in6_Header::len, in_Header::length, tcp_Header::offset, _tcp_Socket::secret, tcp_Header::seqnum, set_timeout(), in6_Header::source, in_Header::source, tcp_Header::srcPort, tcp_RST_TIME, in_Header::tos, in_Header::ver, and WORD.

int _tcp_sendsoon | ( | _tcp_Socket * | s,
 |  | char * | file,
 |  | unsigned | line
 | ) |

Schedule a transmission pretty soon.

This one has an imperfection at midnight, but it is not significant to the connection performance.

Note:
gv: Added - 5 May 2000: Relax retransmission period to tcp_CLOSE_TO when CLOSEWT state is entered.
Relax retransmission period to tcp_OPEN_TO in SYNSENT state.
Definition at line 563 of file PCTCP.C.

References _tcp_send(), cmp_timers(), DWORD, _tcp_Socket::karn_count, _tcp_Socket::recent, _tcp_Socket::rto, _tcp_Socket::rtt_time, set_timeout(), _tcp_Socket::state, tcp_CLOSE_TO, tcp_OPEN_TO, tcp_RTO_BASE, tcp_RTO_SCALE, _tcp_Socket::tx_datalen, and _tcp_Socket::unhappy.

_tcp_Socket* _tcp_unthread | ( | _tcp_Socket * | ds,
 |  | BOOL | free_tx
 | ) |

Unthread a socket from the tcp socket list, if it's there.

Free Tx-buffer if set in tcp_SetWindow(). Definition at line 604 of file PCTCP.C.

References _tcp_allsocs, DWORD, _tcp_Socket::next, _tcp_Socket::state, _tcp_Socket::tx_buf, _tcp_Socket::tx_data, and _tcp_Socket::tx_datalen.

void _udp_cancel | ( | const in_Header * | ip,
 |  | int | icmp_type,
 |  | int | icmp_code,
 |  | const char * | msg,
 |  | const void * | arg
 | ) |

Cancel an UDP socket.

Called upon receiving ICMP errors: REDIRECT, TIMXCEED, PARAMPROB, or host/port UNREACH. See icmp_redirect() or icmp_handler(). Definition at line 1639 of file PCTCP.C.

References _arp_resolve(), _ip_recursion, _udp_allsocs, BYTE, in_Header::destination, DWORD, _udp_Socket::next, sock_reduce_mss(), udp_close(), and WORD.

int raw_read | ( | _raw_Socket * | raw,
 |  | BYTE * | buf,
 |  | int | maxlen
 | ) | [static]

Read data from a raw-socket.

Don't copy IP-header to buf. Definition at line 2858 of file PCTCP.C.

References BYTE, _raw_Socket::ip, in_Header::length, and _raw_Socket::used.

void run_daemons ( void ) [static]

Waterloo "background" daemon processes.

Called from tcp_tick() at each DAEMON_PERIOD interval. Definition at line 3176 of file PCTCP.C.

int sock_enqueue | ( | sock_type * | s,
 |  | const BYTE * | data,
 |  | int | len
 | ) |

For UDP, this function is same as sock_write().

For TCP, this function enqueues 'data' to transmit queue.

Note:
user must not touch 'data' while sock_tbused() returns > 0.
Definition at line 3048 of file PCTCP.C.

int sock_fastread | ( | sock_type * | s,
 |  | BYTE * | buf,
 |  | int | len
 | ) |

Read a socket with maximum 'len' bytes.

Note:
does not busywait until buffer is full.
Definition at line 2936 of file PCTCP.C.

int sock_fastwrite | ( | sock_type * | s,
 |  | const BYTE * | data,
 |  | int | len
 | ) |

Simpler, non-blocking (non-looping) version of sock_write().

Note:
UDP writes may truncate; check the return value.
Definition at line 3022 of file PCTCP.C.

void sock_flush ( sock_type * s )

Send pending TCP data.

If there is Tx-data to be sent, set the PUSH bit. Definition at line 3107 of file PCTCP.C.

int sock_read | ( | sock_type * | s,
 |  | BYTE * | buf,
 |  | int | maxlen
 | ) |

Read a socket with maximum 'maxlen' bytes.

Note:
busywaits until 'buf' is full (and call 's->usr_yield').
Return values:
0 | socket is not open.
<=maxlen | socket has data to be read.
Definition at line 2884 of file PCTCP.C.

void sock_reduce_mss | ( | sock_type * | s,
 |  | WORD | MTU
 | ) | [static]

Reduce socket MSS upon receiving ICMP_UNREACH_NEEDFRAG.

'MTU' is next-hop suggested MTU or 0 if router doesn't support RFC-1191. Definition at line 1610 of file PCTCP.C.

References _inet_ntoa(), sock_type::tcp, and WORD.

int sock_write | ( | sock_type * | s,
 |  | const BYTE * | data,
 |  | int | len
 | ) |

Writes data and returns length written.

Note:
sends with PUSH-bit (flush data).

repeatedly calls 's->usr_yield'.

UDP packetsare sent in chunks of MTU-28.

Return values:
0 | if some error in lower layer.
'len' | if all data sent okay.
Definition at line 2965 of file PCTCP.C.

void(*)(void) sock_yield ( )

Enable user defined yield function.

Return address of previous yield function. Definition at line 2813 of file PCTCP.C.

BOOL tcp_checksum | ( | const in_Header * | ip,
 |  | const tcp_Header * | tcp,
 |  | int | len
 | ) | [static]

Verify the TCP header checksum.

Note:
Not used for IPv6.
Definition at line 2047 of file PCTCP.C.

References tcp_PseudoHeader::checksum, in_Header::destination, tcp_PseudoHeader::dst, tcp_PseudoHeader::length, tcp_PseudoHeader::protocol, in_Header::source, and tcp_PseudoHeader::src.

int tcp_listen | ( | _tcp_Socket * | s,
 |  | WORD | lport,
 |  | DWORD | ip,
 |  | WORD | port,
 |  | ProtoHandler | handler,
 |  | WORD | timeout
 | ) |

Passively opens TCP a connection.

Listen for a connection on a particular port

<

Todo:
use mss from setsockopt()
Definition at line 398 of file PCTCP.C.

void tcp_no_arp ( _tcp_Socket * s ) [static]

Called for a TCP socket when ARP lookup fails.

If socket allocated by BSD API, do a read wakeup on it. Definition at line 2022 of file PCTCP.C.

References _bsd_socket_hook().

int tcp_open | ( | _tcp_Socket * | s,
 |  | WORD | lport,
 |  | DWORD | ip,
 |  | WORD | rport,
 |  | ProtoHandler | handler
 | ) |

Actively open a TCP connection.

Make connection to a particular destination. Not used for IPv6 (see _TCP6_open()).

Return values:
0 on error. 's->err_msg' filled.
Note:
'lport' is local port to associate with the connection.

'rport' is remote port for same connection.

<

Todo:
use mss from setsockopt()

use TCP_NODELAY set in setsockopt()

Definition at line 317 of file PCTCP.C.

__inline int tcp_opt_timestamp | ( | _tcp_Socket * | s,
 |  | BYTE * | opt,
 |  | DWORD | ts_echo
 | ) | [static]

Insert TimeStamp option.

nmap uses TSval (ts_now) as indication of uptime, so send # of msec since started. Definition at line 2202 of file PCTCP.C.

References BYTE, DWORD, set_timeout(), start_time, and _tcp_Socket::ts_sent.

int tcp_read | ( | _tcp_Socket * | s,
 |  | BYTE * | buf,
 |  | int | maxlen
 | ) | [static]

Read from a TCP socket.

  • buf where to put data.
    Note:
    does large buffering.
Definition at line 1838 of file PCTCP.C.

References _tcp_close(), BYTE, _tcp_Socket::missed_seq, _tcp_Socket::recv_next, _tcp_Socket::state, tcp_read(), and tcp_upd_win().

void tcp_Retransmitter ( BOOL force )

Called periodically to perform retransmissions.

  • if 'force == 1' do it now.

< dup ACK counter ?

<

Todo:
set "Slow-start" threshold

Allow for 3 SYN before giving up

< Definition at line 1217 of file PCTCP.C.

References _tcp_allsocs, _tcp_unthread(), arp_lookup(), arp_lookup_pending(), BYTE, chk_timeout(), DWORD, get_timediff(), _tcp_Socket::next, _tcp_Socket::rtt_time, set_timeout(), sock_close(), _tcp_Socket::state, tcp_no_arp(), tcp_OPEN_TO, tcp_RETRAN_TIME, _tcp_Socket::timeout, and UINT.

void tcp_rtt_win ( _tcp_Socket * s ) [static]

Update retransmission timer, VJ algorithm and TCP windows.

Only called after we received something on socket.

Todo:
Use TimeStamp option values

Use the threshold to signify "end-of-Slow-Start" (equilibrium)

Definition at line 2073 of file PCTCP.C.

References chk_timeout(), cmp_timers(), _tcp_Socket::cwindow, _tcp_Socket::datatimer, DWORD, get_timediff(), _tcp_Socket::karn_count, _tcp_Socket::max_seg, _tcp_Socket::rto, _tcp_Socket::rtt_time, _tcp_Socket::send_una, set_timeout(), tcp_MAX_VJSA, tcp_MAX_VJSD, tcp_RTO_ADD, tcp_RTO_BASE, _tcp_Socket::ts_echo, _tcp_Socket::ts_sent, _tcp_Socket::vj_last, _tcp_Socket::vj_sa, _tcp_Socket::vj_sd, and _tcp_Socket::wwindow.

WORD tcp_tick ( sock_type * s )

Must be called periodically by user application (or BSD socket API).

  • if 's != NULL', check this socket for timeout.
  • if 's == NULL', check all sockets in list.
Return values:
0 | if 's' is non-NULL and 's' closes.
!0 | if 's' is NULL or 's' is still open.

Don't enter this loop if reentered. That could return the same packet twice (before we call _eth_free() on the 1st packet).

Todo:
Limit the time spent here (clamp # of loops)
Definition at line 1397 of file PCTCP.C.

References _arp_handler(), _eth_arrived(), _eth_free(), _ip4_handler(), _rarp_handler(), _tcp_unthread(), chk_timeout(), daemon_timer, pppoe_handler(), run_daemons(), set_timeout(), _tcp_Socket::state, sock_type::tcp, tcp_Retransmitter(), and WORD.

int tcp_write | ( | _tcp_Socket * | s,
 |  | const BYTE * | data,
 |  | UINT | len
 | ) | [static]

Write data to a TCP connection.

Return values:
>0 | Number of bytes written.
0 | Connection is not established.
-1 | Error in lower layer.
Definition at line 1886 of file PCTCP.C.

References BYTE, _tcp_Socket::datatimer, _tcp_Socket::max_seg, _tcp_Socket::max_tx_data, set_timeout(), _tcp_Socket::state, _tcp_Socket::tx_data, _tcp_Socket::tx_datalen, UINT, and _tcp_Socket::unhappy.

_udp_Socket* udp_demux | ( | const in_Header * | ip,
 |  | BOOL | ip_bcast,
 |  | DWORD | destin,
 |  | WORD | srcPort,
 |  | WORD | dstPort,
 |  | BOOL * | udp_err
 | ) | [static]

Demultiplexer for incoming UDP packets.

Don't debug packet if no match was found (except if '*udp_err').

Demux to active sockets.

Todo:
use some kind of hashing to speed up the search.
Definition at line 881 of file PCTCP.C.

References _udp_allsocs, in6_Header::destination, _udp_Socket::his6addr, ip6_address, _udp_Socket::my6addr, _udp_Socket::next, _udp_Socket::safetysig, sin_mask, in_Header::source, in6_Header::source, in_Header::ver, and WORD.

int udp_listen | ( | _udp_Socket * | s,
 |  | WORD | lport,
 |  | DWORD | ip,
 |  | WORD | port,
 |  | ProtoHandler | handler
 | ) |

UDP passive open.

Listen for a connection on a particular port. Definition at line 167 of file PCTCP.C.

int udp_open | ( | _udp_Socket * | s,
 |  | WORD | lport,
 |  | DWORD | ip,
 |  | WORD | port,
 |  | ProtoHandler | handler
 | ) |

UDP active open.

Open a connection on a particular port. Definition at line 202 of file PCTCP.C.

int udp_read | ( | _udp_Socket * | s,
 |  | BYTE * | buf,
 |  | int | maxlen
 | ) | [static]

Read from UDP socket.

  • buf where data is put.
  • maxlen read max this amount.
    Note:
    does large buffering.
Definition at line 1583 of file PCTCP.C.

References BYTE, and udp_read().

int udp_write | ( | _udp_Socket * | s,
 |  | const BYTE * | data,
 |  | int | len
 | ) | [static]

Write an UDP packet.

Note:
Assumes data fits in one datagram, else only the first fragment will be sent! Because MTU is used for splits, the guaranteed max data size is 'MTU - UDP_OVERHEAD = 548' for a non-fragmented datagram. Routers should handle at least 576 bytes datagrams.
Definition at line 1503 of file PCTCP.C.

References _default_tos, _eth_formatpacket(), _ip6_checksum(), _pktserial, BYTE, and _udp_Socket::his6addr.

Variable Documentation

char hostname[MAX_HOSTLEN+1] = "random-pc"

Our configured hostname.

Not the FQDN. Definition at line 66 of file PCTCP.C.

struct { ... } MAX_DAEMONS [static]

List of background processes.

Note:
there can be no more than MAX_DAEMONS background processes.

BOOL mtu_blackhole = 0

Todo:
Add PMTU blackhole detection
Definition at line 71 of file PCTCP.C.

BOOL mtu_discover = 0

Todo:
Add PMTU discovery method
Definition at line 70 of file PCTCP.C.

struct tcp_rtt rtt_cache[RTTCACHE] [static]

Round-trip timing cache routines.

These functions implement a very simple system for keeping track of network performance for future use in new connections. The emphasis here is on speed of update (rather than optimum cache hit ratio) since tcp_rtt_add() is called every time a TCP connection updates its round trip estimate.

Note:
'rto' is either in ticks or milli-sec depending on if PC has an 8254 Time chip.
These routines are modified versions from KA9Q by Phil Karn. Definition at line 3238 of file PCTCP.C.

unsigned tcp_MAX_VJSA = DEF_MAX_VJSA

Default max VJ std.

average Definition at line 127 of file PCTCP.C.

unsigned tcp_MAX_VJSD = DEF_MAX_VJSD

Default max VJ std.

deviation Definition at line 128 of file PCTCP.C.

BOOL tcp_nagle = TRUE

Nagle algo.

is on globally Definition at line 138 of file PCTCP.C.

Generated on Wed Jan 25 15:42:42 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/PCTCP.H File Reference

SRC/PCTCP.H File Reference

Detailed Description

Definition in file PCTCP.H.

Go to the source code of this file.

Data Structures

struct | tcp_rtt

Enumerations

enum BSD_SOCKET_OPS {
BSO_FIND_SOCK = 1,
BSO_SYN_CALLBACK,
BSO_RST_CALLBACK,
BSO_IP4_RAW,
BSO_IP6_RAW,
BSO_DEBUG
}

Functions

void | _udp_cancel (const in_Header *, int, int, const char *, const void *)
Cancel an UDP socket.
void | _tcp_cancel (const in_Header *, int, int, const char *, const void *)
Cancel a TCP socket.
void | _tcp_close (_tcp_Socket *s)
Close a TCP connection.
void | tcp_rtt_add (const _tcp_Socket *s, UINT rto, UINT MTU)
void | tcp_rtt_clr (const _tcp_Socket *s)
BOOL | tcp_rtt_get (const _tcp_Socket *s, UINT *rto, UINT *MTU)
int | tcp_established (const _tcp_Socket *s)
Returns 1 if TCP connection is established.
int | _tcp_send (_tcp_Socket *s, char *file, unsigned line)
Format and send an outgoing TCP segment.
int | _tcp_sendsoon (_tcp_Socket *s, char *file, unsigned line)
Schedule a transmission pretty soon.
int | _tcp_keepalive (_tcp_Socket *s)
TCP keepalive transmission.
void | tcp_Retransmitter (BOOL force)
Called periodically to perform retransmissions.
_udp_Socket * | _udp_handler (const in_Header *ip, BOOL broadcast)
Handler for incoming UDP packets.
_tcp_Socket * | _tcp_handler (const in_Header *ip, BOOL broadcast)
The main TCP input handler.
_tcp_Socket * | _tcp_unthread (_tcp_Socket *s, BOOL free_tx)
Unthread a socket from the tcp socket list, if it's there.
_tcp_Socket * | _tcp_abort (_tcp_Socket *s, const char *file, unsigned line)
Abort a TCP connection.
int | _tcp_send_reset (_tcp_Socket *s, const in_Header *ip, const tcp_Header *tcp, const char *file, unsigned line)
Format and send a reset (RST) tcp packet.
W32_FUNC WORD | tcp_tick (sock_type *s)
Must be called periodically by user application (or BSD socket API).
W32_FUNC int | tcp_open (_tcp_Socket *s, WORD lport, DWORD ina, WORD port, ProtoHandler handler)
Actively open a TCP connection.
W32_FUNC int | tcp_listen (_tcp_Socket *s, WORD lport, DWORD ina, WORD port, ProtoHandler handler, WORD timeout)
Passively opens TCP a connection.
W32_FUNC int | udp_open (_udp_Socket *s, WORD lport, DWORD ina, WORD port, ProtoHandler handler)
UDP active open.
W32_FUNC int | udp_listen (_udp_Socket *s, WORD lport, DWORD ina, WORD port, ProtoHandler handler)
UDP passive open.
W32_FUNC void | udp_SetTTL (_udp_Socket *s, BYTE ttl)
Set the TTL on an outgoing UDP datagram.
W32_FUNC void | sock_abort (sock_type *s)
Abort a UDP/TCP/Raw socket.
W32_FUNC int | sock_read (sock_type *s, BYTE *dp, int len)
Read a socket with maximum 'maxlen' bytes.
W32_FUNC int | sock_fastread (sock_type *s, BYTE *dp, int len)
Read a socket with maximum 'len' bytes.
W32_FUNC int | sock_write (sock_type *s, const BYTE *dp, int len)
Writes data and returns length written.
W32_FUNC int | sock_fastwrite (sock_type *s, const BYTE *dp, int len)
Simpler, non-blocking (non-looping) version of sock_write().
W32_FUNC int | sock_enqueue (sock_type *s, const BYTE *dp, int len)
For UDP, this function is same as sock_write().
W32_FUNC void | sock_noflush (sock_type *s)
Sets non-flush mode on next TCP write.
W32_FUNC void | sock_flush (sock_type *s)
Send pending TCP data.
W32_FUNC void | sock_flushnext (sock_type *s)
Causes next transmission to have a flush (PUSH bit set).
W32_FUNC BYTE | sock_putc (sock_type *s, BYTE c)
W32_FUNC int | sock_getc (sock_type *s)
W32_FUNC int | sock_puts (sock_type *s, const BYTE *dp)
W32_FUNC int | sock_gets (sock_type *s, BYTE *dp, int n)
W32_FUNC WORD | sock_dataready (sock_type *s)
sock_dataready - returns number of bytes waiting to be read.
W32_FUNC int | sock_close (sock_type *s)
Close a UDP/TCP socket.
W32_FUNC WORD | sock_mode (sock_type *s, WORD mode)
W32_FUNC int | sock_sselect (const sock_type *s, int state)
W32_FUNC int | sock_keepalive (sock_type *s)
W32_FUNC int | addwattcpd (void(*p)(void))
Add a function to background daemon list.
W32_FUNC int | delwattcpd (void(*p)(void))
Remove a function from background daemon list.
W32_FUNC int MS_CDECL | sock_printf (sock_type *s, const char *fmt,...) ATTR_PRINTF(2
W32_FUNC int MS_CDECL | sock_scanf (sock_type *s, const char *fmt,...) ATTR_SCANF(2
void *MS_CDECL * | _bsd_socket_hook (enum BSD_SOCKET_OPS op,...)
WORD | init_localport (void)
Allocate the "lport_inuse" bit-array from heap.
WORD | find_free_port (WORD oldport, BOOL sleep_msl)
int | grab_localport (WORD port)
int | reuse_localport (WORD port)
int | maybe_reuse_localport (_tcp_Socket *s)
W32_FUNC void | ip_timer_init (sock_type *s, unsigned)
W32_FUNC int | ip_timer_expired (const sock_type *s)
W32_FUNC int | _ip_delay0 (sock_type *, int, UserHandler, int *)
W32_FUNC int | _ip_delay1 (sock_type *, int, UserHandler, int *)
W32_FUNC int | _ip_delay2 (sock_type *, int, UserHandler, int *)
W32_FUNC int | sock_timeout (sock_type *, int)
W32_FUNC int | sock_established (sock_type *)

Variables

W32_DATA unsigned | _mtu
W32_DATA unsigned | _mss
W32_DATA DWORD | my_ip_addr
W32_DATA DWORD | sin_mask
W32_DATA BOOL | block_tcp
W32_DATA BOOL | block_udp
W32_DATA BOOL | block_icmp
W32_DATA BOOL | block_ip
W32_DATA unsigned | tcp_keep_idle
W32_DATA unsigned | tcp_keep_intvl
W32_DATA unsigned | tcp_max_idle
W32_DATA char | hostname [MAX_HOSTLEN+1]
BOOL | mtu_discover
BOOL | mtu_blackhole
BOOL | use_rand_lport
BOOL | tcp_nagle
Nagle algo.
BOOL | tcp_opt_ts
TCP option config flags (RFC 1323).
BOOL | tcp_opt_sack
BOOL | tcp_opt_wscale
_tcp_Socket * _tcp_allsocs
list of tcp-sockets
_udp_Socket * _udp_allsocs
list of udp-sockets
W32_DATA unsigned | tcp_OPEN_TO
W32_DATA unsigned | tcp_CLOSE_TO
W32_DATA unsigned | tcp_RTO_ADD
W32_DATA unsigned | tcp_RTO_BASE
W32_DATA unsigned | tcp_RTO_SCALE
W32_DATA unsigned | tcp_RST_TIME
W32_DATA unsigned | tcp_RETRAN_TIME
W32_DATA unsigned | tcp_MAX_VJSA
W32_DATA unsigned | tcp_MAX_VJSD
W32_DATA DWORD | tcp_recv_win
W32_FUNC void(*)(void) | sock_yield (_tcp_Socket *s, void(*fn)(void))

Function Documentation

void _tcp_cancel | ( | const in_Header * | ip,
 |  | int | icmp_type,
 |  | int | icmp_code,
 |  | const char * | msg,
 |  | const void * | arg
 | ) |

Cancel a TCP socket.

Called upon receiving ICMP errors: host/port UNREACH, REDIRECT, SOURCEQUENCH, TIMXCEED or PARAMPROB. See icmp_redirect() or icmp_handler().

Note: 'ip' is a small copy of the IP-packet originating the ICMP message. We may *not* have received a copy of the original TCP-header. But we probably won't do any harm if got less TCP-header data than needed. I.e. src_port/dst_port will be zero. Definition at line 1745 of file PCTCP.C.

References _arp_resolve(), _ip_recursion, _tcp_allsocs, BYTE, _tcp_Socket::cwindow, in_Header::destination, DWORD, _tcp_Socket::next, _tcp_Socket::rto, sock_reduce_mss(), _tcp_Socket::state, _tcp_Socket::vj_sa, _tcp_Socket::vj_sd, WORD, and _tcp_Socket::wwindow.

void _tcp_close ( _tcp_Socket * s )

Close a TCP connection.

Send a FIN on a particular port -- only works if it is open. Must still allow receives. Definition at line 464 of file PCTCP.C.

References _tcp_unthread(), _tcp_Socket::flags, _tcp_Socket::rtt_time, set_timeout(), _tcp_Socket::state, _tcp_Socket::timeout, _tcp_Socket::tx_datalen, and _tcp_Socket::unhappy.

_tcp_Socket* _tcp_handler | ( | const in_Header * | ip,
 |  | BOOL | broadcast
 | ) |

The main TCP input handler.

All TCP input processing is done from here. Definition at line 653 of file PCTCP.C.

References _ip6_tcp_checksum(), _tcp_allsocs, _tcp_Socket::adv_win, block_tcp, BYTE, in6_Header::destination, in_Header::destination, DWORD, _tcp_Socket::his6addr, _tcp_Socket::inactive_to, ip6_address, in6_Header::len, in_Header::length, _tcp_Socket::my6addr, _tcp_Socket::next, _tcp_Socket::recv_next, _tcp_Socket::safetysig, _tcp_Socket::safetytcp, set_timeout(), in6_Header::source, in_Header::source, tcp_checksum(), tcp_findseq(), tcp_rtt_win(), tcp_sockreset(), _tcp_Socket::unhappy, in_Header::ver, and WORD.

int _tcp_keepalive ( _tcp_Socket * tcp )

TCP keepalive transmission.

If connection is idle (tx_datalen == 0), force the peer to send us a segment by sending a keep-alive packet:

 *    <SEQ=SND.UNA-1><ACK=RCV.NXT><CTL=ACK>
 *
Definition at line 2708 of file PCTCP.C.

References BYTE, and DWORD.

int _tcp_send | ( | _tcp_Socket * | s,
 |  | char * | file,
 |  | unsigned | line
 | ) |

Format and send an outgoing TCP segment.

Several packets may be sent depending on peer's window. Definition at line 2349 of file PCTCP.C.

References _eth_formatpacket(), _ip4_output(), _ip6_checksum(), _ip6_output(), _pktserial, _tcp_Socket::adv_win, BYTE, tcp_PseudoHeader::checksum, _tcp_Socket::cwindow, tcp_PseudoHeader::dst, _tcp_Socket::flags, _tcp_Socket::his6addr, _tcp_Socket::karn_count, tcp_PseudoHeader::length, _tcp_Socket::max_seg, _tcp_Socket::my6addr, tcp_PseudoHeader::protocol, _tcp_Socket::recent, _tcp_Socket::recv_next, _tcp_Socket::rto, _tcp_Socket::rtt_lasttran, _tcp_Socket::rtt_time, _tcp_Socket::safetysig, _tcp_Socket::safetytcp, _tcp_Socket::secret, _tcp_Socket::send_next, _tcp_Socket::send_una, set_timeout(), tcp_PseudoHeader::src, tcp_options(), tcp_RTO_ADD, _tcp_Socket::tos, _tcp_Socket::tx_data, _tcp_Socket::tx_datalen, _tcp_Socket::tx_queue, _tcp_Socket::tx_queuelen, _tcp_Socket::unhappy, _tcp_Socket::vj_last, _tcp_Socket::window, and WORD.

int _tcp_send_reset | ( | _tcp_Socket * | s,
 |  | const in_Header * | his_ip,
 |  | const tcp_Header * | org_tcp,
 |  | const char * | file,
 |  | unsigned | line
 | ) |

Format and send a reset (RST) tcp packet.

Note:
We modify the orignal segment (orig_tcp) to use it for sending.
Definition at line 2565 of file PCTCP.C.

References _default_ttl, _eth_formatpacket(), _ip4_output(), _ip6_checksum(), _ip6_output(), tcp_Header::acknum, BYTE, chk_timeout(), in_Header::destination, in6_Header::destination, tcp_Header::dstPort, DWORD, tcp_Header::flags, in6_Header::len, in_Header::length, tcp_Header::offset, _tcp_Socket::secret, tcp_Header::seqnum, set_timeout(), in_Header::source, in6_Header::source, tcp_Header::srcPort, tcp_RST_TIME, in_Header::tos, in_Header::ver, and WORD.

int _tcp_sendsoon | ( | _tcp_Socket * | s,
 |  | char * | file,
 |  | unsigned | line
 | ) |

Schedule a transmission pretty soon.

This one has an imperfection at midnight, but it is not significant to the connection performance.

Note:
gv: Added - 5 May 2000: Relax retransmission period to tcp_CLOSE_TO when CLOSEWT state is entered.
Relax retransmission period to tcp_OPEN_TO in SYNSENT state.
Definition at line 563 of file PCTCP.C.

References _tcp_send(), cmp_timers(), DWORD, _tcp_Socket::karn_count, _tcp_Socket::recent, _tcp_Socket::rto, _tcp_Socket::rtt_time, set_timeout(), _tcp_Socket::state, tcp_CLOSE_TO, tcp_OPEN_TO, tcp_RTO_BASE, tcp_RTO_SCALE, _tcp_Socket::tx_datalen, and _tcp_Socket::unhappy.

_tcp_Socket* _tcp_unthread | ( | _tcp_Socket * | ds,
 |  | BOOL | free_tx
 | ) |

Unthread a socket from the tcp socket list, if it's there.

Free Tx-buffer if set in tcp_SetWindow(). Definition at line 604 of file PCTCP.C.

References _tcp_allsocs, DWORD, _tcp_Socket::next, _tcp_Socket::state, _tcp_Socket::tx_buf, _tcp_Socket::tx_data, and _tcp_Socket::tx_datalen.

void _udp_cancel | ( | const in_Header * | ip,
 |  | int | icmp_type,
 |  | int | icmp_code,
 |  | const char * | msg,
 |  | const void * | arg
 | ) |

Cancel an UDP socket.

Called upon receiving ICMP errors: REDIRECT, TIMXCEED, PARAMPROB, or host/port UNREACH. See icmp_redirect() or icmp_handler(). Definition at line 1639 of file PCTCP.C.

References _arp_resolve(), _ip_recursion, _udp_allsocs, BYTE, in_Header::destination, DWORD, _udp_Socket::next, sock_reduce_mss(), udp_close(), and WORD.

WORD init_localport ( void )

Allocate the "lport_inuse" bit-array from heap.

Return values:
Highest usable port.
Todo:
Make empherical port range configurable.

Use some hashing technique to speed up find_free_port().

Definition at line 46 of file PORTS.C.

References exit_localport(), and WORD.

W32_FUNC WORD sock_dataready ( sock_type * s )

sock_dataready - returns number of bytes waiting to be read.

  • if in ASCII mode, return >0 if a terminated line is present or the buffer is full or state is LASTACK (tcp only).
  • if in binary mode (default), simply return number of bytes in receive buffer.
  • For UDP or TCP sockets only.
Definition at line 246 of file SOCK_IO.C.

W32_FUNC int sock_enqueue | ( | sock_type * | s,
 |  | const BYTE * | data,
 |  | int | len
 | ) |

For UDP, this function is same as sock_write().

For TCP, this function enqueues 'data' to transmit queue.

Note:
user must not touch 'data' while sock_tbused() returns > 0.
Definition at line 3048 of file PCTCP.C.

References BYTE, sock_enqueue(), sock_type::tcp, _tcp_Socket::tx_datalen, _tcp_Socket::tx_queue, _tcp_Socket::tx_queuelen, sock_type::udp, and udp_write().

W32_FUNC int sock_fastread | ( | sock_type * | s,
 |  | BYTE * | buf,
 |  | int | len
 | ) |

Read a socket with maximum 'len' bytes.

Note:
does not busywait until buffer is full.
Definition at line 2936 of file PCTCP.C.

References BYTE, _raw_Socket::ip_type, sock_type::raw, raw_read(), sock_fastread(), sock_type::tcp, tcp_read(), sock_type::udp, and udp_read().

W32_FUNC int sock_fastwrite | ( | sock_type * | s,
 |  | const BYTE * | data,
 |  | int | len
 | ) |

Simpler, non-blocking (non-looping) version of sock_write().

Note:
UDP writes may truncate; check the return value.
Definition at line 3022 of file PCTCP.C.

References BYTE, sock_fastwrite(), sock_type::tcp, tcp_write(), sock_type::udp, and udp_write().

W32_FUNC void sock_flush ( sock_type * s )

Send pending TCP data.

If there is Tx-data to be sent, set the PUSH bit. Definition at line 3107 of file PCTCP.C.

References _tcp_Socket::send_una, sock_flush(), and sock_type::tcp.

W32_FUNC int sock_puts | ( | sock_type * | s,
 |  | const BYTE * | data
 | ) |

<

Todo:
suppport UDP frags
Definition at line 39 of file SOCK_IO.C.

W32_FUNC int sock_read | ( | sock_type * | s,
 |  | BYTE * | buf,
 |  | int | maxlen
 | ) |

Read a socket with maximum 'maxlen' bytes.

Note:
busywaits until 'buf' is full (and call 's->usr_yield').
Return values:
0 | socket is not open.
<=maxlen | socket has data to be read.
Definition at line 2884 of file PCTCP.C.

References BYTE, sock_type::raw, raw_read(), sock_read(), sock_type::tcp, tcp_read(), tcp_tick(), sock_type::udp, and udp_read().

W32_FUNC int sock_write | ( | sock_type * | s,
 |  | const BYTE * | data,
 |  | int | len
 | ) |

Writes data and returns length written.

Note:
sends with PUSH-bit (flush data).

repeatedly calls 's->usr_yield'.

UDP packetsare sent in chunks of MTU-28.

Return values:
0 | if some error in lower layer.
'len' | if all data sent okay.
Definition at line 2965 of file PCTCP.C.

References BYTE, _tcp_Socket::flags, sock_write(), sock_type::tcp, tcp_tick(), tcp_write(), sock_type::udp, and udp_write().

W32_FUNC int tcp_listen | ( | _tcp_Socket * | s,
 |  | WORD | lport,
 |  | DWORD | ip,
 |  | WORD | port,
 |  | ProtoHandler | handler,
 |  | WORD | timeout
 | ) |

Passively opens TCP a connection.

Listen for a connection on a particular port

<

Todo:
use mss from setsockopt()
Definition at line 398 of file PCTCP.C.

References _default_ttl, _eth_is_init, _inet_ntoa(), _tcp_allsocs, _tcp_unthread(), ProtoHandler, set_timeout(), tcp_listen(), tcp_nagle, _tcp_Socket::timeout, and WORD.

W32_FUNC int tcp_open | ( | _tcp_Socket * | s,
 |  | WORD | lport,
 |  | DWORD | ip,
 |  | WORD | rport,
 |  | ProtoHandler | handler
 | ) |

Actively open a TCP connection.

Make connection to a particular destination. Not used for IPv6 (see _TCP6_open()).

Return values:
0 on error. 's->err_msg' filled.
Note:
'lport' is local port to associate with the connection.

'rport' is remote port for same connection.

<

Todo:
use mss from setsockopt()

use TCP_NODELAY set in setsockopt()

Definition at line 317 of file PCTCP.C.

References _default_ttl, _eth_is_init, _inet_ntoa(), _tcp_allsocs, _tcp_unthread(), arp_start_lookup(), my_ip_addr, ProtoHandler, tcp_nagle, tcp_open(), tcp_OPEN_TO, and WORD.

void tcp_Retransmitter ( BOOL force )

Called periodically to perform retransmissions.

  • if 'force == 1' do it now.

< dup ACK counter ?

<

Todo:
set "Slow-start" threshold

Allow for 3 SYN before giving up

< Definition at line 1217 of file PCTCP.C.

References _tcp_allsocs, _tcp_unthread(), arp_lookup(), arp_lookup_pending(), BYTE, chk_timeout(), DWORD, get_timediff(), _tcp_Socket::next, _tcp_Socket::rtt_time, set_timeout(), sock_close(), _tcp_Socket::state, tcp_no_arp(), tcp_OPEN_TO, tcp_RETRAN_TIME, _tcp_Socket::timeout, and UINT.

W32_FUNC WORD tcp_tick ( sock_type * s )

Must be called periodically by user application (or BSD socket API).

  • if 's != NULL', check this socket for timeout.
  • if 's == NULL', check all sockets in list.
Return values:
0 | if 's' is non-NULL and 's' closes.
!0 | if 's' is NULL or 's' is still open.

Don't enter this loop if reentered. That could return the same packet twice (before we call _eth_free() on the 1st packet).

Todo:
Limit the time spent here (clamp # of loops)
Definition at line 1397 of file PCTCP.C.

W32_FUNC int udp_listen | ( | _udp_Socket * | s,
 |  | WORD | lport,
 |  | DWORD | ip,
 |  | WORD | port,
 |  | ProtoHandler | handler
 | ) |

UDP passive open.

Listen for a connection on a particular port. Definition at line 167 of file PCTCP.C.

References _default_ttl, _eth_is_init, _udp_allsocs, ProtoHandler, udp_close(), udp_listen(), and WORD.

W32_FUNC int udp_open | ( | _udp_Socket * | s,
 |  | WORD | lport,
 |  | DWORD | ip,
 |  | WORD | port,
 |  | ProtoHandler | handler
 | ) |

UDP active open.

Open a connection on a particular port. Definition at line 202 of file PCTCP.C.

References _arp_resolve(), _default_ttl, _eth_is_init, _inet_ntoa(), _udp_allsocs, eth_address, my_ip_addr, ProtoHandler, sin_mask, udp_close(), udp_open(), and WORD.

Variable Documentation

BOOL mtu_blackhole

Todo:
Add PMTU blackhole detection
Definition at line 71 of file PCTCP.C.

BOOL mtu_discover

Todo:
Add PMTU discovery method
Definition at line 70 of file PCTCP.C.

BOOL tcp_nagle

Nagle algo.

is on globally Definition at line 138 of file PCTCP.C.

Generated on Wed Jan 25 15:42:43 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/POLL.C File Reference

SRC/POLL.C File Reference

Detailed Description

BSD poll().

Definition in file POLL.C.

Go to the source code of this file.

Functions

int poll (struct pollfd *p, int num, int timeout)

Generated on Wed Jan 25 15:42:43 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/PORTS.C File Reference

SRC/PORTS.C File Reference

Detailed Description

Handling of local ports used by UDP/TCP.

Moved from pctcp.c

Definition in file PORTS.C.

Go to the source code of this file.

Functions

void | exit_localport (void)
Free allocated memory.
WORD | init_localport (void)
Allocate the "lport_inuse" bit-array from heap.
WORD | find_free_port (WORD port, BOOL linger)
int | grab_localport (WORD port)
int | reuse_localport (WORD port)
int | maybe_reuse_localport (_tcp_Socket *s)

Variables

int | use_rand_lport = TRUE
fd_set * | lport_inuse

Function Documentation

WORD init_localport ( void )

Allocate the "lport_inuse" bit-array from heap.

Return values:
Highest usable port.
Todo:
Make empherical port range configurable.

Use some hashing technique to speed up find_free_port().

Definition at line 46 of file PORTS.C.

References exit_localport(), and WORD.

Generated on Wed Jan 25 15:42:43 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/POWERPAK.C File Reference

SRC/POWERPAK.C File Reference

Detailed Description

A djgpp-like DOS memory interface for Borland's DOS extender (32rtm). Only Borland's BCC32 v4.5+ supported.

by G. Vanem <giva@bgnett.no> Nov 2002

Running PowerPak under plain DOS, the 32rtm extender tries to emulate a subset of the Win32 API. Running the same app. under Win32 uses the real Win32 API (from kernel32.dll etc.). So then we cannot use int386() etc., but must use native calls. This isn't finished yet (I at all possible).

Definition in file POWERPAK.C.

Go to the source code of this file.

Functions

void *WINAPI | GetModuleHandleA (const char *module)
void *WINAPI | GetProcAddress (void *module, const char *func)
UINT (WINAPI *_AllocSelector)(UINT)
BOOL | powerpak_init (void)
WORD | dpmi_create_dos_selector (void)
int | dpmi_free_dos_selector (WORD sel)
void | ReadRealMem (void *dst, REALPTR rp, unsigned size)
void | WriteRealMem (REALPTR rp, const void *src, int size)
BYTE | _farpeekb (WORD sel, DWORD ofs)
WORD | _farpeekw (WORD sel, DWORD ofs)
DWORD | _farpeekl (WORD sel, DWORD ofs)
void | _farpokeb (WORD sel, DWORD ofs, BYTE val)
void | _farpokew (WORD sel, DWORD ofs, WORD val)
void | _farpokel (WORD sel, DWORD ofs, DWORD val)
int | dpmi_getvect (int intr, WORD *sel, DWORD *ofs)
int | dpmi_setvect (int intr, WORD sel, DWORD ofs)
REALPTR | alloc_callback (void(*callback)(void), REAL_regs *regs)
REALPTR | dpmi_alloc_callback_retf (DPMI_callback *cb)
int | dpmi_free_callback_retf (DPMI_callback *cb)

Variables

int | _ostype
BYTE | wrapper_code []

Generated on Wed Jan 25 15:42:43 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/POWERPAK.H File Reference

SRC/POWERPAK.H File Reference

Detailed Description

Definition in file POWERPAK.H.

Go to the source code of this file.

Data Structures

struct | REAL_regs
struct | DPMI_callback

Functions

BOOL | powerpak_init (void)
WORD | dpmi_create_dos_selector (void)
int | dpmi_free_dos_selector (WORD sel)
int | dpmi_delete_memory_alias (void)
DWORD | dpmi_create_memory_alias (DWORD addr, DWORD len)
REALPTR | dpmi_alloc_callback_retf (DPMI_callback *cb)
int | dpmi_free_callback_retf (DPMI_callback *cb)
int | dpmi_getvect (int intr, WORD *sel, DWORD *ofs)
int | dpmi_setvect (int intr, WORD sel, DWORD ofs)
void | ReadRealMem (void *buf, REALPTR rp, unsigned len)
void | WriteRealMem (REALPTR rp, const void *src, int size)
BYTE | _farpeekb (WORD sel, DWORD ofs)
WORD | _farpeekw (WORD sel, DWORD ofs)
DWORD | _farpeekl (WORD sel, DWORD ofs)
void | _farpokeb (WORD sel, DWORD ofs, BYTE val)
void | _farpokew (WORD sel, DWORD ofs, WORD val)
void | _farpokel (WORD sel, DWORD ofs, DWORD val)

Generated on Wed Jan 25 15:42:43 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/PPP.C File Reference

SRC/PPP.C File Reference

Detailed Description

PPP tunneled over Ethernet (PPPOE_SESS_TYPE frames)

This implements just LCP and IPCP, and then only a subset of each of those. This is not supported and probably shouldn't be used for much more than simple experiments with PPP. If you need a real version of PPP, see Paul Mackerras' ppp-2.3. If you do try to use this, don't say I didn't warn you.

This code may be used for any purpose as long as the author's copyright is cited in any source code distributed. This code is also available electronically from the author's web site.

http://people.ne.mediaone.net/carlson/ppp

http://www.workingcode.com/ppp

Copyright 1997 by James Carlson and Working Code

Adapted for Watt-32's PPPoE extension by G. Vanem Aug-2000

Definition in file PPP.C.

Go to the source code of this file.

Data Structures

struct | ppp_dispatch

Functions

void | ipcp_addr_req (struct ppp_state *state, struct ppp_xcp *xcp, const struct xcp_type *tp, const BYTE *buf, int len)
void | ipcp_addr_nak (struct ppp_state *state, struct ppp_xcp *xcp, const struct xcp_type *tp, const BYTE *buf, int len)
void | ipcp_addr_show (struct ppp_state *state, struct ppp_xcp *xcp, const struct xcp_type *tp, const BYTE *buf, int len)
void | send_event (struct ppp_state *state, struct ppp_xcp *xcp, enum ppp_event event)
void | change_phase (struct ppp_state *state, enum ppp_phase phase)
void | buffer_print (const char *verb, const BYTE *buf, int len)
void | safe_string (const BYTE *bp, int len)
void | option_show (const struct ppp_state *state, const struct ppp_xcp *xcp, const BYTE *bp, int rlen)
void | show_packet (const char *inout, const struct ppp_state *state, const struct ppp_xcp *xcp, const BYTE *bp, int len)
void | ppp_write (const struct ppp_state *state, const struct ppp_xcp *xcp, const BYTE *buf, int len)
__inline BYTE * | setup_acpf (BYTE *buf, WORD proto)
BYTE * | code_id (struct ppp_state *state, struct ppp_xcp *xcp, int code)
BYTE * | code_reply (struct ppp_state *state, struct ppp_xcp *xcp, int code)
option_state * | find_option (const struct ppp_xcp *xcp, int type)
void | create_request (struct ppp_state *state, struct ppp_xcp *xcp)
void | copy_peer_values (const struct ppp_state *state, struct ppp_xcp *xcp)
void | dispatch_action (struct ppp_state *state, struct ppp_xcp *xcp, enum xcp_action act)
void | check_timeouts (void)
void | ppp_input (const BYTE *inbuffer, WORD len)
The PPP input handler.
void | set_reject (struct ppp_state *state, struct ppp_xcp *xcp, const BYTE *bp)
void | set_nak (struct ppp_state *state, struct ppp_xcp *xcp, int type, int len, const BYTE *bp)
int | validate_request (struct ppp_state *state, struct ppp_xcp *xcp)
void | process_rcx (struct ppp_state *state, struct ppp_xcp *xcp, BYTE code)
void | std_negotiation (struct ppp_state *state, struct ppp_xcp *xcp)
void | init_xcp (const char *name, struct ppp_xcp *xcp, void(*deliver)(struct ppp_state *state, struct ppp_xcp *xcp), const struct xcp_type *types, int ntypes, WORD proto)
void | set_option_value_lcl (struct ppp_xcp *xcp, int type, int value)
void | set_option_value_rem (struct ppp_xcp *xcp, int type, int value)
void | ppp_start (int dbg_level)

Variables

DWORD | remote_ip_base = 0x0A000000
DWORD | remote_ip_mask = 0xFF000000
int | debug = 0
ppp_state | mystate
const struct xcp_type | lcp_types []
const struct xcp_type | ipcp_types []
const struct ppp_dispatch | ppp_dispatch [10][16]
const char * | ph_str []
const char * | ev_str []
const char * | st_str []
const char * | ac_str []

Function Documentation

void std_negotiation | ( | struct ppp_state * | state,
 |  | struct ppp_xcp * | xcp
 | ) | [static]

Todo:
extract LCP_MRU option
Definition at line 1080 of file PPP.C.

References BYTE, and WORD.

Variable Documentation

const char* ac_str[] [static]

Initial value:

 {
                  "Null", "irc", "scr", "tls", "tlf", "str", "sta",
                  "sca", "scn", "scj", "tld", "tlu", "zrc", "ser"
                }
Definition at line 303 of file PPP.C.

const char* ev_str[] [static]

Initial value:

 {
                  "Up", "Down", "Open", "Close", "TO+", "TO-",
                  "RCR+", "RCR-", "RCA", "RCN", "RTR", "RTA",
                  "RUC", "RXJ+", "RXJ-", "RXR"
                }
Definition at line 291 of file PPP.C.

const struct xcp_type ipcp_types[] [static]

Initial value:

 {
                             { "IP-Address", 3, 1, 6, 6, 0, ipcp_addr_req,
                               ipcp_addr_nak, ipcp_addr_show },
                             { NULL, -1, 0, 0, 0, 0, NULL, NULL, NULL }
                           }
Definition at line 87 of file PPP.C.

const struct xcp_type lcp_types[] [static]

Initial value:

 {
                             { NULL, -1, 0, 0, 0, 0, NULL, NULL, NULL }
                           }
Definition at line 83 of file PPP.C.

const char* ph_str[] [static]

Initial value:

 {
                  "Dead", "Establish", "Authenticate",
                  "Network", "Terminate"
                }
Definition at line 286 of file PPP.C.

const char* st_str[] [static]

Initial value:

 {
                  "Initial", "Starting", "Closed", "Stopped",
                  "Closing", "Stopping", "Req-Sent", "Ack-Rcvd",
                  "Ack-Sent", "Opened", "No-Change"
                }
Definition at line 297 of file PPP.C.

Generated on Wed Jan 25 15:42:43 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/PPP.H File Reference

SRC/PPP.H File Reference

Detailed Description

Definition in file PPP.H.

Go to the source code of this file.

Data Structures

struct | xcp_type
struct | option_state
struct | ppp_xcp
struct | ppp_state

Typedefs

typedef void(* | xcp_func )(struct ppp_state *state, struct ppp_xcp *xcp, const struct xcp_type *tp, const BYTE *buf, int len)
typedef void(* | ppp_func )(struct ppp_state *state, struct ppp_xcp *xcp)

Enumerations

enum ppp_phase {
phDead,
phEstablish,
phAuthenticate,
phNetwork,
phTerminate
}
enum ppp_event {
evUp,
evDown,
evOpen,
evClose,
evTOp,
evTOm,
evRCRp,
evRCRm,
evRCA,
evRCN,
evRTR,
evRTA,
evRUC,
evRXJp,
evRXJm,
evRXR
}
enum xcp_state {
stInitial,
stStarting,
stClosed,
stStopped,
stClosing,
stStopping,
stReqSent,
stAckRcvd,
stAckSent,
stOpened,
stNoChange
}
enum xcp_action {
acNull,
acIrc,
acScr,
acTls,
acTlf,
acStr,
acSta,
acSca,
acScn,
acScj,
acTld,
acTlu,
acZrc,
acSer
}
enum os_state {
osUsable,
osUnusable
}
enum parse_state {
psOK,
psNak,
psRej,
psBad
}

Functions

void | ppp_start (int debug)
void | ppp_input (const BYTE *inbuf, WORD len)
The PPP input handler.

Generated on Wed Jan 25 15:42:43 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/PPPOE.C File Reference

SRC/PPPOE.C File Reference

Detailed Description

PPPoE (PPP-over-Ethernet) for Watt-32. Refer RFC-2516 for spec.

Copyright (c) 1997-2002 Gisle Vanem <giva@bgnett.no>

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. All advertising materials mentioning features or use of this software must display the following acknowledgement: This product includes software developed by Gisle Vanem Bergen, Norway.

THIS SOFTWARE IS PROVIDED BY ME (Gisle Vanem) AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL I OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

Version

0.5 : Aug 07, 2001 : G. Vanem - created 0.6 : Aug 08, 2001 : Added extensions from draft-carrel-info-pppoe-ext-00.txt

Definition in file PPPOE.C.

Go to the source code of this file.

Enumerations

enum States {
StateNone = 0,
StateDiscovery,
StateSession
}

Functions

int | pppoe_send_disc (int code)
Build and send a PADx (PPPoE Active Discovery) packet as link-layer broadcast or unicast.
void | pppoe_config (const char *name, const char *value)
BOOL | pppoe_wait (int wait_code)
Loop waiting for timeout or a PAD response.
BOOL | pppoe_discovery (void)
The PPPoE Discovery handler.
void | pppoe_init (void)
Set config-parser hook and initial values.
int | pppoe_start (void)
Start PPPoE by doing a Discovery.
void | pppoe_exit (void)
Close down PPPoE by sending a PADT.
int | pppoe_handler (const pppoe_Packet *pkt)
Handle incoming PPPoE packets.
BOOL | pppoe_is_up (const void *dest)
Determine if we have a PPPoE session with the machine given by 'dest'.
WORD | build_pad (struct pppoe_Packet *pkt, WORD code)
Build a PADx packet.
int | pppoe_send_sess (const void *sock, const BYTE *buf, WORD len)
Build and send a PPPoE Session packet (IPCP or LCP packet).
void * | pppoe_mac_format (union link_Packet *tx)
Build a PPPoE session packet header.

Variables

void(* | prev_hook )(const char *, const char *)=NULL
BOOL | got_PADO
BOOL | got_PADS
BOOL | got_PADT
BOOL | got_PADM
WORD | session = 0
enum States | state = StateNone
mac_address | ac_macAddr
struct {
int enable
int trace
int timeout
int retries
int lcpEchoInterval
char serviceName [MAX_VALUELEN+1]
char userName [MAX_VALUELEN+1]
char password [MAX_VALUELEN+1]
} cfg

Function Documentation

BOOL pppoe_discovery ( void ) [static]

The PPPoE Discovery handler.

Send PAD Init, wait for PAD offer, send PAD Request and wait for PAD Session confirmation. Definition at line 136 of file PPPOE.C.

References pppoe_send_disc(), and pppoe_wait().

BOOL pppoe_is_up ( const void * dest )

Determine if we have a PPPoE session with the machine given by 'dest'.

Can only have a session with the AC. Definition at line 285 of file PPPOE.C.

References _eth_mac_len.

void* pppoe_mac_format ( union link_Packet * tx )

Build a PPPoE session packet header.

Only called for IPv4 packets. Definition at line 375 of file PPPOE.C.

References _eth_addr, _pkt_ip_ofs, eth_Packet::data, eth_Header::destination, link_Packet::eth, eth_Packet::head, eth_Header::source, eth_Header::type, and WORD.

int pppoe_start ( void )

Start PPPoE by doing a Discovery.

Adjust MSS/MTU for PPPoE packets (8 byte less than normal DIX ethernet). Enter Session state and kick-start PPP (LCP/IPCP).

Todo:
Fix-me: The new MTU/MSS affects all connections (also those which doesn't use PPPoE framing).
Definition at line 183 of file PPPOE.C.

References _pktdevclass, and pppoe_discovery().

BOOL pppoe_wait ( int wait_code ) [static]

Loop waiting for timeout or a PAD response.

Blocks until some got_X flags in by pppoe_handler(). Definition at line 109 of file PPPOE.C.

References chk_timeout(), DWORD, set_timeout(), and tcp_tick().

Variable Documentation

char userName[MAX_VALUELEN+1]

Todo:
PPP user/passwd not handled
Definition at line 82 of file PPPOE.C.

Generated on Wed Jan 25 15:42:43 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/PPPOE.H File Reference

SRC/PPPOE.H File Reference

Detailed Description

Definition in file PPPOE.H.

Go to the source code of this file.

Data Structures

struct | pppoe_Packet

Typedefs

typedef pppoe_Packet | pppoe_Packet

Functions

void | pppoe_init (void)
Set config-parser hook and initial values.
void | pppoe_exit (void)
Close down PPPoE by sending a PADT.
int | pppoe_start (void)
Start PPPoE by doing a Discovery.
int | pppoe_handler (const pppoe_Packet *pkt)
Handle incoming PPPoE packets.
BOOL | pppoe_is_up (const void *dest)
Determine if we have a PPPoE session with the machine given by 'dest'.
int | pppoe_send_sess (const void *sock, const BYTE *buf, WORD len)
Build and send a PPPoE Session packet (IPCP or LCP packet).
void * | pppoe_mac_format (union link_Packet *buf)
Build a PPPoE session packet header.

Function Documentation

BOOL pppoe_is_up ( const void * dest )

Determine if we have a PPPoE session with the machine given by 'dest'.

Can only have a session with the AC. Definition at line 285 of file PPPOE.C.

References _eth_mac_len.

void* pppoe_mac_format ( union link_Packet * tx )

Build a PPPoE session packet header.

Only called for IPv4 packets. Definition at line 375 of file PPPOE.C.

References _eth_addr, _pkt_ip_ofs, eth_Packet::data, eth_Header::destination, link_Packet::eth, eth_Packet::head, eth_Header::source, eth_Header::type, and WORD.

int pppoe_start ( void )

Start PPPoE by doing a Discovery.

Adjust MSS/MTU for PPPoE packets (8 byte less than normal DIX ethernet). Enter Session state and kick-start PPP (LCP/IPCP).

Todo:
Fix-me: The new MTU/MSS affects all connections (also those which doesn't use PPPoE framing).
Definition at line 183 of file PPPOE.C.

References _pktdevclass, and pppoe_discovery().

Generated on Wed Jan 25 15:42:43 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/PRESADDR.C File Reference

SRC/PRESADDR.C File Reference

Detailed Description

Convert network addresses to printable format.

Definition in file PRESADDR.C.

Go to the source code of this file.

Functions

const char * | inet_ntop4 (const u_char *src, char *dst, size_t size)
Format an IPv4 address, more or less like inet_ntoa().
int | inet_pton4 (const char *src, u_char *dst)
Like inet_aton() but without all the hexadecimal and shorthand.
const char * | inet_ntop6 (const u_char *src, char *dst, size_t size)
Convert IPv6 binary address into presentation (printable) format.
int | inet_pton6 (const char *src, u_char *dst)
Convert presentation level address to network order binary form.
const char *W32_CALL | inet_ntop (int af, const void *src, char *dst, size_t size)
Convert a network format address to presentation format.
int W32_CALL | inet_pton (int af, const char *src, void *dst)
Convert from presentation format (which usually means ASCII printable) to network format (which is usually some kind of binary format).
int | main (int argc, char **argv)

Function Documentation

const char* W32_CALL inet_ntop | ( | int | af,
 |  | const void * | src,
 |  | char * | dst,
 |  | size_t | size
 | ) |

Convert a network format address to presentation format.

Return values:
pointer | to presentation format address (`dst'),
NULL | on error (see errno).
Author:
Paul Vixie, 1996.
Definition at line 40 of file PRESADDR.C.

References inet_ntop4(), and inet_ntop6().

const char * inet_ntop4 | ( | const u_char * | src,
 |  | char * | dst,
 |  | size_t | size
 | ) | [static]

Format an IPv4 address, more or less like inet_ntoa().

Return values:
`dst' (as a const)
Note:
  • uses no statics
  • takes a u_char* not an in_addr as input
Author:
Paul Vixie, 1996.
Definition at line 92 of file PRESADDR.C.

const char * inet_ntop6 | ( | const u_char * | src,
 |  | char * | dst,
 |  | size_t | size
 | ) | [static]

Convert IPv6 binary address into presentation (printable) format.

Author:
Paul Vixie, 1996.
Definition at line 110 of file PRESADDR.C.

References inet_ntop4().

int W32_CALL inet_pton | ( | int | af,
 |  | const char * | src,
 |  | void * | dst
 | ) |

Convert from presentation format (which usually means ASCII printable) to network format (which is usually some kind of binary format).

Return values:
1 | the address was valid for the specified address family.
0 | the address wasn't valid (`dst' is untouched in this case).
-1 | some other error occurred (`dst' is untouched in this case, too).
Author:
Paul Vixie, 1996.
Definition at line 66 of file PRESADDR.C.

References inet_pton4(), and inet_pton6().

int inet_pton4 | ( | const char * | src,
 |  | u_char * | dst
 | ) | [static]

Like inet_aton() but without all the hexadecimal and shorthand.

Return values:
1 | if `src' is a valid dotted quad
0 | if `src' is not a valid dotted quad.
Note:
does not touch `dst' unless it's returning 1.
Author:
Paul Vixie, 1996.
Definition at line 222 of file PRESADDR.C.

int inet_pton6 | ( | const char * | src,
 |  | u_char * | dst
 | ) | [static]

Convert presentation level address to network order binary form.

Return values:
1 | if `src' is a valid [RFC1884 2.2] address.
0 | otherwise.
Note:
  • does not touch `dst' unless it's returning 1.
  • `::' in a full address is silently ignored.
Author:
Paul Vixie, 1996.
credit: inspired by Mark Andrews.
Definition at line 280 of file PRESADDR.C.

References inet_pton4().

Generated on Wed Jan 25 15:42:43 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/PRINTK.C File Reference

SRC/PRINTK.C File Reference

Detailed Description

Formatted printf style routines for syslog() etc.

These are safe to use in interrupt handlers Inspired by Linux's printk().

Copyright (c) 1997-2002 Gisle Vanem <giva@bgnett.no>

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. All advertising materials mentioning features or use of this software must display the following acknowledgement: This product includes software developed by Gisle Vanem Bergen, Norway.

THIS SOFTWARE IS PROVIDED BY ME (Gisle Vanem) AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL I OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

Definition in file PRINTK.C.

Go to the source code of this file.

Functions

const char * | str_signal (int sig)
int MS_CDECL | _snprintk (char *buf, int buflen, const char *fmt,...)
int MS_CDECL | _printk (const char *fmt,...)
int | _fputsk (const char *buf, FILE *stream)
void | _printk_flush (void)
void | printk_exit (void)
int | _printk_init (int size, const char *file)
int | _vsnprintk (char *buf, int buflen, const char *fmt, va_list args)

Variables

int | _printk_safe = 1
FILE * | _printk_file = NULL
char * | printk_ptr = NULL
char * | printk_buf = NULL
char * | printk_end = NULL

Variable Documentation

FILE * _printk_file = NULL

what file to print to (or stdout/stderr). Definition at line 58 of file PRINTK.C.

int _printk_safe = 1

safe to print; we're not in a RMCB/ISR. Definition at line 53 of file PRINTK.C.

Generated on Wed Jan 25 15:42:43 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/PRINTK.H File Reference

SRC/PRINTK.H File Reference

Detailed Description

Definition in file PRINTK.H.

Go to the source code of this file.

Functions

int | _printk_init (int size, const char *file)
void | _printk_flush (void)
int | _fputsk (const char *buf, FILE *stream)
int | _vsnprintk (char *buf, int len, const char *fmt, va_list ap)
int MS_CDECL | _printk (const char *fmt,...) ATTR_PRINTF(1
int MS_CDECL | _snprintk (char *buf, int len, const char *fmt,...) ATTR_PRINTF(3

Variables

int | _printk_safe
FILE * | _printk_file

Variable Documentation

FILE* _printk_file

what file to print to (or stdout/stderr). Definition at line 58 of file PRINTK.C.

int _printk_safe

safe to print; we're not in a RMCB/ISR. Definition at line 53 of file PRINTK.C.

Generated on Wed Jan 25 15:42:43 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/QMSG.C File Reference

SRC/QMSG.C File Reference

Detailed Description

Functions for debug messages. Can safely be used inside interrupt handlers or callbacks.

Definition in file QMSG.C.

Go to the source code of this file.

Functions

void | dputch (char x)
void | dmsg (const char *s)
void | dhex1int (int x)
void | dhex2int (int x)
void | dhex4int (int x)
void | dhex8int (DWORD x)

Variables

BYTE | dbg_colour = 14 + (16*1)
WORD | dbg_scrpos = SCR_START
WORD | dbg_scrstart = SCR_START
int | curr_line = (SCR_START/(2*SCR_WIDTH))

Generated on Wed Jan 25 15:42:43 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/RECEIVE.C File Reference

SRC/RECEIVE.C File Reference

Detailed Description

BSD recv(), recvfrom().

Definition in file RECEIVE.C.

Go to the source code of this file.

Functions

int | tcp_receive (Socket *sock, void *buf, int len, int flags, struct sockaddr *from, int *fromlen)
int | udp_receive (Socket *sock, void *buf, int len, int flags, struct sockaddr *from, int *fromlen)
int | raw_receive (Socket *sock, void *buf, unsigned len, int flags, struct sockaddr *from, int *fromlen)
int | receive (const char *func, int s, void *buf, int len, int flags, struct sockaddr *from, int *fromlen)
int W32_CALL | recvfrom (int s, void *buf, int len, int flags, struct sockaddr *from, int *fromlen)
int W32_CALL | recv (int s, void *buf, int len, int flags)
int | read_s (int s, char *buf, int len)
int | recvmsg (int s, struct msghdr *msg, int flags)
int | readv_s (int s, const struct iovec *vector, size_t count)
void | udp_raw_fill_from_ip4 (struct sockaddr *from, int *fromlen, const struct in_addr *peer, WORD port)
void | udp_raw_fill_from_ip6 (struct sockaddr *from, int *fromlen, const void *peer, WORD port)

Function Documentation

int tcp_receive | ( | Socket * | socket,
 |  | void * | buf,
 |  | int | len,
 |  | int | flags,
 |  | struct sockaddr * | from,
 |  | int * | fromlen
 | ) | [static]

Todo:
Handle receiving Out-of-Band data
Definition at line 333 of file RECEIVE.C.

References BYTE, chk_timeout(), DWORD, set_timeout(), sock_fastread(), sock_read(), socket(), sock_type::tcp, tcp_Retransmitter(), and tcp_tick().

int udp_receive | ( | Socket * | socket,
 |  | void * | buf,
 |  | int | len,
 |  | int | flags,
 |  | struct sockaddr * | from,
 |  | int * | fromlen
 | ) | [static]

Todo:
This needs a redesign
Definition at line 475 of file RECEIVE.C.

References set_timeout(), and socket().

Generated on Wed Jan 25 15:42:43 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/REGISTER.H File Reference

SRC/REGISTER.H File Reference

Detailed Description

Definition and constants related to Intel CPU.

COPYRIGHT (c) 1998 valette@crf.canon.fr

The license and distribution terms for this file may be found in the file LICENSE in this distribution or at http://www.OARcorp.com/rtems/license.html.

Id
registers.h,v 1.1 1998/08/05 15:15:46 joel Exp

Definition in file REGISTER.H.

Go to the source code of this file.

Data Structures

struct | eflags_bits
union | eflags
struct | cr0_bits
union | cr0

Generated on Wed Jan 25 15:42:43 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/RES_COMP.C File Reference

SRC/RES_COMP.C File Reference

Detailed Description

Resolver library.

Definition in file RES_COMP.C.

Go to the source code of this file.

Functions

int | mklower (int)
int | dn_find (u_char *, u_char *, u_char **, u_char **)
int | dn_expand (const u_char *msg, const u_char *eom_orig, const u_char *comp_dn, char *exp_dn, int length)
int | dn_comp (const char *exp_dn, u_char *comp_dn, int length, u_char **dnptrs, u_char **lastdnptr)
int | __dn_skipname (const u_char *comp_dn, const u_char *eom)

Generated on Wed Jan 25 15:42:43 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/RES_DATA.C File Reference

SRC/RES_DATA.C File Reference

Detailed Description

Resolver library.

Definition in file RES_DATA.C.

Go to the source code of this file.

Functions

void W32_CALL | herror (const char *prefix)
const char *W32_CALL | hstrerror (int err)

Variables

const char * | _res_opcodes []
const char * | _res_resultcodes []
const char * | h_errlist []
int | h_nerr = DIM (h_errlist)

Variable Documentation

const char* _res_opcodes[]

Initial value:

 {
           "QUERY",
           "IQUERY",
           "CQUERYM",
           "CQUERYU",
           "NOTIFY",
           "5",
           "6",
           "7",
           "8",
           "UPDATEA",
           "UPDATED",
           "UPDATEDA",
           "UPDATEM",
           "UPDATEMA",
           "ZONEINIT",
           "ZONEREF"
         }
Definition at line 63 of file RES_DATA.C.

const char* _res_resultcodes[]

Initial value:

 {
           "NOERROR",
           "FORMERR",
           "SERVFAIL",
           "NXDOMAIN",
           "NOTIMP",
           "REFUSED",
           "6",
           "7",
           "8",
           "9",
           "10",
           "11",
           "12",
           "13",
           "14",
           "NOCHANGE"
         }
Definition at line 82 of file RES_DATA.C.

const char* h_errlist[]

Initial value:

 {
           "Error 0",
           "Unknown host",
           "Host name lookup failure",
           "Unknown server error",
           "No address associated with name",
         }
Definition at line 101 of file RES_DATA.C.

Generated on Wed Jan 25 15:42:43 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/RES_DEBU.C File Reference

SRC/RES_DEBU.C File Reference

Detailed Description

Resolver debugger.

Definition in file RES_DEBU.C.

Go to the source code of this file.

Functions

const char * | dewks (int wks)
const char * | deproto (int protonum)
const u_char * | do_rrset (const u_char *msg, int len, const u_char *cp, int cnt, int pflag, FILE *file, const char *hs)
void | __p_query (const u_char *msg)
void | __fp_resstat (struct __res_state *statp, FILE *file)
void | __fp_nquery (const u_char *msg, int len, FILE *file)
void | __fp_query (const u_char *msg, FILE *file)
const u_char * | __p_cdnname (const u_char *cp, const u_char *msg, int len, FILE *file)
const u_char * | __p_cdname (const u_char *cp, const u_char *msg, FILE *file)
const u_char * | __p_fqname (const u_char *cp, const u_char *msg, FILE *file)
const u_char * | __p_rr (const u_char *cp, const u_char *msg, FILE *file)
const char * | __p_type (int type)
const char * | __p_class (int Class)
const char * | __p_option (u_long option)
char * | __p_time (u_long value)

Generated on Wed Jan 25 15:42:43 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/RES_INIT.C File Reference

SRC/RES_INIT.C File Reference

Detailed Description

Resolver initialisation.

Definition in file RES_INIT.C.

Go to the source code of this file.

Functions

void | res_setoptions (char *options, char *source)
u_int16_t | res_randomid (void)
int | res_init (void)
void | resolver_init (const char *name, const char *value)
void | res_exit (void)
void | res_init0 (void)

Variables

char * | res_cfg_options = NULL
char * | res_cfg_aliases = NULL
__res_state | _res
void(* | prev_hook )(const char *, const char *)
const struct config_table | bind_cfg []

Variable Documentation

const struct config_table bind_cfg[] [static]

Initial value:

 {
          { "RES_OPTIONS", ARG_STRDUP, (void*)&res_cfg_options },
          { "HOSTALIASES", ARG_STRDUP, (void*)&res_cfg_aliases },
          { NULL,          0,          NULL                    }
        }
Definition at line 276 of file RES_INIT.C.

Generated on Wed Jan 25 15:42:43 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/RES_LOC.C File Reference

SRC/RES_LOC.C File Reference

Detailed Description

Resolver library.

Definition in file RES_LOC.C.

Go to the source code of this file.

Functions

const char * | precsize_ntoa (BYTE prec)
BYTE | precsize_aton (char **strptr)
DWORD | latlon2ul (char **latlonstrptr, int *which)
int | loc_aton (const char *ascii, u_char *binary)
char * | loc_ntoa (const u_char *binary, char *ascii)

Variables

unsigned long | poweroften [10]

Variable Documentation

unsigned long poweroften[10] [static]

Initial value:

 {
                     1, 10, 100, 1000, 10000, 100000,
                     1000000,10000000,100000000,1000000000
                   }
Definition at line 71 of file RES_LOC.C.

Generated on Wed Jan 25 15:42:43 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/RES_MKQU.C File Reference

SRC/RES_MKQU.C File Reference

Detailed Description

Resolver.

Definition in file RES_MKQU.C.

Go to the source code of this file.

Functions

int res_mkquery (int op, const char *dname, int Class, int type, const u_char *data, int datalen, const u_char *newrr_in, u_char *buf, int buflen)

Function Documentation

int res_mkquery | ( | int | op,
 |  | const char * | dname,
 |  | int | Class,
 |  | int | type,
 |  | const u_char * | data,
 |  | int | datalen,
 |  | const u_char * | newrr_in,
 |  | u_char * | buf,
 |  | int | buflen
 | ) |

Todo:
Handle STATUS case
Definition at line 67 of file RES_MKQU.C.

Generated on Wed Jan 25 15:42:43 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/RES_QUER.C File Reference

SRC/RES_QUER.C File Reference

Detailed Description

Resolver query function.

Definition in file RES_QUER.C.

Go to the source code of this file.

Functions

int | res_query (const char *name, int Class, int type, u_char *answer, int anslen)
int | res_search (const char *name, int Class, int type, u_char *answer, int anslen)
int | res_querydomain (const char *name, const char *domain, int Class, int type, u_char *answer, int anslen)
char * | __hostalias (const char *name)

Generated on Wed Jan 25 15:42:43 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/RES_SEND.C File Reference

SRC/RES_SEND.C File Reference

Detailed Description

Resolver send module

Definition in file RES_SEND.C.

Go to the source code of this file.

Functions

int | name_server_send (int ns, struct sockaddr_in *nsap)
void | resolve_close (void)
void | Aerror (const char *str, const char *error, struct sockaddr_in address)
void | Perror (const char *str, const char *error)
void | res_send_setqhook (res_send_qhook hook)
void | res_send_setrhook (res_send_rhook hook)
int | res_isourserver (const struct sockaddr_in *inp)
int | res_nameinquery (const char *name, int type, int Class, const u_char *buf, const u_char *eom)
int | res_queriesmatch (const u_char *buf1, const u_char *eom1, const u_char *buf2, const u_char *eom2)
int | res_send (const u_char *buf, int buflen, u_char *ans, int anssiz)
int | tcp_conn (_tcp_Socket *sock, ERROR_TYPE *error, DWORD timeout)
int | tcp_read (_tcp_Socket *sock, u_char *buf, int len, ERROR_TYPE *error, DWORD timeout)
int | udp_read (_udp_Socket *sock, u_char *buf, int len, ERROR_TYPE *error, DWORD timeout)

Variables

sock_type * | sock = NULL
int | vc = 0
int | connected = 0
res_send_qhook | Qhook = NULL
res_send_rhook | Rhook = NULL
HEADER * | hp
HEADER * | anhp
int | gotsomewhere
int | connreset
int | terrno
int | Try
int | v_circuit
int | ns
int | n
int | ns_buflen
int | ns_anssiz
u_long | badns
u_char * | ns_buf
u_char * | ns_ans

Generated on Wed Jan 25 15:42:43 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/RESOLVER.H File Reference

SRC/RESOLVER.H File Reference

Detailed Description

Common include for all res_*.c sources

Definition in file RESOLVER.H.

Go to the source code of this file.

Functions

void | res_init0 (void)

Variables

const char * | _res_opcodes []
const char * | _res_resultcodes []
char * | res_cfg_options
char * | res_cfg_aliases

Generated on Wed Jan 25 15:42:43 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/RS232.C File Reference

SRC/RS232.C File Reference

Detailed Description

Simple serial (RS232) debug-dump, by GvB 2002-09. Debug strings can be dumped to the set-up serial "com" port. I/O port works bady with bcc32. Hence not supported.

Definition in file RS232.C.

Go to the source code of this file.

Functions

int MS_CDECL | __trace2com (const char *fmt,...)
int | trace2com_init (WORD portAddress, DWORD baudRate)

Variables

DWORD | trace2com_speed = 115200UL
int | trace2com_base = 0
int | trace2com_fifoSize_1 = 0
int | trace2com_stdPorts [4] = { 0x3F8, 0x2F8, 0x3E8, 0x2E8 }

Generated on Wed Jan 25 15:42:43 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/RS232.H File Reference

SRC/RS232.H File Reference

Detailed Description

Execution trace via a serial port, GvB 2002-09.

Activated from USER CODE by calling trace2com_init(...) with the port number (either 1-4, or the UARTs hardware address) and the baudrate. Recommend AFAP = 115200. Parameters are always 8,N,1.

Any string then passed to __trace2com(...) is sent out over the COM port. (Even after the CPU has crashed and gone down in flames ;)

Not for BCC32 since it doesn't have native I/O instructions (only via the macros in IOPORT.H)

Definition in file RS232.H.

Go to the source code of this file.

Functions

int | trace2com_init (WORD portAddress, DWORD baudRate)
int MS_CDECL | __trace2com (const char *fmt,...) ATTR_PRINTF(1

Generated on Wed Jan 25 15:42:43 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/SELECT.C File Reference

SRC/SELECT.C File Reference

Detailed Description

BSD select().

Definition in file SELECT.C.

Go to the source code of this file.

Functions

int | read_select (int s, Socket *socket)
int | write_select (int s, Socket *socket)
int | exc_select (int s, Socket *socket)
__inline Socket * | setup_select (int s, BOOL first_loop)
int | select_s (int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout)
The select_s() function.
int W32_CALL | select (int nfds, fd_set *read_fds, fd_set *write_fds, fd_set *except_fds, struct timeval *timeout)
int | pselect (int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timespec *timeout, const sigset_t *sigmask)
__inline int | listen_queued (Socket *socket)
__inline int | sock_signalled (Socket *socket, int mask)
BOOL | handle_ready (int hnd)
void | usage (const char *argv0)
char * | fd_set_str (char *buf, size_t len, const fd_set *fd)
void | select_dump (int sock_err, int num_fd, const struct timeval *tv, const fd_set *fd_read, const fd_set *fd_write, const fd_set *fd_except)
int | main (int argc, char **argv)

Variables

timeval | sel_min_block = { 0, 500000 }
The smallest time for not yielding or calling tcp_tick().

Function Documentation

int exc_select | ( | int | s,
 |  | Socket * | socket
 | ) | [static]

Todo:
Only arrival of OOB-data should count here
Definition at line 624 of file SELECT.C.

References socket().

int select_s | ( | int | nfds,
 |  | fd_set * | readfds,
 |  | fd_set * | writefds,
 |  | fd_set * | exceptfds,
 |  | struct timeval * | timeout
 | ) |

The select_s() function.

Note:
It supports more sockets than would fit in a fd_set. I.e. it handles an array of 'fd_set's on input/output. Thus it is the user's responsibilty to not use a too high 'nfds' value. I.e. If nfs > 512*8 and user fd_set's on input is smaller than 512*, select_s() could trash the fd_set's on output.

Clear our "working" fd_sets.

Note:
Don't use FD_ZERO() since our working fd_sets contain more than FD_SETSIZE sockets.
Definition at line 112 of file SELECT.C.

References _sock_crit_start(), _sock_crit_stop(), DWORD, exc_select(), sel_min_block, socket(), and tcp_tick().

Variable Documentation

struct timeval sel_min_block = { 0, 500000 } [static]

The smallest time for not yielding or calling tcp_tick().

Todo:
Should be configurable.
Definition at line 68 of file SELECT.C.

Generated on Wed Jan 25 15:42:43 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/SETTOD.C File Reference

SRC/SETTOD.C File Reference

Detailed Description

settimeofday() for non-djgpp targets.

The exported prototype used is used is the one specified in the XOpen/POSIX 1.3 standards and the one used on modern (ie 4.4BSD spec) BSDs. ie 'int settimeofday(struct timeval *, ...)', ie the second arg, if specified, is ignored.

Cyrus Patel <cyp@fb14.uni-mainz.de>

May 2001 - Created

Definition in file SETTOD.C.

Go to the source code of this file.

Functions

int MS_CDECL settimeofday (struct timeval *tv,...)

Generated on Wed Jan 25 15:42:43 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/SETTOD.H File Reference

SRC/SETTOD.H File Reference

Detailed Description

settimeofday() for non-djgpp targets.

The exported prototype used is the one specified in the XOpen/POSIX 1.3 standards and the one used on modern (ie 4.4BSD spec) BSDs. ie 'int settimeofday (struct timeval *, ...)', i.e. the second arg, if specified, is ignored.

Definition in file SETTOD.H.

Go to the source code of this file.

Functions

int MS_CDECL settimeofday (struct timeval *tv,...)

Generated on Wed Jan 25 15:42:43 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/SHUTDOWN.C File Reference

SRC/SHUTDOWN.C File Reference

Detailed Description

BSD shutdown().

Definition in file SHUTDOWN.C.

Go to the source code of this file.

Functions

int W32_CALL shutdown (int s, int how)

Function Documentation

int W32_CALL shutdown | ( | int | s,
 |  | int | how
 | ) |

Todo:
For tcp, should send RST if we get incoming data. Don't send ICMP error.

For tcp, should send FIN when all Tx data has been ack'ed. close_s(s) should be same as shutdown(s,SHUT_WR)

Definition at line 46 of file SHUTDOWN.C.

References _socklist_find(), and socket().

Generated on Wed Jan 25 15:42:43 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/SIGNAL.C File Reference

SRC/SIGNAL.C File Reference

Detailed Description

Signal handlers for BSD socket API.

Definition in file SIGNAL.C.

Go to the source code of this file.

Data Structures

struct | signal_table

Functions

void MS_CDECL | sig_catch (int sig)
int | _sock_sig_setup (void)
int | _sock_sig_pending (void)
int | _sock_sig_restore (void)
int | _sock_sig_epipe (void)

Variables

signal_table | sig_tab []
int | signal_depth = 0

Variable Documentation

struct signal_table sig_tab[] [static]

Initial value:

 {
    { NULL, SIGINT,   "SIGINT",  FALSE, TRUE },
#if defined(SIGBREAK)
    { NULL, SIGBREAK, "SIGBREAK",FALSE, TRUE },
#endif
#if defined(SIGQUIT)
    { NULL, SIGQUIT,  "SIGQUIT", FALSE, TRUE },
#endif
#if defined(SIGPIPE)
    { NULL, SIGPIPE,  "SIGPIPE", FALSE, FALSE },
#endif
#if defined(SIGALRM) && 0
    { NULL, SIGALRM,  "SIGALRM", FALSE, FALSE },
#endif
  }
Definition at line 68 of file SIGNAL.C.

Generated on Wed Jan 25 15:42:43 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/SOCK_DBU.C File Reference

SRC/SOCK_DBU.C File Reference

Detailed Description

sock_type debug dump.

Definition in file SOCK_DBU.C.

Go to the source code of this file.

Functions

void sock_debugdump (const sock_type *s)

Generated on Wed Jan 25 15:42:43 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/SOCK_IN.C File Reference

SRC/SOCK_IN.C File Reference

Detailed Description

SOCK_IN: User input functions moved from pctcp.c.

Functions used in these macros: sock_wait_established() sock_wait_input() sock_wait_closed();

Definition in file SOCK_IN.C.

Go to the source code of this file.

Functions

void | ip_timer_init (sock_type *s, unsigned seconds)
int | ip_timer_expired (const sock_type *s)
int | _ip_delay0 (sock_type *s, int timeout_sec, UserHandler fn, int *statusptr)
int | _ip_delay1 (sock_type *s, int timeoutseconds, UserHandler fn, int *statusptr)
int | _ip_delay2 (sock_type *s, int timeoutseconds, UserHandler fn, int *statusptr)
int | sock_timeout (sock_type *s, int sec)
int | sock_established (sock_type *s)

Generated on Wed Jan 25 15:42:43 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/SOCK_INI.C File Reference

SRC/SOCK_INI.C File Reference

Detailed Description

Watt-32 initialisation.

watt_sock_init() - easy way to guarentee:

  • card is ready
  • shutdown is handled
  • ^C/^BREAK are handled
  • WATTCP.CFG config file is read
  • BOOTP/PCDHCP/RARP is run

Version:
0.1: May 2, 1991 Erick - reorganized operations.

0.2: 1998 Gisle V. - Major rewrite; added DHCP, additional startup checks for various targets. Exception handler releases PKTDRVR.

Definition in file SOCK_INI.C.

Go to the source code of this file.

Functions

WattUserConfigFunc | _watt_user_config (WattUserConfigFunc fn)
A user application may call the `_watt_user_config()' function prior to calling sock_init() to inject its own configuration values into the tcp_config() parser.
int | do_exit (int code)
Exit application if _watt_do_exit is TRUE (the default).
void | pre_except_handler (const struct FAULT_STRUC *exc)
void | do_traceback (void)
void | except_handler (int sig)
void | except_handler (excReg *regs)
void | except_handler (int sig, int code)
void | setup_sig_handlers (void)
Install signal-handlers for fatal errors; SIGSEGV, SIGILL, SIGTRAP, SIGFPE etc.
void | restore_sig_handlers (void)
void | tcp_shutdown (void)
Abort all TCP sockets, release DHCP lease and restore signal handlers.
int | tcp_init (void)
Initialise the PKTDRVR (calls _eth_init()).
void | tcp_post_init (void)
Initialise stuff based on configured values.
int | tcp_do_boot (BOOL try_bootp, BOOL try_dhcp, BOOL try_rarp)
Try to boot using BOOTP, DHCP or RARP.
void | check_sock_sizes (size_t tcp_Sock_size, size_t udp_Sock_size)
const char * | sock_init_err (int rc)
int | watt_sock_init (size_t tcp_Sock_size, size_t udp_Sock_size)
int | sock_init (void)
void MS_CDECL | sock_exit (void)
Our only atexit() handler.
void | sock_sig_exit (const char *msg, int sig)
Exit handler for unhandled signals.

Variables

BOOL | _bootp_on = FALSE
Try booting using BOOTP ?
BOOL | _dhcp_on = FALSE
Try booting using DHCP ?
BOOL | _dhcp6_on = FALSE
Try booting using DHCP6 ?
BOOL | _rarp_on = FALSE
Try booting using RARP ?
BOOL | _do_mask_req = FALSE
do an "ICMP Mask Request" when configured
BOOL | _watt_do_exit = TRUE
exit program when all boot attempts failed
BOOL | _watt_no_config = FALSE
run with no config file (embedded/diskless)
WattUserConfigFunc | _watt_user_config_fn = NULL
BOOL | survive_eth = 0
GvB 2002-09, allows us to survive without a (working) packet driver at all - in cases where life still has a meaning without TCP/IP.
BOOL | survive_bootp = TRUE
Survive a failed BOOTP attempt.
BOOL | survive_dhcp = TRUE
Survive a failed DHCP attempt.
BOOL | survive_rarp = FALSE
Don't survive a failed RARP attempt.
BOOL | _watt_is_init = FALSE
watt_sock_init() done (but with possible failed boot)
BOOL | tcp_is_init = FALSE
tcp_init() called okay
int | old_break = -1
Original state of DOS's BREAK handler.
BOOL | use_except = TRUE
Some target dependent functions.
jmp_buf | exc_jmp
FAULT_STRUC | exc_buf
BOOL | sock_init_called = FALSE
The main initialisation routine.

Function Documentation

WattUserConfigFunc _watt_user_config ( WattUserConfigFunc fn )

A user application may call the `_watt_user_config()' function prior to calling sock_init() to inject its own configuration values into the tcp_config() parser.

Useful when running diskless and setting `_watt_no_config = 0'.

Example:

  • 'pass' is 1 for first pass (PKTDRVR/WinPcap configuration), 2 for second pass.
  • 'cfg' is a pointer to the configuration table and must be passed to tcp_inject_config() as-is.

In most cases 'pass' can probably be ignored.

static long my_config_fn (int pass, const struct config_table *cfg) { // Keyword case is not significant (tcp_inject_config will convert // all keys to uppercase)

tcp_inject_config (cfg, "My_IP", "192.168.0.98"); tcp_inject_config (cfg, "NetMask", "255.255.255.0"); tcp_inject_config (cfg, "Gateway", "192.168.0.1"); (void)pass; return (1); // Returning 0 would make tcp_config() return 0 too, // as if the config file was not found }

int main (void) { _watt_no_config = 1; _watt_user_config (my_config_fn); if (sock_init()) return (-1); ... }

Never called inside Watt-32. Definition at line 184 of file SOCK_INI.C.

int do_exit ( int code ) [static]

Exit application if _watt_do_exit is TRUE (the default).

Otherwise return 'code'. Only called during watt_sock_init(). Definition at line 196 of file SOCK_INI.C.

References _watt_do_exit.

void except_handler ( int sig ) [static]

Todo:
Disassemble crash address
Definition at line 251 of file SOCK_INI.C.

References _watt_fatal_error, except_handler(), and rundown_run().

void MS_CDECL sock_exit ( void )

Our only atexit() handler.

Called only once during normal program shutdown. Exception handlers exit differently (see except_handler() above) Definition at line 985 of file SOCK_INI.C.

References _watt_fatal_error, _watt_is_init, rundown_run(), sock_init_called, and tcp_shutdown().

int tcp_do_boot | ( | BOOL | try_bootp,
 |  | BOOL | try_dhcp,
 |  | BOOL | try_rarp
 | ) | [static]

Try to boot using BOOTP, DHCP or RARP.

Only called if at least one '_*on' flag is set.

Return values:
0 on success.
Definition at line 565 of file SOCK_INI.C.

References BOOTP_do_boot(), DHCP_do_boot(), survive_bootp, survive_dhcp, and survive_rarp.

int tcp_init ( void ) [static]

Initialise the PKTDRVR (calls _eth_init()).

  • Reset nameserver table.
  • Initialise local ports.
  • Get machine name (w/o domain) from LAN extension (if any).
  • Prepare parsing TCP configuration.

Note:
May be called more than once without hurting.
Definition at line 481 of file SOCK_INI.C.

References _eth_init(), _get_machine_name(), hostname, init_localport(), and tcp_is_init.

int watt_sock_init | ( | size_t | tcp_Sock_size,
 |  | size_t | udp_Sock_size
 | ) |

Todo:
Use auto-configuration and set 'my_ip_addr' to 169.254/16
Definition at line 697 of file SOCK_INI.C.

References _arp_check_gateways(), _arp_init(), _bootp_on, _dhcp_on, _do_mask_req, _inet_ntoa(), _pkt_inf, _rarp_on, _watt_is_init, _watt_no_config, addwattcpd(), DHCP_init(), DHCP_read_config(), do_exit(), echo_discard_init(), echo_discard_start(), get_day_num(), init_misc(), my_ip_addr, old_break, pppoe_init(), pppoe_start(), reverse_lookup_myip(), set_timeout(), setup_sig_handlers(), sin_mask, sock_exit(), sock_init_called, start_day, start_time, survive_eth, tcp_cbreak(), tcp_do_boot(), tcp_init(), tcp_post_init(), and tftp_init().

Variable Documentation

BOOL sock_init_called = FALSE [static]

The main initialisation routine.

Called only once (during program startup). sock_init() is not a macro in <tcp.h>. Definition at line 695 of file SOCK_INI.C.

BOOL use_except = TRUE [static]

Some target dependent functions.

Install signal handlers. Definition at line 208 of file SOCK_INI.C.

Generated on Wed Jan 25 15:42:43 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/SOCK_INI.H File Reference

SRC/SOCK_INI.H File Reference

Detailed Description

Definition in file SOCK_INI.H.

Go to the source code of this file.

Enumerations

enum eth_init_result {
WERR_NO_ERROR,
WERR_ILL_DOSX,
WERR_NO_MEM,
WERR_NO_DRIVER,
WERR_PKT_ERROR,
WERR_BOOTP_FAIL,
WERR_DHCP_FAIL,
WERR_RARP_FAIL,
WERR_NO_IPADDR,
WERR_PPPOE_DISC
}

Functions

W32_FUNC int | watt_sock_init (size_t tcp_sz, size_t udp_sz)
W32_FUNC void MS_CDECL | sock_exit (void)
Our only atexit() handler.
W32_FUNC const char * | sock_init_err (int rc)
W32_FUNC void | sock_sig_exit (const char *msg, int sig) ATTR_NORETURN()
Exit handler for unhandled signals.

Variables

W32_DATA int | _bootp_on
W32_DATA int | _dhcp_on
W32_DATA int | _dhcp6_on
W32_DATA int | _rarp_on
W32_DATA BOOL | _do_mask_req
W32_DATA BOOL | _watt_do_exit
W32_DATA BOOL | _watt_is_init
W32_DATA BOOL | _watt_no_config
W32_DATA BOOL | survive_eth
W32_DATA BOOL | survive_bootp
W32_DATA BOOL | survive_dhcp
W32_DATA BOOL | survive_rarp

Function Documentation

W32_FUNC void MS_CDECL sock_exit ( void )

Our only atexit() handler.

Called only once during normal program shutdown. Exception handlers exit differently (see except_handler() above) Definition at line 985 of file SOCK_INI.C.

W32_FUNC int watt_sock_init | ( | size_t | tcp_Sock_size,
 |  | size_t | udp_Sock_size
 | ) |

Todo:
Use auto-configuration and set 'my_ip_addr' to 169.254/16
Definition at line 697 of file SOCK_INI.C.

Generated on Wed Jan 25 15:42:43 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/SOCK_IO.C File Reference

SRC/SOCK_IO.C File Reference

Detailed Description

some sock_xx() functions moved from pctcp.c due to memory contraints under Turbo-C

Definition in file SOCK_IO.C.

Go to the source code of this file.

Functions

BYTE | sock_putc (sock_type *s, BYTE c)
int | sock_puts (sock_type *s, const BYTE *data)
int | sock_gets (sock_type *s, BYTE *data, int bmax)
int | sock_getc (sock_type *s)
WORD | sock_dataready (sock_type *s)
sock_dataready - returns number of bytes waiting to be read.
int | sock_putcw (sock_type *s, wchar_t ch)
int | sock_putsw (sock_type *s, const wchar_t *data)
int | sock_getsw (sock_type *s, wchar_t *data, int n)
wchar_t | sock_getcw (sock_type *s)

Function Documentation

WORD sock_dataready ( sock_type * s )

sock_dataready - returns number of bytes waiting to be read.

  • if in ASCII mode, return >0 if a terminated line is present or the buffer is full or state is LASTACK (tcp only).
  • if in binary mode (default), simply return number of bytes in receive buffer.
  • For UDP or TCP sockets only.
Definition at line 246 of file SOCK_IO.C.

References _raw_Socket::ip_type, sock_type::raw, sock_dataready(), _tcp_Socket::state, sock_type::tcp, UINT, and WORD.

wchar_t sock_getcw ( sock_type * s )

Todo:
Wide character version of sock_getc()
Definition at line 322 of file SOCK_IO.C.

int sock_getsw | ( | sock_type * | s,
 |  | wchar_t * | data,
 |  | int | n
 | ) |

Todo:
Wide character version of sock_gets()
Definition at line 315 of file SOCK_IO.C.

int sock_putcw | ( | sock_type * | s,
 |  | wchar_t | ch
 | ) |

Todo:
Wide character versions of above functions.
Definition at line 301 of file SOCK_IO.C.

int sock_puts | ( | sock_type * | s,
 |  | const BYTE * | data
 | ) |

<

Todo:
suppport UDP frags
Definition at line 39 of file SOCK_IO.C.

References BYTE, _raw_Socket::ip_type, sock_type::raw, sock_flushnext(), sock_puts(), sock_write(), and sock_type::tcp.

int sock_putsw | ( | sock_type * | s,
 |  | const wchar_t * | data
 | ) |

Todo:
Wide character version of sock_puts()
Definition at line 308 of file SOCK_IO.C.

Generated on Wed Jan 25 15:42:43 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/SOCK_PRN.C File Reference

SRC/SOCK_PRN.C File Reference

Detailed Description

sock_type printing to network

Definition in file SOCK_PRN.C.

Go to the source code of this file.

Functions

int MS_CDECL sock_printf (sock_type *s, const char *fmt,...)

Generated on Wed Jan 25 15:42:43 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/SOCK_SCN.C File Reference

SRC/SOCK_SCN.C File Reference

Detailed Description

scanf-like function for sock_type.

Definition in file SOCK_SCN.C.

Go to the source code of this file.

Functions

int | vsscanf (const char *buf, const char *fmt, va_list arglist)
int MS_CDECL | sock_scanf (sock_type *s, const char *fmt,...)

Generated on Wed Jan 25 15:42:43 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/SOCK_SEL.C File Reference

SRC/SOCK_SEL.C File Reference

Detailed Description

sock_select(), tcp_simple_state()

Definition in file SOCK_SEL.C.

Go to the source code of this file.

Functions

int | sock_sselect (const sock_type *s, int waitstate)
enum TCP_SIMPLE_STATE | tcp_simple_state (const _tcp_Socket *s)

Generated on Wed Jan 25 15:42:43 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/SOCKET.C File Reference

SRC/SOCKET.C File Reference

Detailed Description

BSD socket().

Definition in file SOCKET.C.

Go to the source code of this file.

Functions

int | _fsext_demux (__FSEXT_Fnumber func, int *rv, va_list _args)
__inline Socket * | sock_hash_get (int fd)
__inline void | sock_hash_add (int fd, Socket *sock)
void * | _sock_calloc (size_t size, const char *file, unsigned line)
Memory allocation; print some info if allocation fails.
int | sock_alloc_fd (char **err)
BOOL | _sock_dos_fd (int s)
_sock_dos_fd - Return TRUE if `s' is a valid DOS/Win32 handle.
int | _sock_set_rcv_buf (sock_type *s, size_t len)
Setup a bigger receive buffer, the default in Wattcp is only 2k.
void | _sock_free_rcv_buf (sock_type *s)
Free receive buffer associated with udp/tcp sockets.
__inline Socket * | sk_list_del (int s)
Deletes the list element associated with a socket.
const sock_type * | __get_sock_from_s (int s, int proto)
Hack function if user app needs to use Wattcp core functions for BSD sockets.
__inline BOOL | other_tcp_listeners (const Socket *_this)
Traverse socket-list to find other SOCK_STREAM sockets besides '_this' which are also listening.
void | _sock_set_syn_hook (int(*func)(_tcp_Socket **))
__inline BOOL | other_raw_socks (const Socket *_this)
Traverse socket-list to find other SOCK_RAW sockets besides '_this'.
BOOL | _sock_set_normal_rx_mode (const Socket *_this)
BOOL | _sock_set_mcast_rx_mode (void)
BOOL | _sock_set_promisc_rx_mode (void)
void | sock_raw_del (Socket *sock)
Free buffers and hooks used by a SOCK_RAW socket.
BOOL | sock_packet_add (Socket *sock)
Allocate ringbuffer and rx-buffers for a SOCK_PACKET socket.
void | sock_packet_del (Socket *sock)
int | sock_packet_peek (const union link_Packet *pkt)
char | get_pkt_type_eth (const eth_Header *eth)
Return correct PACKET_xx type.
char | get_pkt_type_fddi (const fddi_Header *fddi)
char | get_pkt_type_tok (const tok_Header *tok)
char | get_pkt_type_arc (const arcnet_Header *arc)
char | get_pkt_type (const union link_Packet *pkt)
unsigned | sock_packet_receive (Socket *sock, void *buf, unsigned len, struct sockaddr *from, int *fromlen)
Called from receive.c for AF_PACKET sockets.
unsigned | sock_packet_rbused (Socket *sock)
unsigned | sock_packet_transmit (Socket *socket, const void *buf, unsigned len, const struct sockaddr *to, int tolen)
void | sock_close_fd (int fd)
Socket * | _sock_del_fd (int fd, const char *file, unsigned line)
Delete the socket from `inuse' array and all memory associated with it.
int | sock_find_fd (const Socket *socket)
Finds the 'fd' associated with pointer 'socket'.
Socket * | sock_find_udp (const _udp_Socket *udp)
Finds the 'Socket' associated with udp-socket 'udp'.
void * | sock_find_tcp (const _tcp_Socket *tcp)
Finds the 'Socket*' associated with tcp-socket '*tcp'.
int | _sock_chk_sockaddr (Socket *socket, const struct sockaddr *sa, int len)
Check `sockaddr*' passed to bind/connect.
_raw_Socket * | find_free_raw_sock (Socket *sock)
Search in sock->raw?_sock list for an unused raw-buffer.
_raw6_Socket * | find_free_raw6_sock (Socket *sock)
int | sock_raw4_recv (const in_Header *ip)
Called from _ip4_handler() via `_bsd_socket_hook'.
int | sock_raw6_recv (const in6_Header *ip)
void | do_keepalive (Socket *sock)
Handle keepalive on STREAM socket.
void *MS_CDECL | socket_op_demux (enum BSD_SOCKET_OPS op,...)
The demultiplexer for callback operations called via '_bsd_socket_hook' from functions in the core Wattcp API.
Socket * | tcp_sock_daemon (Socket *sock)
Called by sock_daemon() to handle SOCK_STREAM sockets.
Socket * | udp_sock_daemon (Socket *sock)
Called by sock_daemon() for SOCK_DGRAM sockets.
void | sock_daemon (void)
A daemon called from tcp_tick().
void | _sock_crit_start (void)
Start a critical region.
void | _sock_crit_stop (void)
Mark the end of a critical region.
void | sock_fortify_exit (void)
Exit handler for Fortify.
const char * | vendor_version (void)
Return version string of current compiler.
void | check_errno_version (void)
Check that ./util/xx_err.exe is built with same version we're using here.
BOOL | init_sockets (void)
Main initialisation routine for the BSD socket API.
Socket * | _socklist_find (int s)
Returns a pointer to the Socket structure assoiated with socket 's'.
BOOL | sock_raw_add (Socket *sock, int family)
Allocate raw?_Socket buffers for a SOCK_RAW socket.
Socket * | socklist_add (int s, int type, int proto, int family)
Adds a new socket to the sk_list.
int | set_proto (int type, BOOL is_ip6, int *proto)
Select (and check) a suitable protocol for socket-type.
int W32_CALL | socket (int family, int type, int protocol)
socket().
int | stream_cancel (const _tcp_Socket *tcp, BYTE icmp_type, int error)
Callback handlers for "ICMP Port/Host/Network Unreachable" or "ICMP Parameter Problem" issued by lower layer (udp_cancel() and tcp_cancel() in pctcp.c).
int | dgram_cancel (const _udp_Socket *udp, BYTE icmp_type, int error)
__inline const char * | ip_proto_str (WORD prot)
int | icmp_callback (sock_type *s, BYTE icmp_type, BYTE icmp_code)
int | _UDP_open (Socket *socket, struct in_addr host, WORD loc_port, WORD rem_port)
Open and listen routines for SOCK_DGRAM at the socket-level.
int | _UDP_listen (Socket *socket, struct in_addr host, WORD port)
int | _TCP_open (Socket *socket, struct in_addr host, WORD loc_port, WORD rem_port)
Open and listen routines for SOCK_STREAM at the socket-level.
int | _TCP_listen (Socket *socket, struct in_addr host, WORD port)
int | _TCP6_open (Socket *socket, const void *dst, WORD loc_port, WORD rem_port)
int | _TCP6_listen (Socket *socket, const void *host, WORD loc_port)
int | _UDP6_open (Socket *socket, const void *host, WORD loc_port, WORD rem_port)
int | _UDP6_listen (Socket *socket, const void *host, WORD port)
int | _sock_half_open (const _tcp_Socket *s)
_sock_half_open - Return true if peer closed his side.
int W32_CALL | socketpair (int family, int type, int protocol, int usockvec[2])
socketpair() - Create a pair of connected sockets.

Variables

int | sk_block = 0
int | sk_last = SK_FIRST+1
Socket * | sk_list = NULL
DWORD | raw_seq = 0
int(* | tcp_syn_hook )(_tcp_Socket **tcp)=NULL
int(* | ip4_raw_hook )(const in_Header *ip)=NULL
int(* | ip6_raw_hook )(const in6_Header *ip)=NULL
Socket * | sk_hashes [SOCK_HASH_SIZE]
fd_set | inuse [NUM_SOCK_FDSETS]
`inuse[]' has a non-zero bit for each socket-descriptor in use.
BOOL | mcast_set = FALSE
Switch back to normal rx-mode (RXMODE_BROADCAST) if no multicasts active and no more IPv6/SOCK_PACKET sockets besides '_this'.
BOOL | promis_set = FALSE

Function Documentation

const sock_type* __get_sock_from_s | ( | int | s,
 |  | int | proto
 | ) |

Hack function if user app needs to use Wattcp core functions for BSD sockets.

Must *not* modify return value in any way. Definition at line 293 of file SOCKET.C.

References _socklist_find().

void _sock_crit_start ( void )

Start a critical region.

Prevent `sk_list' being destroyed (e.g. in sock_daemon) and thus confusing select_s(), connect() etc. Definition at line 1276 of file SOCKET.C.

void _sock_crit_stop ( void )

Mark the end of a critical region.

If blocking-level reached zero, we run our socket-daemon.

Todo:
handle SIGALRM raised in a critical-section
Definition at line 1286 of file SOCKET.C.

References sock_daemon().

Socket* _sock_del_fd | ( | int | fd,
 |  | const char * | file,
 |  | unsigned | line
 | ) |

Delete the socket from `inuse' array and all memory associated with it.

Also unlink it from the socket list (sk_list). Clear _tcp_syn_hook is no more SOCK_STREAM listeners. Return pointer to next node in list or NULL if none/error. Definition at line 680 of file SOCKET.C.

References _bsd_socket_hook(), _pkt_rxmode, _sock_free_rcv_buf(), _socklist_find(), inuse, other_tcp_listeners(), RXMODE_BROADCAST, sk_list_del(), sock_abort(), sock_raw_del(), sock_type::tcp, and sock_type::udp.

BOOL _sock_dos_fd ( int s )

_sock_dos_fd - Return TRUE if `s' is a valid DOS/Win32 handle.

Used to differentiate EBADF from ENOTSOCK.

Note: for non-djgpp targets `s' may have same value as a DOS-handle. This function should only be used when `s' isn't found in `sk_list'. Definition at line 213 of file SOCKET.C.

int _sock_half_open ( const _tcp_Socket * s )

_sock_half_open - Return true if peer closed his side.

There might still be data to read Definition at line 2164 of file SOCKET.C.

References _tcp_Socket::state.

int _sock_set_rcv_buf | ( | sock_type * | s,
 |  | size_t | len
 | ) |

Setup a bigger receive buffer, the default in Wattcp is only 2k.

Note:
If calloc() fails, sock_setbuf() reverts to default 2kB socket buffer.

Todo:
allow user to define size using SO_RCVBUF/SO_SNDBUF before calling connect().
Definition at line 243 of file SOCKET.C.

References BYTE.

Socket* _socklist_find ( int s )

Returns a pointer to the Socket structure assoiated with socket 's'.

If socket `s' was not found, NULL is returned. Definition at line 1497 of file SOCKET.C.

References init_sockets().

int _TCP6_listen | ( | Socket * | socket,
 |  | const void * | host,
 |  | WORD | loc_port
 | ) |

Todo:
Support TCP listen() for AF_INET6
Definition at line 2127 of file SOCKET.C.

References socket(), and WORD.

int _TCP6_open | ( | Socket * | socket,
 |  | const void * | dst,
 |  | WORD | loc_port,
 |  | WORD | rem_port
 | ) |

Todo:
use mss from setsockopt()

Yield for IPv6 sockets

use TCP_NODELAY set in setsockopt()

< Definition at line 2035 of file SOCKET.C.

References _default_ttl, _eth_is_init, _inet6_ntoa(), _sock_set_rcv_buf(), _tcp_allsocs, _tcp_unthread(), icmp_upcall, my_ip_addr, set_timeout(), socket(), tcp_nagle, tcp_OPEN_TO, tcp_recv_win, UINT, and WORD.

int _TCP_open | ( | Socket * | socket,
 |  | struct in_addr | host,
 |  | WORD | loc_port,
 |  | WORD | rem_port
 | ) |

Open and listen routines for SOCK_STREAM at the socket-level.

The parameters to tcp_open() is a bit tricky, but the internal Wattcp socket 's' contains the following elements that must match in the first 'for-loop' of _tcp_handler().

s->hisport != 0 i.e. active (non-listening) port s->myaddr == ip->destination, our IP-address s->hisaddr == ip->source, above 'dest' address s->myport == tcp->dstPort, above 'loc_port' s->hisport == tcp->srcPort, above 'rem_port' Definition at line 1992 of file SOCKET.C.

References _sock_set_rcv_buf(), DWORD, icmp_upcall, socket(), tcp_open(), tcp_recv_win, and WORD.

int _UDP6_listen | ( | Socket * | socket,
 |  | const void * | host,
 |  | WORD | port
 | ) |

Todo:
Support UDP listen() for AF_INET6
Definition at line 2147 of file SOCKET.C.

References socket(), and WORD.

int _UDP6_open | ( | Socket * | socket,
 |  | const void * | host,
 |  | WORD | loc_port,
 |  | WORD | rem_port
 | ) |

Todo:
Support UDP connect() for AF_INET6
Definition at line 2136 of file SOCKET.C.

References _sock_set_rcv_buf(), icmp_upcall, socket(), and WORD.

void check_errno_version ( void ) [static]

Check that ./util/xx_err.exe is built with same version we're using here.

Print a warning of there's a mis-match. Definition at line 1417 of file SOCKET.C.

References vendor_version().

void do_keepalive ( Socket * sock ) [static]

Handle keepalive on STREAM socket.

Not complete; doesn't consider tcp_max_idle. Definition at line 1042 of file SOCKET.C.

References _tcp_keepalive(), chk_timeout(), set_timeout(), and tcp_keep_idle.

BOOL init_sockets ( void ) [static]

Main initialisation routine for the BSD socket API.

Called only once to do:

  • Calls watt_sock_init() w/o exiting if it fails.
  • Checks the generated errno list.
  • Set the limit on max number of sockets.
  • Add our sock_daemon().
  • Initialise Fortify malloc debugger.
Definition at line 1446 of file SOCKET.C.

References _watt_do_exit, addwattcpd(), check_errno_version(), inuse, sock_daemon(), sock_fortify_exit(), and watt_sock_init().

__inline BOOL other_raw_socks ( const Socket * _this ) [static]

Traverse socket-list to find other SOCK_RAW sockets besides '_this'.

Unhook '_raw_ip?_hook' if none found. Definition at line 337 of file SOCKET.C.

int set_proto | ( | int | type,
 |  | BOOL | is_ip6,
 |  | int * | proto
 | ) | [static]

Select (and check) a suitable protocol for socket-type.

<

Todo:
IPPROTO_XTP
Definition at line 1648 of file SOCKET.C.

References _pkt_errno, pkt_strerror(), and sock_raw4_recv().

__inline Socket* sk_list_del ( int s ) [static]

Deletes the list element associated with a socket.

Return pointer to next node. Return NULL if no next or socket not found. Definition at line 269 of file SOCKET.C.

void sock_daemon ( void ) [static]

A daemon called from tcp_tick().

Called every DAEMON_PERIOD (500 msec) to perform cleanup of bound SOCK_STREAM and SOCK_DGRAM sockets still in use. Definition at line 1236 of file SOCKET.C.

References inuse, tcp_sock_daemon(), and udp_sock_daemon().

int sock_find_fd ( const Socket * socket ) [static]

Finds the 'fd' associated with pointer 'socket'.

Return -1 if not found. Definition at line 777 of file SOCKET.C.

References socket().

Socket* sock_find_udp ( const _udp_Socket * udp ) [static]

Finds the 'Socket' associated with udp-socket 'udp'.

Return NULL if not found. Definition at line 791 of file SOCKET.C.

void sock_fortify_exit ( void ) [static]

Exit handler for Fortify.

Traverse all sockets and print some state and memory statistics. Definition at line 1306 of file SOCKET.C.

References DWORD, and inuse.

unsigned sock_packet_receive | ( | Socket * | sock,
 |  | void * | buf,
 |  | unsigned | len,
 |  | struct sockaddr * | from,
 |  | int * | fromlen
 | ) |

Called from receive.c for AF_PACKET sockets.

Todo:
This should loop until some packet is received.
Definition at line 580 of file SOCKET.C.

References _eth_get_hwtype(), _pkt_ip_ofs, BYTE, and WORD.

int sock_raw4_recv ( const in_Header * ip ) [static]

Called from _ip4_handler() via `_bsd_socket_hook'.

IP-header is already checked in `_ip4_handler()'. Finds all 'Socket' associated with raw IP-packet 'ip'. Enqueue to 'sock->raw_sock'. Return >=1 if 'ip' is consumed, 0 otherwise.

Todo:
Handle receiving bad IP-packets for SOCK_RAW sockets.
Definition at line 904 of file SOCKET.C.

References in_Header::destination, DWORD, find_free_raw_sock(), in_Header::identification, _raw_Socket::ip, in_Header::length, in_Header::proto, _raw_Socket::rx_data, _raw_Socket::seq_num, and _raw_Socket::used.

int W32_CALL socket | ( | int | family,
 |  | int | type,
 |  | int | protocol
 | ) |

socket().

  • family The protocol family. Supports the AF_INET, AF_INET6, AF_PACKET families.
  • type SOCK_STREAM (tcp), SOCK_DGRAM (udp), SOCK_RAW (ip) or SOCK_PACKET (link).
  • protocol IPPROTO_TCP, IPPROTO_UDP or 0/IPPROTO_IP.
Return values:
The socket ID number
Definition at line 1719 of file SOCKET.C.

References _bsd_socket_hook(), init_sockets(), set_proto(), socket_op_demux(), and socklist_add().

int W32_CALL socketpair | ( | int | family,
 |  | int | type,
 |  | int | protocol,
 |  | int | usockvec[2]
 | ) |

socketpair() - Create a pair of connected sockets.

Modified version based on Linux's version. Definition at line 2179 of file SOCKET.C.

References socket().

int stream_cancel | ( | const _tcp_Socket * | tcp,
 |  | BYTE | icmp_type,
 |  | int | error
 | ) | [static]

Callback handlers for "ICMP Port/Host/Network Unreachable" or "ICMP Parameter Problem" issued by lower layer (udp_cancel() and tcp_cancel() in pctcp.c).

Note:
a single ICMP message may apply to several UDP sockets.
We should drop (i.e. set ECONNREFUSED in lack of a better errno) on receiving "ICMP-param problem" or "ICMP-unreachable" reached stress-level. Definition at line 1837 of file SOCKET.C.

References BYTE, and socket().

Socket* tcp_sock_daemon ( Socket * sock ) [static]

Called by sock_daemon() to handle SOCK_STREAM sockets.

Unlink the socket from the linked list if application has read all data and tcp_state has become CLOSED and the linger period has expired. Definition at line 1148 of file SOCKET.C.

References _sock_free_rcv_buf(), do_keepalive(), sock_fastread(), and sock_type::tcp.

Socket* udp_sock_daemon ( Socket * sock ) [static]

Called by sock_daemon() for SOCK_DGRAM sockets.

Unlink the socket from the linked list if application has read all data and "state" is disconnecting.

Note:
Setting 'SS_ISDISCONNECTING' is really a mis-nomer, but should indicate socket is closed/aborted with Rx-data remaining.
Definition at line 1216 of file SOCKET.C.

Variable Documentation

fd_set inuse[NUM_SOCK_FDSETS] [static]

`inuse[]' has a non-zero bit for each socket-descriptor in use.

There can be max `MAX_SOCKETS' allocated at any time. Dead stream sockets will be unlinked by `sock_daemon()' in due time.

Non-djgpp targets: Allocate a new descriptor (handle) by searching through `inuse' for the first zero bit. Update `sk_last' as needed.

djgpp target: Allocate a descriptior from the "File System Extension" layer. `sk_last' is not used (initialised to MAX_SOCKETS). Thus max # of sockets are limited by max # of DOS handles that can be created. Definition at line 143 of file SOCKET.C.

Generated on Wed Jan 25 15:42:43 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/SOCKET.H File Reference

SRC/SOCKET.H File Reference

Detailed Description

Definition in file SOCKET.H.

Go to the source code of this file.

Data Structures

struct | sock_packet_buf
struct | sock_packet_pool
struct | Socket

Typedefs

typedef sock_packet_pool | sock_packet_pool
typedef Socket | Socket

Functions

W32_FUNC int | close_s (int s)
W32_FUNC int | write_s (int s, const char *buf, int num)
W32_FUNC int | writev_s (int s, const struct iovec *vec, size_t num)
W32_FUNC int | recvmsg (int s, struct msghdr *msg, int flags)
W32_FUNC int | read_s (int s, char *buf, int num)
W32_FUNC int | select_s (int n, fd_set *r, fd_set *w, fd_set *x, struct timeval *t)
The select_s() function.
W32_FUNC int W32_CALL | select (int num_sockets, fd_set *read_events, fd_set *write_events, fd_set *except_events, struct timeval *timeout)
int | _sock_sig_setup (void)
int | _sock_sig_restore (void)
int | _sock_sig_pending (void)
int | _sock_sig_epipe (void)
void | _sock_crit_start (void)
Start a critical region.
void | _sock_crit_stop (void)
Mark the end of a critical region.
void | _sock_start_timer (void)
void | _sock_stop_timer (void)
unsigned | sock_packet_transmit (Socket *sock, const void *buf, unsigned len, const struct sockaddr *to, int tolen)
unsigned | sock_packet_receive (Socket *sock, void *buf, unsigned len, struct sockaddr *from, int *fromlen)
Called from receive.c for AF_PACKET sockets.
unsigned | sock_packet_rbused (Socket *sock)
void * | _sock_calloc (size_t size, const char *file, unsigned line)
Memory allocation; print some info if allocation fails.
Socket * | _sock_del_fd (int sock, const char *file, unsigned line)
Delete the socket from `inuse' array and all memory associated with it.
Socket * | _socklist_find (int s)
Returns a pointer to the Socket structure assoiated with socket 's'.
BOOL | _sock_dos_fd (int s)
_sock_dos_fd - Return TRUE if `s' is a valid DOS/Win32 handle.
int | _sock_half_open (const _tcp_Socket *tcp)
_sock_half_open - Return true if peer closed his side.
int | _sock_append (_tcp_Socket **tcp)
Called from tcp_fsm.c / tcp_listen_state() (via _bsd_socket_hook) to append a new connection to the listen-queue of socket 'sock'.
int | _sock_set_rcv_buf (sock_type *s, size_t len)
Setup a bigger receive buffer, the default in Wattcp is only 2k.
void | _sock_free_rcv_buf (sock_type *s)
Free receive buffer associated with udp/tcp sockets.
void | _sock_set_syn_hook (int(*func)(_tcp_Socket **))
BOOL | _sock_set_promisc_rx_mode (void)
BOOL | _sock_set_mcast_rx_mode (void)
BOOL | _sock_set_normal_rx_mode (const Socket *_this)
const sock_type * | __get_sock_from_s (int s, int proto)
Hack function if user app needs to use Wattcp core functions for BSD sockets.
void | __get_ifname (char *if_name)
void | __set_ifname (const char *if_name)
int | __scope_ascii_to_id (const char *str)
int | __scope_id_to_ascii (int scope)
int | _sock_chk_sockaddr (Socket *socket, const struct sockaddr *sa, int len)
Check `sockaddr*' passed to bind/connect.
int | _TCP_open (Socket *socket, struct in_addr host, WORD loc_port, WORD rem_port)
Open and listen routines for SOCK_STREAM at the socket-level.
int | _UDP_open (Socket *socket, struct in_addr host, WORD loc_port, WORD rem_port)
Open and listen routines for SOCK_DGRAM at the socket-level.
int | _TCP_listen (Socket *socket, struct in_addr host, WORD loc_port)
int | _UDP_listen (Socket *socket, struct in_addr host, WORD port)
int | _TCP6_open (Socket *socket, const void *host, WORD loc_port, WORD rem_port)
int | _UDP6_open (Socket *socket, const void *host, WORD loc_port, WORD rem_port)
int | _TCP6_listen (Socket *socket, const void *host, WORD loc_port)
int | _UDP6_listen (Socket *socket, const void *host, WORD port)

Function Documentation

const sock_type* __get_sock_from_s | ( | int | s,
 |  | int | proto
 | ) |

Hack function if user app needs to use Wattcp core functions for BSD sockets.

Must *not* modify return value in any way. Definition at line 293 of file SOCKET.C.

int _sock_append ( _tcp_Socket ** tcp )

Called from tcp_fsm.c / tcp_listen_state() (via _bsd_socket_hook) to append a new connection to the listen-queue of socket 'sock'.

TCB on input ('orig') has received a SYN. Replace TCB on output with a cloned TCB that we append to the listen-queue and eventually is used by accept() to create a new socket.

TCB on input ('orig') must still be listening for further connections on the same port as specified in call to _TCP_listen().

Todo:
Implement SYN-cookies. http://cr.yp.to/syncookies.html

Todo:
Implement SYN-cookies and drop the segment if no match

drop the oldest (or a random) slot in the listen-queue.

Definition at line 416 of file ACCEPT.C.

References _bsd_socket_hook(), _sock_set_rcv_buf(), _tcp_allsocs, _tcp_Socket::last_acknum, _tcp_Socket::last_seqnum, _tcp_Socket::my6addr, _tcp_Socket::send_next, set_timeout(), tcp_recv_win, and _tcp_Socket::unhappy.

void _sock_crit_start ( void )

Start a critical region.

Prevent `sk_list' being destroyed (e.g. in sock_daemon) and thus confusing select_s(), connect() etc. Definition at line 1276 of file SOCKET.C.

void _sock_crit_stop ( void )

Mark the end of a critical region.

If blocking-level reached zero, we run our socket-daemon.

Todo:
handle SIGALRM raised in a critical-section
Definition at line 1286 of file SOCKET.C.

References sock_daemon().

Socket* _sock_del_fd | ( | int | fd,
 |  | const char * | file,
 |  | unsigned | line
 | ) |

Delete the socket from `inuse' array and all memory associated with it.

Also unlink it from the socket list (sk_list). Clear _tcp_syn_hook is no more SOCK_STREAM listeners. Return pointer to next node in list or NULL if none/error. Definition at line 680 of file SOCKET.C.

References _bsd_socket_hook(), _pkt_rxmode, _sock_free_rcv_buf(), _socklist_find(), inuse, other_tcp_listeners(), RXMODE_BROADCAST, sk_list_del(), sock_abort(), sock_raw_del(), sock_type::tcp, and sock_type::udp.

BOOL _sock_dos_fd ( int s )

_sock_dos_fd - Return TRUE if `s' is a valid DOS/Win32 handle.

Used to differentiate EBADF from ENOTSOCK.

Note: for non-djgpp targets `s' may have same value as a DOS-handle. This function should only be used when `s' isn't found in `sk_list'. Definition at line 213 of file SOCKET.C.

int _sock_half_open ( const _tcp_Socket * s )

_sock_half_open - Return true if peer closed his side.

There might still be data to read Definition at line 2164 of file SOCKET.C.

References _tcp_Socket::state.

int _sock_set_rcv_buf | ( | sock_type * | s,
 |  | size_t | len
 | ) |

Setup a bigger receive buffer, the default in Wattcp is only 2k.

Note:
If calloc() fails, sock_setbuf() reverts to default 2kB socket buffer.

Todo:
allow user to define size using SO_RCVBUF/SO_SNDBUF before calling connect().
Definition at line 243 of file SOCKET.C.

References BYTE.

Socket* _socklist_find ( int s )

Returns a pointer to the Socket structure assoiated with socket 's'.

If socket `s' was not found, NULL is returned. Definition at line 1497 of file SOCKET.C.

References init_sockets().

int _TCP6_listen | ( | Socket * | socket,
 |  | const void * | host,
 |  | WORD | loc_port
 | ) |

Todo:
Support TCP listen() for AF_INET6
Definition at line 2127 of file SOCKET.C.

References socket(), and WORD.

int _TCP6_open | ( | Socket * | socket,
 |  | const void * | dst,
 |  | WORD | loc_port,
 |  | WORD | rem_port
 | ) |

Todo:
use mss from setsockopt()

Yield for IPv6 sockets

use TCP_NODELAY set in setsockopt()

< Definition at line 2035 of file SOCKET.C.

References _default_ttl, _eth_is_init, _inet6_ntoa(), _sock_set_rcv_buf(), _tcp_allsocs, _tcp_unthread(), icmp_upcall, my_ip_addr, set_timeout(), socket(), tcp_nagle, tcp_OPEN_TO, tcp_recv_win, UINT, and WORD.

int _TCP_open | ( | Socket * | socket,
 |  | struct in_addr | host,
 |  | WORD | loc_port,
 |  | WORD | rem_port
 | ) |

Open and listen routines for SOCK_STREAM at the socket-level.

The parameters to tcp_open() is a bit tricky, but the internal Wattcp socket 's' contains the following elements that must match in the first 'for-loop' of _tcp_handler().

s->hisport != 0 i.e. active (non-listening) port s->myaddr == ip->destination, our IP-address s->hisaddr == ip->source, above 'dest' address s->myport == tcp->dstPort, above 'loc_port' s->hisport == tcp->srcPort, above 'rem_port' Definition at line 1992 of file SOCKET.C.

References _sock_set_rcv_buf(), DWORD, icmp_upcall, socket(), tcp_open(), tcp_recv_win, and WORD.

int _UDP6_listen | ( | Socket * | socket,
 |  | const void * | host,
 |  | WORD | port
 | ) |

Todo:
Support UDP listen() for AF_INET6
Definition at line 2147 of file SOCKET.C.

References socket(), and WORD.

int _UDP6_open | ( | Socket * | socket,
 |  | const void * | host,
 |  | WORD | loc_port,
 |  | WORD | rem_port
 | ) |

Todo:
Support UDP connect() for AF_INET6
Definition at line 2136 of file SOCKET.C.

References _sock_set_rcv_buf(), icmp_upcall, socket(), and WORD.

W32_FUNC int select_s | ( | int | nfds,
 |  | fd_set * | readfds,
 |  | fd_set * | writefds,
 |  | fd_set * | exceptfds,
 |  | struct timeval * | timeout
 | ) |

The select_s() function.

Note:
It supports more sockets than would fit in a fd_set. I.e. it handles an array of 'fd_set's on input/output. Thus it is the user's responsibilty to not use a too high 'nfds' value. I.e. If nfs > 512*8 and user fd_set's on input is smaller than 512*, select_s() could trash the fd_set's on output.

Clear our "working" fd_sets.

Note:
Don't use FD_ZERO() since our working fd_sets contain more than FD_SETSIZE sockets.
Definition at line 112 of file SELECT.C.

unsigned sock_packet_receive | ( | Socket * | sock,
 |  | void * | buf,
 |  | unsigned | len,
 |  | struct sockaddr * | from,
 |  | int * | fromlen
 | ) |

Called from receive.c for AF_PACKET sockets.

Todo:
This should loop until some packet is received.
Definition at line 580 of file SOCKET.C.

References _eth_get_hwtype(), _pkt_ip_ofs, BYTE, and WORD.

Generated on Wed Jan 25 15:42:43 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/SOCKOPT.C File Reference

SRC/SOCKOPT.C File Reference

Detailed Description

BSD setsockopt(), getsockopt().

Definition in file SOCKOPT.C.

Go to the source code of this file.

Functions

int | set_sol_opt (Socket *s, int opt, const void *val, unsigned len)
int | set_raw_opt (Socket *s, int opt, const void *val, int len)
int | get_sol_opt (Socket *s, int opt, void *val, int *len)
int | get_raw_opt (Socket *s, int opt, void *val, int *len)
int | set_tcp_opt (_tcp_Socket *tcp, int opt, const void *val, int len)
int | set_udp_opt (_udp_Socket *udp, int opt, const void *val, int len)
int | get_tcp_opt (_tcp_Socket *tcp, int opt, void *val, int *len)
int | get_udp_opt (_udp_Socket *udp, int opt, void *val, int *len)
int | set_recv_buf (sock_type *s, DWORD size, BOOL is_tcp)
int | set_xmit_buf (sock_type *s, DWORD size, BOOL is_tcp)
int | raw_rx_buf (_raw_Socket *raw, DWORD size)
int | raw6_rx_buf (_raw6_Socket *raw, DWORD size)
int | raw_tx_buf (_raw_Socket *raw, DWORD size)
int | raw6_tx_buf (_raw6_Socket *raw, DWORD size)
int | set_tx_lowat (Socket *s, unsigned size)
int | set_rx_lowat (Socket *s, unsigned size)
int | get_tx_lowat (const Socket *s, unsigned *size)
int | get_rx_lowat (const Socket *s, unsigned *size)
const char * | sockopt_name (int level, int option)
int W32_CALL | setsockopt (int s, int level, int option, const void *optval, int optlen)
int W32_CALL | getsockopt (int s, int level, int option, void *optval, int *optlen)

Variables

const struct search_list | sol_options []
const struct search_list | tcp_options []
const struct search_list | ip_options []

Function Documentation

int get_sol_opt | ( | Socket * | s,
 |  | int | opt,
 |  | void * | val,
 |  | int * | len
 | ) | [static]

Todo:
Handle urgent (OOB) data

Handle these SOL_OPTIONS:

Definition at line 348 of file SOCKOPT.C.

References DWORD, and tcp_keep_idle.

int raw6_rx_buf | ( | _raw6_Socket * | raw,
 |  | DWORD | size
 | ) | [static]

Todo:
Support setting Rx-buffer size of raw IPv6 sockets
Definition at line 889 of file SOCKOPT.C.

int raw6_tx_buf | ( | _raw6_Socket * | raw,
 |  | DWORD | size
 | ) | [static]

Todo:
Support setting Tx-buffer size of raw IPv6 sockets
Definition at line 907 of file SOCKOPT.C.

int raw_rx_buf | ( | _raw_Socket * | raw,
 |  | DWORD | size
 | ) | [static]

Todo:
Support setting Rx-buffer size of raw IPv4 sockets
Definition at line 880 of file SOCKOPT.C.

int raw_tx_buf | ( | _raw_Socket * | raw,
 |  | DWORD | size
 | ) | [static]

Todo:
Support setting Tx-buffer size of raw IPv4 sockets
Definition at line 898 of file SOCKOPT.C.

Variable Documentation

const struct search_list ip_options[] [static]

Initial value:

 {
                  { IP_OPTIONS,        "IP_OPTIONS"         },
                  { IP_HDRINCL,        "IP_HDRINCL"         },
                  { IP_TOS,            "IP_TOS"             },
                  { IP_TTL,            "IP_TTL"             },
                  { IP_RECVOPTS,       "IP_RECVOPTS"        },
                  { IP_RECVRETOPTS,    "IP_RECVRETOPTS"     },
                  { IP_RECVDSTADDR,    "IP_RECVDSTADDR"     },
                  { IP_RETOPTS,        "IP_RETOPTS"         },
                  { IP_MULTICAST_IF,   "IP_MULTICAST_IF"    },
                  { IP_MULTICAST_TTL,  "IP_MULTICAST_TTL"   },
                  { IP_MULTICAST_LOOP, "IP_MULTICAST_LOOP"  },
                  { IP_ADD_MEMBERSHIP, "IP_ADD_MEMBERSHIP"  },
                  { IP_DROP_MEMBERSHIP,"IP_DROP_MEMBERSHIP" },
                  { IP_MULTICAST_VIF,  "IP_MULTICAST_VIF"   },
                  { IP_RSVP_ON,        "IP_RSVP_ON"         },
                  { IP_RSVP_OFF,       "IP_RSVP_OFF"        },
                  { IP_RSVP_VIF_ON,    "IP_RSVP_VIF_ON"     },
                  { IP_RSVP_VIF_OFF,   "IP_RSVP_VIF_OFF"    },
                  { IP_PORTRANGE,      "IP_PORTRANGE"       },
                  { IP_RECVIF,         "IP_RECVIF"          },
                  { IP_FW_ADD,         "IP_FW_ADD"          },
                  { IP_FW_DEL,         "IP_FW_DEL"          },
                  { IP_FW_FLUSH,       "IP_FW_FLUSH"        },
                  { IP_FW_ZERO,        "IP_FW_ZERO"         },
                  { IP_FW_GET,         "IP_FW_GET"          },
                  { IP_NAT,            "IP_NAT"             }
                }
Definition at line 1025 of file SOCKOPT.C.

const struct search_list sol_options[] [static]

Initial value:

 {
                  { SO_DEBUG,       "SO_DEBUG"       },
                  { SO_ACCEPTCONN,  "SO_ACCEPTCONN"  },
                  { SO_REUSEADDR,   "SO_REUSEADDR"   },
                  { SO_KEEPALIVE,   "SO_KEEPALIVE"   },
                  { SO_DONTROUTE,   "SO_DONTROUTE"   },
                  { SO_BROADCAST,   "SO_BROADCAST"   },
                  { SO_USELOOPBACK, "SO_USELOOPBACK" },
                  { SO_LINGER,      "SO_LINGER"      },
                  { SO_OOBINLINE,   "SO_OOBINLINE"   },
                  { SO_SNDBUF,      "SO_SNDBUF"      },
                  { SO_RCVBUF,      "SO_RCVBUF"      },
                  { SO_SNDLOWAT,    "SO_SNDLOWAT"    },
                  { SO_RCVLOWAT,    "SO_RCVLOWAT"    },
                  { SO_SNDTIMEO,    "SO_SNDTIMEO"    },
                  { SO_RCVTIMEO,    "SO_RCVTIMEO"    },
                  { SO_ERROR,       "SO_ERROR"       },
                  { SO_TYPE,        "SO_TYPE"        }
                }
Definition at line 998 of file SOCKOPT.C.

const struct search_list tcp_options[] [static]

Initial value:

 {
                  { TCP_NODELAY, "TCP_NODELAY" },
                  { TCP_MAXSEG,  "TCP_MAXSEG"  },
                  { TCP_NOPUSH,  "TCP_NOPUSH"  },
                  { TCP_NOOPT,   "TCP_NOOPT"   }
                }
Definition at line 1018 of file SOCKOPT.C.

Generated on Wed Jan 25 15:42:43 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/SPLIT.C File Reference

SRC/SPLIT.C File Reference

Detailed Description

Splitting of link-layer packets into components.

Definition in file SPLIT.C.

Go to the source code of this file.

Functions

void | split_mac (struct pkt_split *, const void *)
void | split_ip4 (struct pkt_split *, const in_Header *)
void | split_ip6 (struct pkt_split *, const in6_Header *)
const struct pkt_split * | pkt_get_split_in (void)
const struct pkt_split * | pkt_get_split_out (void)
const struct pkt_split * | pkt_get_type_in (enum Components type)
const struct pkt_split * | pkt_get_type_out (enum Components type)
const struct pkt_split * | pkt_split_mac_in (const void *ptr)
const struct pkt_split * | pkt_split_mac_out (const void *ptr)
void | pkt_print_split_in (void)
void | pkt_print_split_out (void)

Variables

pkt_split | split_list_in [MAX_SPLITS]
pkt_split | split_list_out [MAX_SPLITS]
const struct search_list | names []

Function Documentation

void split_ip6 | ( | struct pkt_split * | ps,
 |  | const in6_Header * | ip6
 | ) | [static]

Todo:
Handle Fragment, ESP, AUTH, IPv6 encap
Definition at line 342 of file SPLIT.C.

References BYTE, in6_Header::len, in6_Header::next_hdr, and WORD.

Generated on Wed Jan 25 15:42:43 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/SPLIT.H File Reference

SRC/SPLIT.H File Reference

Detailed Description

Definition in file SPLIT.H.

Go to the source code of this file.

Data Structures

struct | pkt_split

Enumerations

enum Components {
TYPE_TOKEN_HEAD = 1,
TYPE_FDDI_HEAD,
TYPE_ETHER_HEAD,
TYPE_ARCNET_HEAD,
TYPE_ARP,
TYPE_RARP,
TYPE_PPPOE_DISC,
TYPE_PPPOE_SESS,
TYPE_PPP_LCP,
TYPE_PPP_IPCP,
TYPE_LLC_HEAD,
TYPE_IP4,
TYPE_IP4_OPTIONS,
TYPE_IP4_FRAG,
TYPE_ICMP,
TYPE_IGMP,
TYPE_UDP_HEAD,
TYPE_UDP_DATA,
TYPE_TCP_HEAD,
TYPE_TCP_OPTIONS,
TYPE_TCP_DATA,
TYPE_IP6,
TYPE_IP6_HOP,
TYPE_IP6_IPV6,
TYPE_IP6_ROUTING,
TYPE_IP6_FRAGMENT,
TYPE_IP6_ESP,
TYPE_IP6_AUTH,
TYPE_IP6_ICMP,
TYPE_IP6_DEST,
TYPE_IP6_NONE,
TYPE_IP6_UNSUPP,
TYPE_MAX
}

Functions

const struct pkt_split * | pkt_split_mac_in (const void *link_pkt)
const struct pkt_split * | pkt_split_mac_out (const void *link_pkt)
const struct pkt_split * | pkt_get_split_in (void)
const struct pkt_split * | pkt_get_split_out (void)
const struct pkt_split * | pkt_get_type_in (enum Components type)
const struct pkt_split * | pkt_get_type_out (enum Components type)
void | pkt_print_split_in (void)
void | pkt_print_split_out (void)

Generated on Wed Jan 25 15:42:43 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/STREAM.C File Reference

SRC/STREAM.C File Reference

Detailed Description

sock_fgets(), sock_fputs().

BSD sockets functionality for Waterloo TCP/IP

Copyright (c) 1997-2002 Gisle Vanem <giva@bgnett.no>

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. All advertising materials mentioning features or use of this software must display the following acknowledgement: This product includes software developed by Gisle Vanem Bergen, Norway.

THIS SOFTWARE IS PROVIDED BY ME (Gisle Vanem) AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL I OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

Version

0.5 : Dec 18, 1997 : G. Vanem - created

Definition in file STREAM.C.

Go to the source code of this file.

Functions

int | sock_fgets (char *buf, int max, FILE *stream)
int | sock_fputs (const char *text, FILE *stream)

Generated on Wed Jan 25 15:42:43 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/STRINGS.C File Reference

SRC/STRINGS.C File Reference

Detailed Description

Printing to console and general string handling.

Definition in file STRINGS.C.

Go to the source code of this file.

Functions

void | _outchar (char c)
void | outch (char chr)
int (MS_CDECL *_printf)(const char *
int MS_CDECL | EmptyPrint (const char *fmt,...)
void | outs (const char *s)
void | outsnl (const char *s)
void | outsn (const char *s, int n)
void | outhex (char c)
void | outhexes (const char *s, int n)
char * | rip (char *s)
Removes end-of-line termination from a string.
BYTE | atox (const char *hex)
Convert hexstring "0x??" to hex.
char * | strreplace (int ch1, int ch2, char *str)
Replace 'ch1' to 'ch2' in string.
char * | StrLcpy (char *dst, const char *src, size_t len)
Similar to strncpy(), but always returns 'dst' with 0-termination.
char * | strltrim (const char *s)
Return pointer to first non-blank (space/tab) in a string.
char * | strrtrim (char *s)
Trim trailing blanks (space/tab) from a string.
size_t | strntrimcpy (char *dst, const char *src, size_t n)
Copy a string, stripping leading and trailing blanks (space/tab).
int | isstring (const char *str, size_t len)

Variables

void(* | _outch )(char c)=outch

Function Documentation

BYTE atox ( const char * hex )

Convert hexstring "0x??" to hex.

Just assumes "??" are in the [0-9,a-fA-F] range. Don't call atox() unless they are or before checking for a "0x" prefix. Definition at line 190 of file STRINGS.C.

References BYTE.

char* rip ( char * s )

Removes end-of-line termination from a string.

Removes "\n" (Unix), "\r" (MacOS) or "\r\n" (DOS/net-ascii) terminations, but not single "\n\r" (who uses that?). Definition at line 176 of file STRINGS.C.

char* StrLcpy | ( | char * | dst,
 |  | const char * | src,
 |  | size_t | len
 | ) |

Similar to strncpy(), but always returns 'dst' with 0-termination.

Note:
Don't call this strlcpy() in case Watt-32 was compiled with djgpp 2.03, but linked with 2.04 (which already have strlcpy). And vice-versa.
Definition at line 224 of file STRINGS.C.

size_t strntrimcpy | ( | char * | dst,
 |  | const char * | src,
 |  | size_t | n
 | ) |

Copy a string, stripping leading and trailing blanks (space/tab).

Note:
This function does not work exactly like strncpy(), in that it expects the destination buffer to be at last (n+1) chars long.
Definition at line 277 of file STRINGS.C.

Generated on Wed Jan 25 15:42:43 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/STRINGS.H File Reference

SRC/STRINGS.H File Reference

Detailed Description

Definition in file STRINGS.H.

Go to the source code of this file.

Functions

W32_DATA | int (MS_CDECL *_printf)(const char *fmt
W32_DATA | ATTR_PRINTF (1, 2)
W32_FUNC void | outs (const char *s)
W32_FUNC void | outsnl (const char *s)
W32_FUNC void | outsn (const char *s, int n)
W32_FUNC void | outhexes (const char *s, int n)
W32_FUNC void | outhex (char ch)
W32_FUNC char * | rip (char *s)
Removes end-of-line termination from a string.
char * | strreplace (int ch1, int ch2, char *str)
Replace 'ch1' to 'ch2' in string.
char * | StrLcpy (char *dst, const char *src, size_t len)
Similar to strncpy(), but always returns 'dst' with 0-termination.
size_t | strntrimcpy (char *dst, const char *src, size_t len)
Copy a string, stripping leading and trailing blanks (space/tab).
char * | strrtrim (char *src)
Trim trailing blanks (space/tab) from a string.
char * | strltrim (const char *src)
Return pointer to first non-blank (space/tab) in a string.
BYTE | atox (const char *src)
Convert hexstring "0x??" to hex.

Variables

W32_DATA void(* | _outch )(char c)

Function Documentation

BYTE atox ( const char * hex )

Convert hexstring "0x??" to hex.

Just assumes "??" are in the [0-9,a-fA-F] range. Don't call atox() unless they are or before checking for a "0x" prefix. Definition at line 190 of file STRINGS.C.

References BYTE.

W32_FUNC char* rip ( char * s )

Removes end-of-line termination from a string.

Removes "\n" (Unix), "\r" (MacOS) or "\r\n" (DOS/net-ascii) terminations, but not single "\n\r" (who uses that?). Definition at line 176 of file STRINGS.C.

char* StrLcpy | ( | char * | dst,
 |  | const char * | src,
 |  | size_t | len
 | ) |

Similar to strncpy(), but always returns 'dst' with 0-termination.

Note:
Don't call this strlcpy() in case Watt-32 was compiled with djgpp 2.03, but linked with 2.04 (which already have strlcpy). And vice-versa.
Definition at line 224 of file STRINGS.C.

size_t strntrimcpy | ( | char * | dst,
 |  | const char * | src,
 |  | size_t | n
 | ) |

Copy a string, stripping leading and trailing blanks (space/tab).

Note:
This function does not work exactly like strncpy(), in that it expects the destination buffer to be at last (n+1) chars long.
Definition at line 277 of file STRINGS.C.

Generated on Wed Jan 25 15:42:43 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/SYSLOG.C File Reference

SRC/SYSLOG.C File Reference

Detailed Description

Simple syslog handler for Watt-32.

Loosely based on BSD-version. by Gisle Vanem <giva@bgnett.no> Jun-99

This module really belongs to the application layer, but is included in Watt-32 for convenience.

Note:
syslog_init() must be called in watt_sock_init() (or prior to that). openlog() and syslog() cannot be used before watt_sock_init() is called.

Todo:
configure variables in syslog2.c when calling openlog() thus making syslog() independant of watt_sock_init().

Definition in file SYSLOG.C.

Go to the source code of this file.

Functions

void MS_CDECL | syslog (int pri, const char *fmt,...)
void | vsyslog (int pri, const char *fmt, va_list ap)
const char * | getlogname (void)
int | openloghost (char **errbuf)
void | openlog (const char *ident, int logstat, int logfac)
int | setlogmask (int mask)
char * | setlogtag (char *newTag)
void | closelog (void)
int | main (void)

Variables

sock_type * | logSock = NULL
FILE * | logFile = NULL
DWORD | logHost = 0UL
BOOL | logOpened = FALSE
int | logStat = 0
char * | logTag = NULL
int | logMask = LOG_INFO
DWORD | logFacil = LOG_USER
CODE | prioritynames []
CODE | facilitynames []

Variable Documentation

CODE facilitynames[]

Initial value:

 {
        { LOG_AUTH,      "auth"      },
        { LOG_AUTHPRIV,  "authpriv"  },
        { LOG_CRON,      "cron"      },
        { LOG_DAEMON,    "daemon"    },
        { LOG_FTP,       "ftp"       },
        { LOG_KERN,      "kern"      },
        { LOG_LPR,       "lpr"       },
        { LOG_MAIL,      "mail"      },
        { INTERNAL_MARK, "mark"      },
        { LOG_NEWS,      "news"      },
        { LOG_NTP,       "ntp"       },
        { LOG_AUTH,      "security"  },
        { LOG_SYSLOG,    "syslog"    },
        { LOG_USER,      "user"      },
        { LOG_UUCP,      "uucp"      },
        { LOG_LOCAL0,    "local0"    },
        { LOG_LOCAL1,    "local1"    },
        { LOG_LOCAL2,    "local2"    },
        { LOG_LOCAL3,    "local3"    },
        { LOG_LOCAL4,    "local4"    },
        { LOG_LOCAL5,    "local5"    },
        { LOG_LOCAL6,    "local6"    },
        { LOG_LOCAL7,    "local7"    },
        { -1,            NULL        }
      }
Definition at line 83 of file SYSLOG.C.

CODE prioritynames[]

Initial value:

 {
        { LOG_ALERT,      "alert"    },
        { LOG_CRIT,       "crit"     },
        { LOG_DEBUG,      "debug"    },
        { LOG_EMERG,      "emerg"    },
        { LOG_ERR,        "err"      },
        { LOG_ERR,        "error"    },
        { LOG_INFO,       "info"     },
        { INTERNAL_NOPRI, "none"     },
        { LOG_NOTICE,     "notice"   },
        { LOG_EMERG,      "panic"    },
        { LOG_WARNING,    "warn"     },
        { LOG_WARNING,    "warning"  },
        { -1,             NULL       }
      }
Definition at line 67 of file SYSLOG.C.

Generated on Wed Jan 25 15:42:43 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/SYSLOG2.C File Reference

SRC/SYSLOG2.C File Reference

Detailed Description

Config-parser for syslog().

Simple syslog handler for Watt-32 & DOS. This module contain data and config-parser only.

Copyright (c) 1997-2002 Gisle Vanem <giva@bgnett.no>

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. All advertising materials mentioning features or use of this software must display the following acknowledgement: This product includes software developed by Gisle Vanem Bergen, Norway.

THIS SOFTWARE IS PROVIDED BY ME (Gisle Vanem) AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL I OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

Definition in file SYSLOG2.C.

Go to the source code of this file.

Functions

int | getlogmask (const char *value)
void | set_syslog_mask (const char *value)
void | ourinit (const char *name, const char *value)
void | syslog_init (void)

Variables

void(* | prev_hook )(const char *, const char *)=NULL
char | syslog_fileName [MAX_NAMELEN] = ""
char | syslog_hostName [MAX_HOSTLEN] = ""
WORD | syslog_port = 514
int | syslog_mask = LOG_UPTO(-1)

Generated on Wed Jan 25 15:42:43 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/SYSLOG2.H File Reference

SRC/SYSLOG2.H File Reference

Detailed Description

Definition in file SYSLOG2.H.

Go to the source code of this file.

Functions

void | syslog_init (void)

Variables

char | syslog_fileName [MAX_NAMELEN]
char | syslog_hostName [MAX_HOSTLEN]
WORD | syslog_port
int | syslog_mask

Generated on Wed Jan 25 15:42:43 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/TARGET.H File Reference

SRC/TARGET.H File Reference

Detailed Description

Definitions of targets and macros for Waterloo tcp/ip.

by G. Vanem <giva@bgnett.no> 1995 - 2003

Definition in file TARGET.H.

Go to the source code of this file.

Typedefs

typedef BYTE _far * | FARPTR

Functions

void | ENABLE (void)
void | DISABLE (void)
int __cdecl | kbhit (void)

Variables

REALPTR | _watt_dosTbr
DWORD | _watt_dosTbSize
FARPTR | _watt_dosFp
WORD | _watt_dosTbSeg
WORD | _watt_dos_ds
CRITICAL_SECTION | _watt_crit_sect

Variable Documentation

FARPTR _watt_dosFp

Todo:
detect program restarts
Definition at line 267 of file TARGET.H.

Generated on Wed Jan 25 15:42:43 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/TCP_FSM.C File Reference

SRC/TCP_FSM.C File Reference

Detailed Description

State machine for TCP processing. Previously this was in pctcp.c and tcp_handler().

Definition in file TCP_FSM.C.

Go to the source code of this file.

Data Structures

struct | tcp_reasm

Typedefs

typedef int(* | tcp_StateProc )(_tcp_Socket **, const in_Header *, tcp_Header *, int)

Functions

int | tcp_listen_state (_tcp_Socket **, const in_Header *, tcp_Header *, int)
int | tcp_resolve_state (_tcp_Socket **, const in_Header *, tcp_Header *, int)
int | tcp_synsent_state (_tcp_Socket **, const in_Header *, tcp_Header *, int)
int | tcp_synrec_state (_tcp_Socket **, const in_Header *, tcp_Header *, int)
int | tcp_estab_state (_tcp_Socket **, const in_Header *, tcp_Header *, int)
int | tcp_estcl_state (_tcp_Socket **, const in_Header *, tcp_Header *, int)
int | tcp_finwt1_state (_tcp_Socket **, const in_Header *, tcp_Header *, int)
int | tcp_finwt2_state (_tcp_Socket **, const in_Header *, tcp_Header *, int)
int | tcp_closewt_state (_tcp_Socket **, const in_Header *, tcp_Header *, int)
int | tcp_closing_state (_tcp_Socket **, const in_Header *, tcp_Header *, int)
int | tcp_lastack_state (_tcp_Socket **, const in_Header *, tcp_Header *, int)
int | tcp_timewt_state (_tcp_Socket **, const in_Header *, tcp_Header *, int)
int | tcp_process_data (_tcp_Socket *s, const tcp_Header *tcp, int len, int *flags)
Process the data in an incoming segment.
void | tcp_set_window (_tcp_Socket *s, const tcp_Header *tcp)
Allocate a Tx-buffer based on peer's advertised window.
int | tcp_process_ACK (_tcp_Socket *s, long *unack)
int | tcp_reassemble (_tcp_Socket *s, const tcp_Header *tcp, UINT len, int flags)
int | _tcp_fsm (_tcp_Socket **sp, const in_Header *ip)
void | tcp_process_options (_tcp_Socket *s, const tcp_Header *tcp, const BYTE *tcp_data, int flags)
Process TCP options in segment.
void | copy_in_order (_tcp_Socket *s, const BYTE *data, unsigned len)
void | data_in_order (_tcp_Socket *s, const BYTE *data, unsigned len, unsigned diff)
void | prepend_out_of_order (_tcp_Socket *s, const BYTE *data, unsigned len)
void | append_out_of_order (_tcp_Socket *s, const BYTE *data, unsigned len)
void | data_out_of_order (_tcp_Socket *s, const BYTE *data, unsigned len, unsigned diff)
int | tcp_reassemble (_tcp_Socket *s, const tcp_Header *tcp, const BYTE *data, UINT len, int *flags)

Variables

tcp_StateProc | tcp_state_tab []
BOOL | is_ip4
DWORD | acknum
DWORD | seqnum

Function Documentation

int tcp_process_data | ( | _tcp_Socket * | s,
 |  | const tcp_Header * | tcp,
 |  | int | len,
 |  | int * | flags
 | ) | [static]

Process the data in an incoming segment.

Called from all states where incoming data can be received: SYNSENT, ESTAB, ESTCL, CLOSWT, FIN-WAIT-1 and FIN-WAIT-2.

Todo:
Handle Out-of-Order urgent data. Raise SIGURG.
Definition at line 991 of file TCP_FSM.C.

References _tcp_Socket::adv_win, BYTE, _tcp_Socket::recv_next, tcp_process_options(), tcp_set_window(), _tcp_Socket::tx_datalen, and _tcp_Socket::unhappy.

int tcp_reassemble | ( | _tcp_Socket * | s,
 |  | const tcp_Header * | tcp,
 |  | const BYTE * | data,
 |  | UINT | len,
 |  | int * | flags
 | ) | [static]

Todo:
Create a better TCP reassembler some day. Current logic only handles 1 missed segment. We should handle at least 2.
Definition at line 1197 of file TCP_FSM.C.

References _tcp_Socket::adv_win, BYTE, DWORD, _tcp_Socket::recv_next, and UINT.

void tcp_set_window | ( | _tcp_Socket * | s,
 |  | const tcp_Header * | tcp
 | ) | [static]

Allocate a Tx-buffer based on peer's advertised window.

Note: our advertised window (s->adv_win) is controlled by sock_setbuf().

Todo:
Set slow-start threshold
Definition at line 1153 of file TCP_FSM.C.

References BYTE, DWORD, _tcp_Socket::max_tx_data, _tcp_Socket::tx_buf, _tcp_Socket::tx_data, _tcp_Socket::tx_datalen, _tcp_Socket::window, and WORD.

int tcp_synsent_state | ( | _tcp_Socket ** | sp,
 |  | const in_Header * | ip,
 |  | tcp_Header * | tcp,
 |  | int | flags
 | ) | [static]

Todo:
recalculate RTT-timer
Definition at line 217 of file TCP_FSM.C.

References _tcp_Socket::flags, _tcp_Socket::last_seqnum, in6_Header::len, in_Header::length, _tcp_Socket::recv_next, _tcp_Socket::send_next, set_timeout(), _tcp_Socket::state, tcp_process_data(), _tcp_Socket::timeout, _tcp_Socket::tos, in_Header::tos, _tcp_Socket::tx_datalen, and _tcp_Socket::unhappy.

Variable Documentation

tcp_StateProc tcp_state_tab[] [static]

Initial value:

 {
  tcp_listen_state,
  tcp_resolve_state,
  tcp_synsent_state,
  tcp_synrec_state,
  tcp_estab_state,
  tcp_estcl_state,
  tcp_finwt1_state,
  tcp_finwt2_state,
  tcp_closewt_state,
  tcp_closing_state,
  tcp_lastack_state,
  tcp_timewt_state,
}
Definition at line 63 of file TCP_FSM.C.

Generated on Wed Jan 25 15:42:43 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/TCP_MD5.C File Reference

SRC/TCP_MD5.C File Reference

Detailed Description

Handling of TCP MD5 fingrprint option.

Copyright (c) 1997-2002 Gisle Vanem <giva@bgnett.no> Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. All advertising materials mentioning features or use of this software must display the following acknowledgement: This product includes software developed by Gisle Vanem Bergen, Norway.

THIS SOFTWARE IS PROVIDED BY ME (Gisle Vanem) AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL I OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

Version

0.1 : Mar 24, 2004 : G. Vanem - created

Definition in file TCP_MD5.C.

Go to the source code of this file.

Data Structures

struct | MD5_CTX

Functions

void | MD5_Init (MD5_CTX *context)
void | MD5_Update (MD5_CTX *context, const void *buffer, size_t length)
void | MD5_Final (BYTE result[16], MD5_CTX *context)
const char * | tcp_md5_secret (void *s, const char *secret)
void | make_md5_signature (const in_Header *ip, const tcp_Header *tcp, WORD datalen, const char *secret, BYTE *buf)
BOOL | check_md5_signature (const _tcp_Socket *s, const in_Header *ip)
void | Transform (DWORD[4], const BYTE *)
void | Encode (BYTE *, const DWORD *, size_t)
void | Decode (DWORD *, const BYTE *, size_t)

Variables

BYTE | padding [64]

Variable Documentation

BYTE padding[64] [static]

Initial value:

 {
       0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
       0, 0
     }
Definition at line 256 of file TCP_MD5.C.

Generated on Wed Jan 25 15:42:43 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/TCP_MD5.H File Reference

SRC/TCP_MD5.H File Reference

Detailed Description

Definition in file TCP_MD5.H.

Go to the source code of this file.

Functions

const char * | tcp_md5_secret (void *s, const char *secret)
void | make_md5_signature (const in_Header *ip, const tcp_Header *tcp, WORD datalen, const char *secret, BYTE *buf)
BOOL | check_md5_signature (const _tcp_Socket *s, const in_Header *ip)

Generated on Wed Jan 25 15:42:43 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/TEREDO64.H File Reference

SRC/TEREDO64.H File Reference

Detailed Description

Definition in file TEREDO64.H.

Go to the source code of this file.

Generated on Wed Jan 25 15:42:43 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/TFTP.C File Reference

SRC/TFTP.C File Reference

Detailed Description

TFTP client.

Boot-ROM-Code to load (any file or) an operating system across a TCP/IP network.

Module: tftp.c Purpose: Get a file with TFTP protocol Entries: tftp_boot_load, tftp_set_server, tftp_set_boot_fname

Copyright (C) 1995,1996,1997 Gero Kuhlmann <gero@gkminix.han.de>

This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

Major changes for Watt-32 by G. Vanem <giva@bgnett.no> 1999

This client adheres to RFC-1350 (TFTP v2), but supports only reading from a remote host.

Todo:
Support option negotiation and ETFTP (RFC-1986)

Definition in file TFTP.C.

Go to the source code of this file.

Functions

void | send_req (char request, const char *fname)
void | send_ack (WORD block)
const char * | tftp_strerror (int code)
void | udp_callback (_udp_Socket *s, int icmp_type, int icmp_code)
int | recv_packet (DWORD block)
int | tftp_open (DWORD server, const char *fname)
void | tftp_close (void)
char * | tftp_set_server (const char *name, int len)
char * | tftp_set_boot_fname (const char *name, int len)
char * | tftp_set_xfer_mode (const char *name)
int | tftp_get_block (const char **buf)
int | tftp_boot_load (void)
void | tftp_cfg_hook (const char *name, const char *value)
void | tftp_exit (void)
Free allocated memory.
int | tftp_init (void)
Initialize config-hook for TFTP protocol.
int | close_func (void)
int | write_func (const void *buf, size_t length)
void | usage (char *argv0)
int | main (int argc, char **argv)

Variables

int(* | tftp_writer )(const void *, size_t)=NULL
int(* | tftp_terminator )(void)=NULL
tftphdr * | inbuf
tftphdr * | outbuf
sock_type * | sock
DWORD | currblock
int | blocksize
int | ibuflen
int | isopen
int | tftp_errno = 0
DWORD | tftp_server = 0
int | tftp_timeout = TFTP_TIMEOUT
int | tftp_retry = TFTP_RETRY
int | tftp_lport = 0
char | tftp_server_name [MAX_HOSTLEN] = ""
char | tftp_xfer_mode [MAX_VALUELEN] = OCTET_STR
char * | tftp_boot_remote_file = NULL
char * | tftp_boot_local_file = NULL
char * | tftp_openmode = NULL
void(* | prev_hook )(const char *, const char *)=NULL
FILE * | file
char * | fname
DWORD | tot_size
time_t | start

Generated on Wed Jan 25 15:42:43 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/TFTP.H File Reference

SRC/TFTP.H File Reference

Detailed Description

Boot-ROM-Code to load an operating system across a TCP/IP network.

Definitions for implementing the TFTP protocol

Copyright (C) 1995,1996,1997 Gero Kuhlmann <gero@gkminix.han.de>

This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

Definition in file TFTP.H.

Go to the source code of this file.

Functions

int | tftp_init (void)
Initialize config-hook for TFTP protocol.
int | tftp_boot_load (void)
char * | tftp_set_server (const char *name, int len)
char * | tftp_set_boot_fname (const char *name, int len)

Variables

int(* | tftp_writer )(const void *buf, size_t length)
int(* | tftp_terminator )(void)

Generated on Wed Jan 25 15:42:43 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/TIMER.C File Reference

SRC/TIMER.C File Reference

Detailed Description

Module for handling timers.

Modifications by GvB 2002-09

Todo:
To get rid of the timer problem once and for all we need a timer ISR that increments a 32-bit value no regard to day roll-over etc. Maybe hook up IRQ 8 to call a real-mode stub that we opy to DOS-memory (similar to the pkt_receiver stub code. Then far-peek at that timer variable.
09-Jan-2003: Bernd Omenitch <Omenitsch@cashpoint.at> contributed the Timer ISR code (init_timer_isr() etc). I rewrote it and added support for Borland/PowerPak/Pharlap).

Definition in file TIMER.C.

Go to the source code of this file.

Functions

void | init_timers (void)
Setup timer stuff and measure CPU speed.
void | init_userSuppliedTimerTick (void)
init_userSuppliedTimerTick() - setup timer handling for programs that are already running a periodic interrupt or whatever (i.e.
void | userTimerTick (DWORD elapsed_time_msec)
Provide timer-ticks from an application.
void | new_int_8 (void)
User defined 10ms counter ISR.
void | exit_timer_isr (void)
void | init_timer_isr (void)
int | cmp_timers (DWORD t1, DWORD t2)
Compare two timers with expirary at 't1' and 't2'.
int | hires_timer (int on)
Control use of high-resolution timer.
DWORD | clockbits (void)
DWORD | millisec_clock (void)
DWORD | set_timeout (DWORD msec)
Return time for when given timeout (msec) expires.
BOOL | chk_timeout (DWORD value)
Check if milli-sec value has expired:.
int | set_timediff (long msec)
Must be called by user right before or after a time change occurs.
long | get_timediff (DWORD now, DWORD tim)
Return time difference between timers 'now' and 'tim'.
double | timeval_diff (const struct timeval *newer, const struct timeval *older)
double | filetime_sec (const void *filetime)
const char * | time_str (DWORD val)
const char * | hms_str (DWORD sec)
const char * | elapsed_str (DWORD val)
DWORD | ms_clock (void)
void | profile_start (const char *str)
void | profile_stop (void)
void | profile_exit (void)
void | profile_dump (const uint64 *data, size_t num)
void | profile_recv (const uint64 *putp, const uint64 *getp)
int | profile_init (void)
int | profile_on (void)
void | Wait_N_ticks (int num)
uint64 | get_cpu_speed (void)
Return estimated CPU speed in Hz.

Variables

DWORD | start_time = 0
Start-time of watt_sock_init() (in msec).
DWORD | start_day = 0
Start-day of watt_sock_init().
BOOL | has_8254 = FALSE
Do we have a working 8254 timer chip?
BOOL | has_rdtsc = FALSE
Do we have a CPU with RDTSC instruction?
BOOL | use_rdtsc = FALSE
Do not use RDTSC by default.
BOOL | using_int8 = FALSE
init_timer_isr() called
DWORD clocks_per_usec
Measured CPU speed (MHz).
time_t | user_tick_base = 0UL
DWORD | user_tick_msec = 0UL
BOOL | user_tick_active = FALSE
DWORD | date = 0
DWORD | date_ms = 0
BOOL | profile_enable = FALSE
char | profile_file [MAX_PATHLEN+1] = ".\\WATTCP.PRO"
FILE * | prof_fout
uint64 | prof_start
uint64 | num_profs
W32_IntrHandler | old_int_8 = NULL
REALPTR | int8_cback
FARPTR | old_int_8_pm
RMC_BLK | rmBlock_int8
DWORD | itimer_resolution = 0UL
void(* | old_sigalrm )(int)
itimerval | old_itimer
DWORD | tick_timer_8254 = 0UL

Function Documentation

BOOL chk_timeout ( DWORD value )

Check if milli-sec value has expired:.

Return values:
\li TRUE timer expired
  • FALSE not expired (or value not set)
Definition at line 528 of file TIMER.C.

References DWORD, has_8254, and set_timeout().

int cmp_timers | ( | DWORD | t1,
 |  | DWORD | t2
 | ) |

Compare two timers with expirary at 't1' and 't2'.

Return values:
\li -1 if t1 expires before t2
  • 0 if t1 == t2
  • +1 if t1 expires after t2
Note:
This logic fails when timers approaches ULONG_MAX after approx. 50 days.
Definition at line 347 of file TIMER.C.

long get_timediff | ( | DWORD | now,
 |  | DWORD | tim
 | ) |

Return time difference between timers 'now' and 'tim'.

Check for day rollover. Max timer distance is 24 hours. This function should be called immediately after chk_timeout() is called. Definition at line 598 of file TIMER.C.

References has_8254.

int hires_timer ( int on )

Control use of high-resolution timer.

When using Watt-32 together with programs that reprogram the PIT (8254 timer chip), the millisec_clock() function may return wrong values. In such cases it's best to use old-style 55ms timers. Using Watt-32 with Allegro graphics library is one such case where application program should call `ÿhires_timer(0)' after `sock_init()' has been called. Definition at line 363 of file TIMER.C.

References chk_timeout(), and has_8254.

void init_timers ( void )

Setup timer stuff and measure CPU speed.

Called from init_misc().

<

Todo:
check if 8254 PIT is really working
Definition at line 116 of file TIMER.C.

References chk_timeout(), clocks_per_usec, DWORD, get_cpu_speed(), has_rdtsc, hires_timer(), set_utc_offset(), and use_rdtsc.

void init_userSuppliedTimerTick ( void )

init_userSuppliedTimerTick() - setup timer handling for programs that are already running a periodic interrupt or whatever (i.e.

ALLEGRO & more). This is called to signify that the 'user task' will periodically call userTimerTick() to supply the elapsed time since the last call. Best called once before sock_init(). There is no way to revert to original timer handling once this is called. By GvB 2002-09 Definition at line 148 of file TIMER.C.

References has_8254.

int set_timediff ( long msec )

Must be called by user right before or after a time change occurs.

Not used in Watt-32. Definition at line 585 of file TIMER.C.

DWORD set_timeout ( DWORD msec )

Return time for when given timeout (msec) expires.

Make sure it never returns 0 (it will confuse chk_timeout). Definition at line 487 of file TIMER.C.

References DWORD, and has_8254.

void userTimerTick ( DWORD elapsed_time_msec )

Provide timer-ticks from an application.

This should be periodically called from user code to increment the timer count once activated via init_userSuppliedTimerTick(). Best called from a periodic interrupt handler (int 8/1Ch/70h) which is the case now with init_timer_isr(). GvB 2002-09 Definition at line 175 of file TIMER.C.

Generated on Wed Jan 25 15:42:43 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/TIMER.H File Reference

SRC/TIMER.H File Reference

Detailed Description

Definition in file TIMER.H.

Go to the source code of this file.

Functions

W32_FUNC void | init_timers (void)
Setup timer stuff and measure CPU speed.
W32_FUNC DWORD | set_timeout (DWORD msec)
Return time for when given timeout (msec) expires.
W32_FUNC BOOL | chk_timeout (DWORD timeout)
Check if milli-sec value has expired:.
W32_FUNC int | cmp_timers (DWORD t1, DWORD t2)
Compare two timers with expirary at 't1' and 't2'.
W32_FUNC DWORD | millisec_clock (void)
W32_FUNC int | hires_timer (int on)
Control use of high-resolution timer.
DWORD | clockbits (void)
DWORD | ms_clock (void)
W32_FUNC int | set_timediff (long msec)
Must be called by user right before or after a time change occurs.
W32_FUNC long | get_timediff (DWORD now, DWORD t)
Return time difference between timers 'now' and 'tim'.
W32_FUNC double | timeval_diff (const struct timeval *a, const struct timeval *b)
W32_FUNC double | filetime_sec (const void *filetime)
const char * | time_str (DWORD val)
const char * | hms_str (DWORD sec)
const char * | elapsed_str (DWORD val)
W32_FUNC void | init_timer_isr (void)
W32_FUNC void | exit_timer_isr (void)
W32_FUNC void | init_userSuppliedTimerTick (void)
init_userSuppliedTimerTick() - setup timer handling for programs that are already running a periodic interrupt or whatever (i.e.
W32_FUNC void | userTimerTick (DWORD elapsedTimeMs)
Provide timer-ticks from an application.
uint64 | get_cpu_speed (void)
Return estimated CPU speed in Hz.
void | profile_start (const char *where)
void | profile_stop (void)
int | profile_init (void)
int | profile_on (void)
void | profile_dump (const uint64 *data, size_t num_elem)
void | profile_recv (const uint64 *put, const uint64 *get)

Variables

W32_DATA BOOL | has_8254
W32_DATA BOOL | has_rdtsc
W32_DATA BOOL | use_rdtsc
W32_DATA BOOL | user_tick_active
W32_DATA BOOL | using_int8
W32_DATA DWORD | clocks_per_usec
W32_DATA DWORD | user_tick_msec
W32_DATA time_t | user_tick_base
W32_DATA DWORD | start_time
W32_DATA DWORD | start_day
BOOL | profile_enable
char | profile_file [MAX_PATHLEN+1]

Function Documentation

W32_FUNC BOOL chk_timeout ( DWORD value )

Check if milli-sec value has expired:.

Return values:
\li TRUE timer expired
  • FALSE not expired (or value not set)
Definition at line 528 of file TIMER.C.

W32_FUNC int cmp_timers | ( | DWORD | t1,
 |  | DWORD | t2
 | ) |

Compare two timers with expirary at 't1' and 't2'.

Return values:
\li -1 if t1 expires before t2
  • 0 if t1 == t2
  • +1 if t1 expires after t2
Note:
This logic fails when timers approaches ULONG_MAX after approx. 50 days.
Definition at line 347 of file TIMER.C.

W32_FUNC long get_timediff | ( | DWORD | now,
 |  | DWORD | tim
 | ) |

Return time difference between timers 'now' and 'tim'.

Check for day rollover. Max timer distance is 24 hours. This function should be called immediately after chk_timeout() is called. Definition at line 598 of file TIMER.C.

W32_FUNC int hires_timer ( int on )

Control use of high-resolution timer.

When using Watt-32 together with programs that reprogram the PIT (8254 timer chip), the millisec_clock() function may return wrong values. In such cases it's best to use old-style 55ms timers. Using Watt-32 with Allegro graphics library is one such case where application program should call `ÿhires_timer(0)' after `sock_init()' has been called. Definition at line 363 of file TIMER.C.

W32_FUNC void init_timers ( void )

Setup timer stuff and measure CPU speed.

Called from init_misc().

<

Todo:
check if 8254 PIT is really working
Definition at line 116 of file TIMER.C.

References chk_timeout(), clocks_per_usec, DWORD, get_cpu_speed(), has_rdtsc, hires_timer(), set_utc_offset(), and use_rdtsc.

W32_FUNC void init_userSuppliedTimerTick ( void )

init_userSuppliedTimerTick() - setup timer handling for programs that are already running a periodic interrupt or whatever (i.e.

ALLEGRO & more). This is called to signify that the 'user task' will periodically call userTimerTick() to supply the elapsed time since the last call. Best called once before sock_init(). There is no way to revert to original timer handling once this is called. By GvB 2002-09 Definition at line 148 of file TIMER.C.

W32_FUNC int set_timediff ( long msec )

Must be called by user right before or after a time change occurs.

Not used in Watt-32. Definition at line 585 of file TIMER.C.

W32_FUNC DWORD set_timeout ( DWORD msec )

Return time for when given timeout (msec) expires.

Make sure it never returns 0 (it will confuse chk_timeout). Definition at line 487 of file TIMER.C.

W32_FUNC void userTimerTick ( DWORD elapsed_time_msec )

Provide timer-ticks from an application.

This should be periodically called from user code to increment the timer count once activated via init_userSuppliedTimerTick(). Best called from a periodic interrupt handler (int 8/1Ch/70h) which is the case now with init_timer_isr(). GvB 2002-09 Definition at line 175 of file TIMER.C.

Generated on Wed Jan 25 15:42:43 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/TRANSMIT.C File Reference

SRC/TRANSMIT.C File Reference

Detailed Description

BSD send(), sendto(), write().

Definition in file TRANSMIT.C.

Go to the source code of this file.

Functions

int | raw_transmit (Socket *socket, const void *buf, unsigned len)
int | udp_transmit (Socket *socket, const void *buf, unsigned len)
int | tcp_transmit (Socket *socket, const void *buf, unsigned len, int flags)
int | setup_udp_raw (Socket *socket, const struct sockaddr *to, int tolen)
int | transmit (const char *func, int s, const void *buf, unsigned len, int flags, const struct sockaddr *to, int tolen, BOOL from_sendto)
int W32_CALL | sendto (int s, const void *buf, int len, int flags, const struct sockaddr *to, int tolen)
int W32_CALL | send (int s, const void *buf, int len, int flags)
int | write_s (int s, const char *buf, int nbyte)
int | writev_s (int s, const struct iovec *vector, size_t count)
int | sendmsg (int s, const struct msghdr *msg, int flags)
__inline void | msg_eor_close (Socket *socket)
__inline BOOL | check_non_block_tx (Socket *socket, unsigned *len)
int | ip4_transmit (Socket *socket, const void *tx, unsigned len)
Raw IPv4 transmitter.
int | ip6_transmit (Socket *socket, const void *tx, unsigned len)
Raw IPv6 transmitter.

Function Documentation

int ip4_transmit | ( | Socket * | socket,
 |  | const void * | tx,
 |  | unsigned | len
 | ) | [static]

Raw IPv4 transmitter.

Note:
'tx' is always non-NULL and 'len' is always > 0. Except for SOCK_DGRAM probe packets (tx=NULL and len==0).

Todo:
Handle sending fragments with IP optons
Definition at line 721 of file TRANSMIT.C.

References _arp_resolve(), _eth_formatpacket(), _eth_send(), _get_ip4_id(), BYTE, DWORD, eth_address, gethostid(), socket(), UINT, and WORD.

int ip6_transmit | ( | Socket * | socket,
 |  | const void * | tx,
 |  | unsigned | len
 | ) | [static]

Raw IPv6 transmitter.

Note:
'tx' is always non-NULL and 'len' is always > 0. Except for SOCK_DGRAM probe packets (tx=NULL and len==0).

Todo:
support fragmentation
Definition at line 878 of file TRANSMIT.C.

References _default_ttl, _eth_formatpacket(), _eth_send(), _gethostid6(), _inet6_ntoa(), BYTE, eth_address, ip6_address, and socket().

int tcp_transmit | ( | Socket * | socket,
 |  | const void * | buf,
 |  | unsigned | len,
 |  | int | flags
 | ) | [static]

Todo:
Allow non-blocking sockets to send in SYNSENT state
Definition at line 471 of file TRANSMIT.C.

References _inet6_ntoa(), BYTE, _tcp_Socket::datatimer, _tcp_Socket::max_tx_data, sock_enqueue(), sock_write(), socket(), _tcp_Socket::state, sock_type::tcp, tcp_Retransmitter(), and tcp_tick().

Generated on Wed Jan 25 15:42:43 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/UDP_DOM.C File Reference

SRC/UDP_DOM.C File Reference

Detailed Description

Domain Name Server protocol.

This portion of the code needs some major work. I ported it (read STOLE IT) from NCSA and lost about half the code somewhere in the process.

Version:
0.6
Date:
Mar 19, 2004 - Added ACE encoding/decoding of international domain names. Ref. RFC-3490.
Version:
0.5
Date:
Aug 20, 2003 - Added storing of CNAME record (used as alias in gethostbyname, gethostbyaddr)
Version:
0.4
Date:
Aug 04, 2002 - Rewritten for IPv6 support (DTYPE_AAAA)
Version:
0.3
Date:
Jun 16, 1997 - calling usr_yield (i.e. system_yield) while resolving
Version:
0.2
Date:
Apr 24, 1991 - use substring portions of domain
Version:
0.1
Date:
Mar 18, 1991 - improved the trailing domain list
Version:
0.0
Date:
Feb 19, 1991 - pirated by Erick Engelke
Version:
-1.0 - NCSA code

Definition in file UDP_DOM.C.

Go to the source code of this file.

Functions

void | query_init (struct DNS_query *q, BOOL is_ip6)
Initialise the query header and clear the alternate addr-list.
void | store_alt_address (const void *data, int idx, BOOL is_ip6)
Remember alternate address in dom_a?list[].
int | pack_domain (BYTE *dst, const char *src)
Pack a regular text string into a packed domain name, suitable for the name server.
int | send_query (sock_type *sock, struct DNS_query *q, const char *name, DWORD towho, WORD qtype)
Put together a domain lookup packet and send it.
__inline int | countpaths (const char *pathstring)
__inline const char * | getpath (const char *pathstring, int whichone)
void | extract_cname (const struct DNS_query *q, const char *src, char *dest, size_t max)
Extract the CNAME from a resource record.
int | unpack_domain (const struct DNS_query *q, const BYTE *src, size_t src_size, BYTE *dst, size_t dst_size)
Unpack a received compressed domain name.
int | read_response (const struct DNS_query *q, int len, WORD qtype, void *addr)
Extract the IPv4/v6 address from a response message (A or AAAA record).
__inline BOOL | legal_ident (WORD id, const WORD *cache, int num)
int | lookup_domain (struct DNS_query *q, const char *mname, BOOL add_dom, DWORD nameserver, BOOL *timedout, BOOL is_ip4, void *addr)
DOMAIN based name lookup.
const char * | next_domain (const char *domain, int count)
Given domain and count = 0,1,2,..., return next larger domain or NULL when no more are available.
const char * | server_error (enum DNS_serv_resp err)
Return text for server-side errors.
const char * | client_error (enum DNS_client_code err)
Return text for client-side errors.
const char * | dom_strerror (int err)
Return text for error code (dom_errno).
DWORD | resolve (const char *name)
Convert host name to an address.
int | resolve_ip6 (const char *name, void *addr)

Variables

BOOL | called_from_resolve = FALSE
Hacks to make gethostbyname() and resolve() cooperate.
BOOL | called_from_ghbn = FALSE
char | defaultdomain [MAX_HOSTLEN+1] = "your.domain.com"
The 2 next variables are loaded from WATTCP.CFG file.
char * | def_domain = defaultdomain
int(* | _resolve_hook )(void)
BOOL | _resolve_exit
BOOL | _resolve_timeout
DWORD | dom_ttl
int | dom_errno
char | dom_cname [MAX_HOSTLEN+1]
DWORD | def_nameservers [MAX_NAMESERVERS]
WORD | last_nameserver = 0
UINT | dns_timeout = 0
BOOL | dns_recurse = TRUE
BOOL | dns_do_ipv6 = TRUE
BOOL | dns_do_idna = TRUE
WORD | dns_windns = 0
const char * | loc_domain
DWORD | res_timeout
DWORD | dom_a4list [MAX_ADDRESSES+1]
ip6_address | dom_a6list [MAX_ADDRESSES+1]

Function Documentation

int lookup_domain | ( | struct DNS_query * | q,
 |  | const char * | mname,
 |  | BOOL | add_dom,
 |  | DWORD | nameserver,
 |  | BOOL * | timedout,
 |  | BOOL | is_ip4,
 |  | void * | addr
 | ) | [static]

DOMAIN based name lookup.

Query a domain name server to get an IP number Returns the machine number of the machine record for future reference. Events generated will have this number tagged with them. Returns various negative numbers on error conditions.

if add_dom is nonzero, add default domain. Definition at line 484 of file UDP_DOM.C.

References BYTE, chk_timeout(), dom_strerror(), Random(), read_response(), send_query(), sock_close(), sock_dataready(), sock_fastread(), tcp_tick(), sock_type::udp, UINT, and WORD.

int pack_domain | ( | BYTE * | dst,
 |  | const char * | src
 | ) | [static]

Pack a regular text string into a packed domain name, suitable for the name server.

Returns length or -1 if a labellength is > 63. Definition at line 142 of file UDP_DOM.C.

References BYTE.

int read_response | ( | const struct DNS_query * | q,
 |  | int | len,
 |  | WORD | qtype,
 |  | void * | addr
 | ) | [static]

Extract the IPv4/v6 address from a response message (A or AAAA record).

Returns 0 on fail and sets appropriate status code in `dom_errno'. Returns 1 if okay and if the ip is available, Read upto len bytes from reply.

Note: Our query is echoed in the answer, but 'q' below is not same as we sent in send_query(). Definition at line 362 of file UDP_DOM.C.

References BYTE, DWORD, extract_cname(), ip6_address, store_alt_address(), unpack_domain(), and WORD.

DWORD resolve ( const char * name )

Convert host name to an address.

Returns 0 if name is unresolvable right now. Return value is host-order. Definition at line 756 of file UDP_DOM.C.

References aton(), called_from_resolve, dom_strerror(), DWORD, isaddr(), lookup_domain(), my_ip_addr, next_domain(), query_init(), rip(), set_timeout(), UINT, and WORD.

int send_query | ( | sock_type * | sock,
 |  | struct DNS_query * | q,
 |  | const char * | name,
 |  | DWORD | towho,
 |  | WORD | qtype
 | ) | [static]

Put together a domain lookup packet and send it.

Uses port DOM_DST_PORT (53). Definition at line 191 of file UDP_DOM.C.

References BYTE, pack_domain(), sock_write(), sock_type::udp, udp_open(), and WORD.

int unpack_domain | ( | const struct DNS_query * | q,
 |  | const BYTE * | src,
 |  | size_t | src_size,
 |  | BYTE * | dst,
 |  | size_t | dst_size
 | ) | [static]

Unpack a received compressed domain name.

Handles pointers to continuation domain names.

  • address of query response ('q') is used as the base for the offset of any pointer which is present.
  • returns the number of bytes at 'src' which should be skipped over. Includes the 0-terminator in its length count.
  • returns -1 if the response is munged.
Definition at line 308 of file UDP_DOM.C.

References BYTE.

Generated on Wed Jan 25 15:42:43 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/UDP_DOM.H File Reference

SRC/UDP_DOM.H File Reference

Detailed Description

Definition in file UDP_DOM.H.

Go to the source code of this file.

Data Structures

struct | DNS_head
struct | DNS_query
struct | DNS_resource

Enumerations

enum DNS_serv_resp {
DNS_SRV_OK = 0,
DNS_SRV_FORM,
DNS_SRV_FAIL,
DNS_SRV_NAME,
DNS_SRV_NOTIMPL,
DNS_SRV_REFUSE,
DNS_SRV_MAX = 15
}
enum DNS_client_code {
DNS_CLI_SYSTEM = DNS_SRV_MAX,
DNS_CLI_REFUSE,
DNS_CLI_USERQUIT,
DNS_CLI_NOSERV,
DNS_CLI_TIMEOUT,
DNS_CLI_ILL_RESP,
DNS_CLI_ILL_IDNA,
DNS_CLI_TOOBIG,
DNS_CLI_NOIP,
DNS_CLI_NOIPV6,
DNS_CLI_OTHER,
DNS_CLI_MAX
}

Functions

W32_FUNC DWORD | resolve (const char *name)
Convert host name to an address.
W32_FUNC int | resolve_ip6 (const char *name, void *addr)
W32_FUNC const char * | dom_strerror (int err)
Return text for error code (dom_errno).
int | reverse_lookup_myip (void)
Do a reverse lookup on `my_ip_addr'.
int | reverse_resolve_ip4 (DWORD ipv4, char *result, size_t size)
int | reverse_resolve_ip6 (const void *ipv6, char *result, size_t size)
W32_FUNC DWORD | lookup_host (const char *host, char *ip_str)

Variables

W32_DATA int(* | _resolve_hook )(void)
W32_DATA BOOL | _resolve_exit
W32_DATA BOOL | _resolve_timeout
W32_DATA char | defaultdomain [MAX_HOSTLEN+1]
W32_DATA char * | def_domain
W32_DATA DWORD | def_nameservers [MAX_NAMESERVERS]
W32_DATA WORD | last_nameserver
W32_DATA int | dom_errno
char | dom_cname [MAX_HOSTLEN+1]
DWORD | dom_ttl
BOOL | dns_do_ipv6
BOOL | dns_do_idna
WORD | dns_windns
BOOL | called_from_resolve
Hacks to make gethostbyname() and resolve() cooperate.
BOOL | called_from_ghbn
DWORD | dom_a4list [MAX_ADDRESSES+1]
ip6_address | dom_a6list [MAX_ADDRESSES+1]
W32_DATA UINT | dns_timeout
W32_DATA BOOL | dns_recurse

Function Documentation

W32_FUNC DWORD resolve ( const char * name )

Convert host name to an address.

Returns 0 if name is unresolvable right now. Return value is host-order. Definition at line 756 of file UDP_DOM.C.

int reverse_lookup_myip ( void )

Do a reverse lookup on `my_ip_addr'.

If successfull, replace `hostname' and `def_domain' with returned result. Definition at line 301 of file UDP_REV.C.

References my_ip_addr, and sethostname().

Generated on Wed Jan 25 15:42:44 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/UDP_REV.C File Reference

SRC/UDP_REV.C File Reference

Detailed Description

Reverse DNS lookup

Definition in file UDP_REV.C.

Go to the source code of this file.

Functions

size_t | query_init_ip4 (struct DNS_query *q, DWORD ip)
Fill in the reverse lookup question packet.
BOOL | read_response (sock_type *s, char *name, size_t size)
Read answer and extract host name.
BOOL | reverse_lookup (const struct DNS_query *q, size_t qlen, char *name, size_t size, DWORD nameserver)
Translate an IPv4/IPv6 address into a host name.
int | reverse_lookup_myip (void)
Do a reverse lookup on `my_ip_addr'.
int | do_rresolve (const struct DNS_query *q, size_t qlen, char *result, size_t size)
int | reverse_resolve_ip4 (DWORD ip, char *result, size_t size)
size_t | query_init_ip6 (struct DNS_query *q, const void *addr)
Fill in the reverse lookup question packet.
int | reverse_resolve_ip6 (const void *addr, char *result, size_t size)

Function Documentation

size_t query_init_ip4 | ( | struct DNS_query * | q,
 |  | DWORD | ip
 | ) | [static]

Fill in the reverse lookup question packet.

Return total length of request. Definition at line 59 of file UDP_REV.C.

References BYTE, set_timeout(), and WORD.

size_t query_init_ip6 | ( | struct DNS_query * | q,
 |  | const void * | addr
 | ) | [static]

Fill in the reverse lookup question packet.

Return total length of request.

Todo:
Use "ip6.arpa" bitstring format ?
Definition at line 370 of file UDP_REV.C.

References BYTE, ip6_address, set_timeout(), and WORD.

BOOL read_response | ( | sock_type * | s,
 |  | char * | name,
 |  | size_t | size
 | ) | [static]

Read answer and extract host name.

Return values:
0 | on error (dom_errno = DNS_CLI_ILL_RESP),
1 | on success.
Definition at line 124 of file UDP_REV.C.

References BYTE, sock_fastread(), and WORD.

BOOL reverse_lookup | ( | const struct DNS_query * | q,
 |  | size_t | qlen,
 |  | char * | name,
 |  | size_t | size,
 |  | DWORD | nameserver
 | ) | [static]

Translate an IPv4/IPv6 address into a host name.

Returns 1 on success, 0 on error or timeout. Definition at line 225 of file UDP_REV.C.

References BYTE, chk_timeout(), dom_strerror(), DWORD, read_response(), set_timeout(), sock_close(), sock_dataready(), sock_write(), tcp_tick(), sock_type::udp, and udp_open().

int reverse_lookup_myip ( void )

Do a reverse lookup on `my_ip_addr'.

If successfull, replace `hostname' and `def_domain' with returned result. Definition at line 301 of file UDP_REV.C.

References my_ip_addr, and sethostname().

Generated on Wed Jan 25 15:42:44 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/UFORTIFY.H File Reference

SRC/UFORTIFY.H File Reference

Detailed Description

User options for Fortify.

User options for fortify. Changes to this file require fortify.c to be recompiled, but nothing else.

Definition in file UFORTIFY.H.

Go to the source code of this file.

Generated on Wed Jan 25 15:42:44 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/VERSION.C File Reference

SRC/VERSION.C File Reference

Detailed Description

Return Watt-32 version/capabilities strings.

Definition in file VERSION.C.

Go to the source code of this file.

Functions

const char * | wattcpVersion (void)
const char * | wattcpCapabilities (void)

Variables

const char * | wattcpCopyright = "See COPYRIGHT.H for details"
const char * | capa []
Return compiled-in capabilities.

Generated on Wed Jan 25 15:42:44 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/WATTCP.C File Reference

SRC/WATTCP.C File Reference

Detailed Description

DLL entry-point for HighC.

Definition in file WATTCP.C.

Go to the source code of this file.

Functions

DWORD DllEntryPoint (void *hDll, DWORD reason, void *reserved)

Generated on Wed Jan 25 15:42:44 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/WATTCP.H File Reference

SRC/WATTCP.H File Reference

Detailed Description

Definition in file WATTCP.H.

Go to the source code of this file.

Data Structures

struct | ulong_long
struct | in_Header
struct | in6_Header
struct | ip_Packet
struct | udp_Header
struct | tcp_Header
struct | tcp_PseudoHeader
struct | tcp_PseudoHeader6
struct | IGMP_packet
struct | arp_Header
struct | _udp_Socket
struct | _tcp_Socket
struct | _raw_Socket
struct | _raw6_Socket
union | sock_type
struct | watt_sockaddr

Typedefs

typedef unsigned char | BYTE
typedef unsigned short | WORD
typedef unsigned long | DWORD
typedef unsigned int | UINT
typedef BYTE | eth_address [6]
typedef BYTE | tok_address [6]
typedef BYTE | fddi_address [6]
typedef BYTE | ax25_address [7]
typedef BYTE | arcnet_address
typedef BYTE | ip6_address [16]
typedef int(* | ProtoHandler )(void *sock, const void *data, unsigned len, const void *tcp_pseudo_hdr, const void *udp_hdr)
typedef int(* | UserHandler )(void *sock)
typedef int(* | icmp_upcall )(void *socket, BYTE icmp_type, BYTE icmp_code)
typedef unsigned long long | uint64
our unsigned "long long" type
typedef long long | int64
our signed "long long" type
typedef in_Header | in_Header
typedef in6_Header | in6_Header
typedef ip_Packet | ip_Packet
typedef udp_Header | udp_Header
typedef tcp_Header | tcp_Header
typedef tcp_PseudoHeader | tcp_PseudoHeader
typedef tcp_PseudoHeader6 | tcp_PseudoHeader6
typedef IGMP_packet | IGMP_packet
typedef arp_Header | arp_Header
typedef _udp_Socket | _udp_Socket
typedef _tcp_Socket | _tcp_Socket
typedef _raw_Socket | _raw_Socket
typedef _raw6_Socket | _raw6_Socket
typedef sock_type | sock_type
typedef watt_sockaddr | watt_sockaddr

Typedef Documentation

typedef BYTE arcnet_address

ARCNET address Definition at line 48 of file WATTCP.H.

typedef BYTE ax25_address[7]

AX-25 address Definition at line 47 of file WATTCP.H.

typedef unsigned char BYTE

8 bits Definition at line 34 of file WATTCP.H.

typedef unsigned long DWORD

32 bits Definition at line 36 of file WATTCP.H.

typedef BYTE eth_address[6]

Ether address Definition at line 44 of file WATTCP.H.

typedef BYTE fddi_address[6]

FDDI address Definition at line 46 of file WATTCP.H.

typedef int(* icmp_upcall)(void *socket, BYTE icmp_type, BYTE icmp_code)

64-bit types (compiler dependant). Definition at line 64 of file WATTCP.H.

typedef BYTE ip6_address[16]

IPv6 address Definition at line 49 of file WATTCP.H.

typedef int(* ProtoHandler)(void *sock, const void *data, unsigned len, const void *tcp_pseudo_hdr, const void *udp_hdr)

user-data callback type. Definition at line 55 of file WATTCP.H.

typedef BYTE tok_address[6]

TokenRing address Definition at line 45 of file WATTCP.H.

UINT

16/32 bit Definition at line 37 of file WATTCP.H.

typedef int(* UserHandler)(void *sock)

Callback type for ICMP event. Definition at line 60 of file WATTCP.H.

typedef unsigned short WORD

16 bits Definition at line 35 of file WATTCP.H.

Generated on Wed Jan 25 15:42:44 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/WDPMI.C File Reference

SRC/WDPMI.C File Reference

Detailed Description

DPMI interface for Watcom-type targets.

DOS-extender/DPMI interface for DOS4GW Pro, DOS4G, DOS32A, Pmode/W, CauseWay, EDOS, WDOSX and Borland's POWERPAK (32rtm). Possibly usable with gcc and WDOSX also.

From udplib 1.111 by John Snagel <jslagel@volition-inc.com> and Freek Brysse <frbrysse@vub.ac.be>

11 november, 1997 Ref. http://igweb.vub.ac.be/knights/udplib.html

Heavily changed by G. Vanem <giva@bgnett.no> August 1998

Definition in file WDPMI.C.

Go to the source code of this file.

Functions

void cdecl | cstart_ (void)
void far __loadds | exception_main (void)
BOOL | is_wdosx_or_pmodew (DWORD sign)
BOOL | dpmi_is_wdosx (void)
BOOL | dpmi_is_pmodew (void)
BOOL | dpmi_is_dos32a (void)
BOOL | dpmi_is_dos4gw (void)
BOOL | dpmi_is_causeway (void)
BOOL | dpmi_is_hxdos (void)
const char * | dos4gw_extender_name (void)
int | dpmi_except_handler (exceptionHook exc_func)
void * | dpmi_get_real_vector (int intr)
int | dpmi_get_base_address (WORD sel, DWORD *base)
WORD | dpmi_real_malloc (WORD size, WORD *selector)
int | dpmi_real_free (WORD selector)
int | dpmi_lock_region (void *address, unsigned length)
int | dpmi_unlock_region (void *address, unsigned length)
int | dpmi_real_interrupt (int intr, IREGS *reg)
int | dpmi_real_call_retf (IREGS *reg)
int | real_interrupt (int intr, IREGS *reg)
int | int386 (int intno, union REGS *ireg, union REGS *oreg)
int | int386x (int intno, union REGS *ireg, union REGS *oreg, struct SREGS *sreg)
void | segread (struct SREGS *sreg)
void | SS_TO_DGROUP (void)
void | RESTORE_SS_AND_GO (void)
void | stack_rewind (DWORD start, DWORD base)
BOOL | dpmi_init (void)

Variables

char | _Extender
char | _ExtenderSubtype
WORD | __dpmi_errno = 0
WORD | causeway_ver = 0
BOOL | dos32a_nullptr_chk = 0
FAULT_STRUC | exc_struct
exceptionHook | user_exc_hook = NULL
int | _STACKTOP
DWORD | exc_app_start = 4096UL

Variable Documentation

DWORD exc_app_start = 4096UL [static]

Todo:
find the real application start
Definition at line 621 of file WDPMI.C.

Generated on Wed Jan 25 15:42:44 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/WDPMI.H File Reference

SRC/WDPMI.H File Reference

Detailed Description

Definition in file WDPMI.H.

Go to the source code of this file.

Data Structures

struct | FAULT_STRUC

Typedefs

typedef void(* | exceptionHook )(const struct FAULT_STRUC *)

Functions

BOOL | dpmi_init (void)
WORD | dpmi_real_malloc (WORD size, WORD *sel)
int | dpmi_real_free (WORD selector)
int | dpmi_get_base_address (WORD sel, DWORD *base)
int | dpmi_lock_region (void *address, unsigned length)
int | dpmi_unlock_region (void *address, unsigned length)
void * | dpmi_get_real_vector (int intr)
int | dpmi_real_interrupt (int intr, IREGS *reg)
int | dpmi_real_call_retf (IREGS *reg)
BOOL | dpmi_is_wdosx (void)
BOOL | dpmi_is_pmodew (void)
BOOL | dpmi_is_dos32a (void)
BOOL | dpmi_is_dos4gw (void)
BOOL | dpmi_is_causeway (void)
int | dpmi_except_handler (exceptionHook exc_func)
const char * | dos4gw_extender_name (void)
void | stack_rewind (DWORD start, DWORD base)

Variables

WORD | __dpmi_errno

Generated on Wed Jan 25 15:42:44 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/WINMISC.C File Reference

SRC/WINMISC.C File Reference

Detailed Description

Various stuff for Windows only.

Copyright (c) 2004 Gisle Vanem <giva@bgnett.no>

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. All advertising materials mentioning features or use of this software must display the following acknowledgement: This product includes software developed by Gisle Vanem Bergen, Norway.

THIS SOFTWARE IS PROVIDED BY ME (Gisle Vanem) AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL I OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

Definition in file WINMISC.C.

Go to the source code of this file.

Typedefs

typedef IN WORD | wType
typedef IN WORD IN DWORD | options
typedef IN WORD IN DWORD IN
IP4_ARRAY * 		aipServers
typedef IN WORD IN DWORD IN
IP4_ARRAY IN OUT DNS_RECORD ** 		queryResults
typedef IN WORD IN DWORD IN
IP4_ARRAY IN OUT DNS_RECORD
IN OUT void ** 		reserved
typedef IN DNS_RECORD * | deleteRecords
typedef IN DNS_RECORD IN DWORD
IN HANDLE 		context
typedef IN DNS_RECORD IN DWORD
IN HANDLE OPTIONAL IN IP4_ARRAY * 		serverList
typedef IN DNS_FREE_TYPE | freeType

Functions

typedef | DNS_STATUS (WINAPI *DnsQuery_A_func)(IN const char *name
typedef | void (WINAPI *DnsFree_func)(IN OUT void *data
BOOL | get_win_version (WORD *ver, BOOL *is_win9x)
BOOL | check_gui_app (void)
int | gui_printf (const char *fmt,...)
void | win32_exit (void)
char * | win_strerror (DWORD err)
void | assert_fail_win (const char *file, unsigned line, const char *what)
BOOL | init_winmisc (void)
BOOL | WinDnsQueryCommon (WORD type, const void *what, void *result, size_t size)
BOOL | WinDnsQuery_A4 (const char *name, DWORD *ip)
BOOL | WinDnsQuery_A6 (const char *name, void *ip)
BOOL | WinDnsQuery_PTR4 (DWORD ip, char *name, size_t size)
BOOL | WinDnsQuery_PTR6 (const void *ip, char *name, size_t size)
BOOL | WinDnsCachePut_A4 (const char *name, DWORD ip4)
BOOL | WinDnsCachePut_A6 (const char *name, const void *ip6)
int __stdcall | WSAStartup (WORD version_required, WSADATA *wsa_data)
int __stdcall | WSACleanup (void)
int __stdcall | __WSAFDIsSet (int s, winsock_fd_set *fd)

Variables

CRITICAL_SECTION | _watt_crit_sect
BOOL | _watt_is_win9x = FALSE
BOOL | is_gui_app = FALSE
DnsFree_func | _DnsFree = NULL
DnsQuery_A_func | _DnsQuery_A = NULL
DnsModifyRecordsInSet_A_func | _DnsModifyRecordsInSet_A = NULL
HINSTANCE | windns_mod = NULL

Generated on Wed Jan 25 15:42:44 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/WINPCAP.C File Reference

SRC/WINPCAP.C File Reference

Detailed Description

Packet-driver like interface to WinPcap.

Copyright (c) 2004 Gisle Vanem <giva@bgnett.no>

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. All advertising materials mentioning features or use of this software must display the following acknowledgement: This product includes software developed by Gisle Vanem Bergen, Norway.

THIS SOFTWARE IS PROVIDED BY ME (Gisle Vanem) AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL I OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

Definition in file WINPCAP.C.

Go to the source code of this file.

Functions

BOOL | get_perm_mac_address (void *mac)
BOOL | get_interface_mtu (DWORD *mtu)
BOOL | get_interface_type (WORD *link)
BOOL | get_connected_status (BOOL *is_up)
void | show_link_details (void)
void | set_txmode (const char *value)
Select async (overlapping) tx-mode.
DWORD __stdcall | pkt_recv_thread (void *arg)
Our low-level capture thread.
BOOL | parse_config_pass_1 (void)
WATTCP.CFG parser for "PCAP." keywords in WATTCP.CFG.
BOOL | find_adapter (char *aname, size_t size)
Traverse 'adapters_list' and select 1st device with an IPv4 address.
int | pkt_eth_init (mac_address *mac_addr)
Initialise Packet driver interface.
int | pkt_release (void)
int | pkt_get_addr (mac_address *eth)
Return the MAC address.
int | pkt_set_addr (const void *eth)
Set a new MAC source address.
BOOL | pkt_check_address (DWORD my_ip)
int | pkt_buf_wipe (void)
Clear the receive queue.
int | pkt_waiting (void)
Return number of packets waiting in queue.
void | pkt_free_pkt (const void *pkt)
Release a packet from the receive queue.
pkt_rx_element * | pkt_poll_recv (void)
int | pkt_send (const void *tx, int length)
Send a link-layer frame.
int | pkt_set_rcv_mode (int mode)
Sets the receive mode of the interface.
int | pkt_get_rcv_mode (void)
Gets the receive mode of the interface (can never be mode 0).
int | pkt_get_stats (struct PktStats *stats, struct PktStats *total)
Get PKTDRVR statistics.
DWORD | pkt_dropped (void)
Return number of packets dropped.
int | pkt_get_mtu (void)
Return PKTDRVR maximum-transmit-units (MTU).
const char * | pkt_strerror (int code)
Return textual error representing error-code.
int | pkt_get_multicast_list (mac_address *listbuf, int *len)
Gets the current list of multicast addresses from the PKTDRVR.
int | pkt_set_multicast_list (const void *listbuf, int len)
Sets the list of multicast addresses for which the PKTDRVR is responsible.
BOOL | get_interface_speed (DWORD *speed)
BOOL | get_real_media (int *media)
BOOL | ndis_set_loopback (BOOL enable)
int | pkt_get_api_ver (DWORD *ver)
Return version of spec.
int | pkt_get_drvr_ver (DWORD *ver)
Return version of PKTDRVR.

Variables

WORD | _pktdevclass = PDCLASS_UNKNOWN
WORD | _pkt_ip_ofs = 0
BOOL | _pktserial = FALSE
int | _pkt_errno = 0
int | _pkt_rxmode = RXMODE_DEFAULT
active receive mode
int | _pkt_rxmode0 = -1
startup receive mode
int | _pkt_forced_rxmode = -1
wattcp.cfg Rx mode
char | _pktdrvrname [MAX_VALUELEN+1] = ""
char | _pktdrvr_descr [MAX_VALUELEN+1] = ""
pkt_info * | _pkt_inf = NULL
module data that will be locked
int | pkt_num_rx_bufs = RX_BUFS
DWORD | num_tx_pkt = 0UL
DWORD | num_tx_bytes = 0UL
DWORD | num_tx_errors = 0UL
DWORD | num_rx_bytes = 0UL
DWORD | pkt_drop_cnt = 0UL
int | pkt_txretries = 2
int | thr_realtime = 0
BOOL | thr_stopped = FALSE
FILE * | dump_file = NULL
char | dump_fname [MAX_PATHLEN] = "$(TEMP)\\winpcap_dump.txt"
const struct search_list | logical_media []
const struct search_list | phys_media []

Function Documentation

BOOL find_adapter | ( | char * | aname,
 |  | size_t | size
 | ) | [static]

Traverse 'adapters_list' and select 1st device with an IPv4 address.

Assuming that device is a physical adapter we can use.

Todo:
Use IPhlpAPI function to return list of adapters
Definition at line 182 of file WINPCAP.C.

References npf_if_addr::IPAddress, ADAPTER_INFO::Name, ADAPTER_INFO::NetworkAddresses, ADAPTER_INFO::Next, ADAPTER_INFO::NNetworkAddresses, and StrLcpy().

int pkt_eth_init ( mac_address * mac_addr )

Initialise Packet driver interface.

<

Todo:
Support Win-9x too
Definition at line 213 of file WINPCAP.C.

References _pkt_errno, _pkt_inf, _pkt_ip_ofs, _pkt_rxmode, _pkt_rxmode0, _pktdevclass, _watt_no_config, pkt_info::adapter, pkt_info::adapter_info, DWORD, ExpandVarStr(), find_adapter(), fopen_excl(), pkt_info::handle, pkt_info::is_serial, pkt_info::npf_buf, pkt_info::npf_buf_size, parse_config_pass_1(), pkt16_drvr_init(), pkt_get_addr(), pkt_get_rcv_mode(), pkt_info::pkt_ip_ofs, pkt_info::pkt_queue, pkt_recv_thread(), pkt_release(), pkt_set_rcv_mode(), pkt_info::pkt_type_ofs, pkt_info::recv_thread, pkt_info::rx_buf, and StrLcpy().

void pkt_free_pkt ( const void * pkt )

Release a packet from the receive queue.

If USE_FAST_PKT, pkt has already been free'd. Just update drop count. Definition at line 536 of file WINPCAP.C.

References _pkt_inf, _pkt_ip_ofs, DWORD, and pkt_info::pkt_queue.

int pkt_get_api_ver ( DWORD * ver )

Return version of spec.

this PKTDRVR conforms to.

Return values:
-1 on error. Return major version in upper 8 bit, minor in lower.
Definition at line 1143 of file WINPCAP.C.

References _pkt_inf, pkt_info::adapter, DWORD, and WORD.

int pkt_get_mtu ( void )

Return PKTDRVR maximum-transmit-units (MTU).

Note:
This includes length of MAC-header.
Definition at line 880 of file WINPCAP.C.

References _pktdevclass, and DWORD.

int pkt_get_multicast_list | ( | mac_address * | listbuf,
 |  | int * | len
 | ) |

Gets the current list of multicast addresses from the PKTDRVR.

  • listbuf is the buffer into which the list is placed
  • len on input: length of listbuf on output: length of list returned
Return values:
0 | upon error - _pkt_errno is set
1 | if retrieval was successful,
Definition at line 899 of file WINPCAP.C.

References _pkt_errno, _pktdevlevel, _pktserial, get_rmode_data(), and WORD.

int pkt_get_rcv_mode ( void )

Gets the receive mode of the interface (can never be mode 0).

Return values:
!0 | Okay - _pkt_errno is 0, _pkt_rxmode and retval is current mode.
0 | Error - _pkt_errno is set.
_pkt_rxmode is one of the following modes: (upon successful return)
  • 1 - turn off receiver
  • 2 - receive only packets sent to this interface
  • 3 - mode 2 plus broadcast packets (default)
  • 4 - mode 3 plus limited multicast packets
  • 5 - mode 3 plus all multicast packets
  • 6 - all packets (a.k.a promiscuous mode)
Definition at line 772 of file WINPCAP.C.

References _pkt_errno, _pkt_inf, _pkt_rxmode, _pktdevlevel, _pktserial, pkt_info::adapter, DWORD, and pkt_info::handle.

int pkt_get_stats | ( | struct PktStats * | stats,
 |  | struct PktStats * | total
 | ) |

Get PKTDRVR statistics.

Return both 'stats' for current session and 'total' statistics since driver loaded. Definition at line 804 of file WINPCAP.C.

References _pkt_inf, pkt_info::adapter, DWORD, get_rmode_data(), and pkt_info::handle.

DWORD __stdcall pkt_recv_thread ( void * arg )

Our low-level capture thread.

Loop waiting for packet(s) in PacketReceivePacket(). In _pkt_release() the receive event-handle (adapter->Readvent) is set. This causes WaitForSingleObject() in PacketReceivePacket() to return. It is vital that the ADAPTER object isn't deallocated before PacketReceivePacket() returns.

The return-value is > 0 if thread exited on it's own. Otherwise it is 0 (from GetExitCodeThread). Definition at line 580 of file WINPCAP.C.

References _pkt_inf, pkt_info::adapter, PACKET::Buffer, BYTE, DWORD, pkt_info::error, PACKET::Length, pkt_info::npf_buf, pkt_info::npf_buf_size, macstat::num_too_large, pkt_info::pkt_queue, pkt_info::stop_thread, and PACKET::ulBytesReceived.

int pkt_release ( void )

Todo:
We might be called between 1st and 2nd packet-driver upcall. Need to wait for 2nd upcall to finish or else freeing the RMCB too early could cause a crash or a stuck PKTDRVR.
Definition at line 412 of file WINPCAP.C.

References _pkt_inf, _watt_fatal_error, pkt_info::adapter, DWORD, pkt_info::handle, pkt_info::npf_buf, pkt_release_handle(), pkt_reset_handle(), pkt_info::recv_thread, release_real_mem(), and pkt_info::stop_thread.

int pkt_send | ( | const void * | tx,
 |  | int | length
 | ) |

Send a link-layer frame.

For PPP/SLIP 'tx' contains no MAC-header. For EtherNet, Token-Ring, ARCNET and FDDI, 'tx' contains the complete frame.

Todo:
Change this so that we doesn't retry if the driver was stuck for "too long". I've seen drivers using approx. 100 msec on each iteration below. Retrying if the driver is stuck is not worth the time.

Todo:
estimate max time this should take
Definition at line 698 of file WINPCAP.C.

References _pkt_errno, _pkt_inf, pkt_info::adapter, PACKET::Buffer, BYTE, chk_timeout(), DWORD, PACKET::Length, macstat::num_tx_err, macstat::num_tx_retry, macstat::num_tx_timeout, pkt_tx_buf(), set_timeout(), pkt_info::use_near_ptr, Wait(), and WORD.

int pkt_set_multicast_list | ( | const void * | listbuf,
 |  | int | len
 | ) |

Sets the list of multicast addresses for which the PKTDRVR is responsible.

  • listbuf is the buffer containing the list
  • len is the length of listbuf
Return values:
0 | upon error - _pkt_errno is set
1 | if set was successful
Definition at line 908 of file WINPCAP.C.

References _pkt_errno, _pktdevlevel, _pktserial, and WORD.

int pkt_set_rcv_mode ( int mode )

Sets the receive mode of the interface.

mode is one of the following modes:

  • 1 - turn off receiver
  • 2 - receive only packets sent to this interface
  • 3 - mode 2 plus broadcast packets <default>
  • 4 - mode 3 plus limited multicast packets
  • 5 - mode 3 plus all multicast packets
  • 6 - all packets (AKA promiscuous mode)

Return values:
0 | - upon error - _pkt_errno is set
1 | - if the mode was set successfully
Definition at line 739 of file WINPCAP.C.

References _pkt_errno, _pkt_inf, _pkt_rxmode, _pktdevlevel, _pktserial, pkt_info::adapter, DWORD, and pkt_info::handle.

void set_txmode ( const char * value ) [static]

Select async (overlapping) tx-mode.

NOT YET. Definition at line 563 of file WINPCAP.C.

Variable Documentation

const struct search_list logical_media[] [static]

Initial value:

 {
     { -1,                   "Unknown" },
     { NdisMedium802_3,      "802.3" },
     { NdisMedium802_5,      "802.5" },
     { NdisMediumFddi,       "FDDI" },
     { NdisMediumWan,        "WAN" },
     { NdisMediumLocalTalk,  "LocalTalk" },
     { NdisMediumDix,        "DIX" },
     { NdisMediumArcnetRaw,  "ArcNet (raw)" },
     { NdisMediumArcnet878_2,"ArcNet (878.2)" },
     { NdisMediumAtm,        "ATM" },
     { NdisMediumWirelessWan,"WiFi" },
     { NdisMediumIrda,       "IrDA" },
     { NdisMediumNull,       "Null?!" },
     { NdisMediumCHDLC,      "CHDLC" },
     { NdisMediumPPPSerial,  "PPP-ser" }
    }
Definition at line 113 of file WINPCAP.C.

const struct search_list phys_media[] [static]

Initial value:

 {
     { ND_PHY_WirelessLan,  "Wireless LAN" },
     { ND_PHY_CableModem,   "Cable"        },
     { ND_PHY_PhoneLine,    "Phone"        },
     { ND_PHY_PowerLine,    "PowerLine"    },
     { ND_PHY_DSL,          "DSL"          },
     { ND_PHY_FibreChannel, "Fibre"        },
     { ND_PHY_1394,         "IEEE1394"     },
     { ND_PHY_WirelessWan,  "Wireless WAN" }
   }
Definition at line 131 of file WINPCAP.C.

Generated on Wed Jan 25 15:42:44 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/WINPCAP.H File Reference

SRC/WINPCAP.H File Reference

Detailed Description

Only included on Win32

Definition in file WINPCAP.H.

Go to the source code of this file.

Data Structures

struct | pkt_info
Placeholder for vital data accessed by capture thread. More...

Enumerations

enum ReceiveModes {
RXMODE_OFF = 0x00,
RXMODE_DIRECT = 0x01,
RXMODE_MULTICAST1 = 0x02,
RXMODE_MULTICAST2 = 0x04,
RXMODE_BROADCAST = 0x08,
RXMODE_PROMISCOUS = 0x20,
RXMODE_ALL_LOCAL = 0x80
}

Functions

W32_FUNC int | pkt_eth_init (mac_address *eth)
Initialise Packet driver interface.
W32_FUNC int | pkt_release (void)
W32_FUNC int | pkt_reset_handle (void *handle)
W32_FUNC int | pkt_send (const void *tx, int length)
Send a link-layer frame.
W32_FUNC int | pkt_buf_wipe (void)
Clear the receive queue.
W32_FUNC void | pkt_free_pkt (const void *pkt)
Release a packet from the receive queue.
W32_FUNC int | pkt_waiting (void)
Return number of packets waiting in queue.
W32_FUNC int | pkt_set_addr (const void *eth)
Set a new MAC source address.
W32_FUNC int | pkt_get_addr (mac_address *eth)
Return the MAC address.
W32_FUNC int | pkt_get_mtu (void)
Return PKTDRVR maximum-transmit-units (MTU).
W32_FUNC int | pkt_get_drvr_ver (DWORD *ver)
Return version of PKTDRVR.
W32_FUNC int | pkt_get_api_ver (DWORD *ver)
Return version of spec.
W32_FUNC int | pkt_set_rcv_mode (int mode)
Sets the receive mode of the interface.
W32_FUNC int | pkt_get_rcv_mode (void)
Gets the receive mode of the interface (can never be mode 0).
W32_FUNC BOOL | pkt_check_address (DWORD my_ip)
pkt_rx_element * | pkt_poll_recv (void)
int | pkt_get_multicast_list (mac_address *listbuf, int *len)
Gets the current list of multicast addresses from the PKTDRVR.
int | pkt_set_multicast_list (const void *listbuf, int len)
Sets the list of multicast addresses for which the PKTDRVR is responsible.
W32_FUNC int | pkt_get_stats (struct PktStats *stats, struct PktStats *total)
Get PKTDRVR statistics.

Variables

W32_DATA char | _pktdrvr_descr []
W32_DATA struct pkt_info * | _pkt_inf
module data that will be locked

Enumeration Type Documentation

enum ReceiveModes

Enumeration values:
RXMODE_OFF | possible to turn off?
RXMODE_DIRECT | NDIS_PACKET_TYPE_DIRECTED.
RXMODE_MULTICAST1 | NDIS_PACKET_TYPE_MULTICAST.
RXMODE_MULTICAST2 | NDIS_PACKET_TYPE_ALL_MULTICAST.
RXMODE_BROADCAST | NDIS_PACKET_TYPE_BROADCAST.
RXMODE_PROMISCOUS | NDIS_PACKET_TYPE_PROMISCUOUS.
RXMODE_ALL_LOCAL | NDIS_PACKET_TYPE_ALL_LOCAL (direct+bc+mc1).
Definition at line 35 of file WINPCAP.H.

Function Documentation

W32_FUNC int pkt_eth_init ( mac_address * mac_addr )

Initialise Packet driver interface.

<

Todo:
Support Win-9x too
Definition at line 1499 of file PCPKT.C.

References _pkt_errno, _pkt_inf, _pkt_ip_ofs, _pkt_rxmode, _pkt_rxmode0, _pktdevclass, _watt_no_config, pkt_info::adapter, pkt_info::adapter_info, DWORD, ExpandVarStr(), find_adapter(), fopen_excl(), pkt_info::handle, pkt_info::is_serial, pkt_info::npf_buf, pkt_info::npf_buf_size, parse_config_pass_1(), pkt16_drvr_init(), pkt_get_addr(), pkt_get_rcv_mode(), pkt_info::pkt_ip_ofs, pkt_info::pkt_queue, pkt_recv_thread(), pkt_release(), pkt_set_rcv_mode(), pkt_info::pkt_type_ofs, pkt_info::recv_thread, pkt_info::rx_buf, and StrLcpy().

W32_FUNC void pkt_free_pkt ( const void * pkt )

Release a packet from the receive queue.

If USE_FAST_PKT, pkt has already been free'd. Just update drop count. Definition at line 1381 of file PCPKT.C.

References _pkt_inf, _pkt_ip_ofs, DWORD, and pkt_info::pkt_queue.

W32_FUNC int pkt_get_api_ver ( DWORD * ver )

Return version of spec.

this PKTDRVR conforms to.

Return values:
-1 on error. Return major version in upper 8 bit, minor in lower.
Definition at line 508 of file PCPKT.C.

References _pkt_inf, pkt_info::adapter, DWORD, and WORD.

W32_FUNC int pkt_get_mtu ( void )

Return PKTDRVR maximum-transmit-units (MTU).

Note:
This includes length of MAC-header.
Definition at line 478 of file PCPKT.C.

References _pktdevclass, and DWORD.

int pkt_get_multicast_list | ( | mac_address * | listbuf,
 |  | int * | len
 | ) |

Gets the current list of multicast addresses from the PKTDRVR.

  • listbuf is the buffer into which the list is placed
  • len on input: length of listbuf on output: length of list returned
Return values:
0 | upon error - _pkt_errno is set
1 | if retrieval was successful,
Definition at line 2086 of file PCPKT.C.

References _pkt_errno, _pktdevlevel, _pktserial, get_rmode_data(), and WORD.

W32_FUNC int pkt_get_rcv_mode ( void )

Gets the receive mode of the interface (can never be mode 0).

Return values:
!0 | Okay - _pkt_errno is 0, _pkt_rxmode and retval is current mode.
0 | Error - _pkt_errno is set.
_pkt_rxmode is one of the following modes: (upon successful return)
  • 1 - turn off receiver
  • 2 - receive only packets sent to this interface
  • 3 - mode 2 plus broadcast packets (default)
  • 4 - mode 3 plus limited multicast packets
  • 5 - mode 3 plus all multicast packets
  • 6 - all packets (a.k.a promiscuous mode)
Definition at line 2048 of file PCPKT.C.

References _pkt_errno, _pkt_inf, _pkt_rxmode, _pktdevlevel, _pktserial, pkt_info::adapter, DWORD, and pkt_info::handle.

W32_FUNC int pkt_get_stats | ( | struct PktStats * | stats,
 |  | struct PktStats * | total
 | ) |

Get PKTDRVR statistics.

Return both 'stats' for current session and 'total' statistics since driver loaded. Definition at line 1275 of file PCPKT.C.

References _pkt_inf, pkt_info::adapter, DWORD, get_rmode_data(), and pkt_info::handle.

W32_FUNC int pkt_release ( void )

Todo:
We might be called between 1st and 2nd packet-driver upcall. Need to wait for 2nd upcall to finish or else freeing the RMCB too early could cause a crash or a stuck PKTDRVR.
Definition at line 808 of file PCPKT.C.

References _pkt_inf, _watt_fatal_error, pkt_info::adapter, DWORD, pkt_info::handle, pkt_info::npf_buf, pkt_release_handle(), pkt_reset_handle(), pkt_info::recv_thread, release_real_mem(), and pkt_info::stop_thread.

W32_FUNC int pkt_send | ( | const void * | tx,
 |  | int | length
 | ) |

Send a link-layer frame.

For PPP/SLIP 'tx' contains no MAC-header. For EtherNet, Token-Ring, ARCNET and FDDI, 'tx' contains the complete frame.

Todo:
Change this so that we doesn't retry if the driver was stuck for "too long". I've seen drivers using approx. 100 msec on each iteration below. Retrying if the driver is stuck is not worth the time.

Todo:
estimate max time this should take
Definition at line 1060 of file PCPKT.C.

References _pkt_errno, _pkt_inf, pkt_info::adapter, PACKET::Buffer, BYTE, chk_timeout(), DWORD, PACKET::Length, macstat::num_tx_err, macstat::num_tx_retry, macstat::num_tx_timeout, pkt_tx_buf(), set_timeout(), pkt_info::use_near_ptr, Wait(), and WORD.

int pkt_set_multicast_list | ( | const void * | listbuf,
 |  | int | len
 | ) |

Sets the list of multicast addresses for which the PKTDRVR is responsible.

  • listbuf is the buffer containing the list
  • len is the length of listbuf
Return values:
0 | upon error - _pkt_errno is set
1 | if set was successful
Definition at line 2133 of file PCPKT.C.

References _pkt_errno, _pktdevlevel, _pktserial, and WORD.

W32_FUNC int pkt_set_rcv_mode ( int mode )

Sets the receive mode of the interface.

mode is one of the following modes:

  • 1 - turn off receiver
  • 2 - receive only packets sent to this interface
  • 3 - mode 2 plus broadcast packets <default>
  • 4 - mode 3 plus limited multicast packets
  • 5 - mode 3 plus all multicast packets
  • 6 - all packets (AKA promiscuous mode)

Return values:
0 | - upon error - _pkt_errno is set
1 | - if the mode was set successfully
Definition at line 2004 of file PCPKT.C.

References _pkt_errno, _pkt_inf, _pkt_rxmode, _pktdevlevel, _pktserial, pkt_info::adapter, DWORD, and pkt_info::handle.

Generated on Wed Jan 25 15:42:44 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/X32VM.C File Reference

SRC/X32VM.C File Reference

Detailed Description

FlashTek DOS extender interface.

A Pharlap-like interface for FlashTek's X32VM DOS extender Currently this only supports the Digital Mars compiler.

by G. Vanem <giva@bgnett.no> July 2002

Definition in file X32VM.C.

Go to the source code of this file.

Data Structures

struct | RMCB_record

Typedefs

typedef RMCB_record | RMCB_record

Enumerations

enum ReturnType {
RETF = 0xCB,
IRET = 0xCF
}

Functions

void __far | PmodeGlue (int taskIndex)
void | PmGlueEnd (void)
void | _dx_rmiv_get (int int_no, REALPTR *handler)
void | _dx_rmiv_set (int int_no, REALPTR handler)
void | _dx_pmiv_get (int int_no, FARPTR *handler)
void | _dx_apmiv_set (int int_no, FARPTR handler)
void | _dx_real_int (int int_no, SWI_REGS *regs)
int | _dx_call_real (REALPTR proc, RMC_BLK *rm_reg, DWORD count,...)
void | _dx_rmlink_get (REALPTR *cback, REALPTR *rm_cbuf, DWORD *rm_cbuf_size, void _far **pm_cbuf)
int | _dx_real_above (int para_count, WORD *para, WORD *largest)
int | _dx_real_free (WORD seg)
int | _dx_real_alloc (int para_count, WORD *para, WORD *largest)
int | _dx_lock_pgs (const void _far *addr, int len)
int | _dx_lock_pgsn (const void *addr, int len)
int | _dx_ulock_pgsn (const void *addr, int len)
void | ReadRealMem (void *buf, REALPTR rp, unsigned len)
void | WriteRealMem (REALPTR rp, const void *src, int len)
void | FillRealMem (REALPTR rp, char val, int len)
void | PokeRealWord (REALPTR rp, WORD val)
void | stack_rewind (DWORD start, DWORD base)
REALPTR | normalize (REALPTR rp)
REALPTR | _dx_alloc_rmode_wrapper (pmodeHook pmHook, int len, int stack_size, ReturnType returnType)
void | _dx_free_rmode_wrapper (REALPTR dos_addr)
REALPTR | _dx_alloc_rmode_wrapper_retf (pmodeHook pmHook, rmodeHook rmHook, int len, int stack_size)
REALPTR | _dx_alloc_rmode_wrapper_iret (pmodeHook pmHook, int stack_size)
void __far | PmodeGlue (struct RMCB_record *task_ptr)

Variables

char | num_wrappers = 0
DWORD | exc_app_start = 4096
RMCB_record | rmcb [MAX_WRAPPERS]

Function Documentation

int _dx_real_alloc | ( | int | para_count,
 |  | WORD * | para,
 |  | WORD * | largest
 | ) |

<

Todo:
Definition at line 233 of file X32VM.C.

References WORD.

void PmGlueEnd ( void ) [static]

Todo:
Support 32-bit Watcom with X32VM
Definition at line 619 of file X32VM.C.

Variable Documentation

struct RMCB_record rmcb[MAX_WRAPPERS] [static]

Todo:
find the real application start
Definition at line 47 of file X32VM.C.

Generated on Wed Jan 25 15:42:44 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/X32VM.H File Reference

SRC/X32VM.H File Reference

Detailed Description

Definition in file X32VM.H.

Go to the source code of this file.

Data Structures

struct | SWI_REGS
struct | RMC_BLK
struct | RMI_BLK

Typedefs

typedef SWI_REGS | SWI_REGS
typedef RMC_BLK | RMC_BLK
typedef void(* | pmodeHook )(SWI_REGS *)
typedef void(* | rmodeHook )(void)

Functions

void | _dx_rmiv_get (int int_no, REALPTR *handler)
void | _dx_rmiv_set (int int_no, REALPTR handler)
void | _dx_pmiv_get (int int_no, FARPTR *handler)
void | _dx_apmiv_set (int int_no, FARPTR handler)
void | _dx_real_int (int int_no, SWI_REGS *regs)
int | _dx_real_free (WORD segment)
int | _dx_real_above (int paras, WORD *para, WORD *largest)
int | _dx_real_alloc (int paras, WORD *para, WORD *largest)
int | _dx_call_real (REALPTR proc, RMC_BLK *rm_reg, DWORD count,...)
int | _dx_lock_pgs (const void _far *addr, int len)
int | _dx_lock_pgsn (const void *addr, int len)
int | _dx_ulock_pgsn (const void *addr, int len)
void | _dx_rmlink_get (REALPTR *cback, REALPTR *rm_cbuf, DWORD *rm_cbuf_size, void _far **pm_cbuf)
REALPTR | _dx_alloc_rmode_wrapper_retf (pmodeHook pmHook, rmodeHook rmHook, int len, int stack_size)
REALPTR | _dx_alloc_rmode_wrapper_iret (pmodeHook pmHook, int stack_size)
void | _dx_free_rmode_wrapper (REALPTR dosAddr)
void | ReadRealMem (void *buf, REALPTR rp, unsigned len)
void | WriteRealMem (REALPTR rp, const void *src, int size)
void | PokeRealWord (REALPTR rp, WORD val)
WORD | PeekRealWord (REALPTR rp)
DWORD | PeekRealDWord (REALPTR rp)
void | stack_rewind (DWORD start, DWORD base)

Variables

UINT cdecl | _x386_stacklow

Function Documentation

int _dx_real_alloc | ( | int | para_count,
 |  | WORD * | para,
 |  | WORD * | largest
 | ) |

<

Todo:
Definition at line 233 of file X32VM.C.

References WORD.

Generated on Wed Jan 25 15:42:44 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/ERR.H Source File

inc/ERR.H

Go to the documentation of this file.
00001
00005 #ifndef __SYS_WERRNO_H
00006 #include <sys/werrno.h>
00007 #endif
00008
Generated on Wed Jan 25 15:42:32 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/NETDB.H Source File

inc/NETDB.H

Go to the documentation of this file.
00001
00005 /*-
00006  * Copyright (c) 1980, 1983, 1988, 1993
00007  *      The Regents of the University of California.  All rights reserved.
00008  *
00009  * Redistribution and use in source and binary forms, with or without
00010  * modification, are permitted provided that the following conditions
00011  * are met:
00012  * 1. Redistributions of source code must retain the above copyright
00013  *    notice, this list of conditions and the following disclaimer.
00014  * 2. Redistributions in binary form must reproduce the above copyright
00015  *    notice, this list of conditions and the following disclaimer in the
00016  *    documentation and/or other materials provided with the distribution.
00017  * 3. All advertising materials mentioning features or use of this software
00018  *    must display the following acknowledgement:
00019  *      This product includes software developed by the University of
00020  *      California, Berkeley and its contributors.
00021  * 4. Neither the name of the University nor the names of its contributors
00022  *    may be used to endorse or promote products derived from this software
00023  *    without specific prior written permission.
00024  *
00025  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
00026  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00027  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00028  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
00029  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00030  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00031  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00032  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00033  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00034  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00035  * SUCH DAMAGE.
00036  *
00037  *      @(#)netdb.h     8.1 (Berkeley) 6/2/93
00038  *      $Id: netdb.h,v 1.5 1996/08/29 20:00:56 peter Exp $
00039  * -
00040  * Portions Copyright (c) 1993 by Digital Equipment Corporation.
00041  *
00042  * Permission to use, copy, modify, and distribute this software for any
00043  * purpose with or without fee is hereby granted, provided that the above
00044  * copyright notice and this permission notice appear in all copies, and that
00045  * the name of Digital Equipment Corporation not be used in advertising or
00046  * publicity pertaining to distribution of the document or software without
00047  * specific, written prior permission.
00048  *
00049  * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
00050  * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
00051  * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
00052  * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
00053  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
00054  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
00055  * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
00056  * SOFTWARE.
00057  * -
00058  * --Copyright--
00059  */
00060
00061 #ifndef __NETDB_H
00062 #define __NETDB_H
00063
00064 #ifndef _PATH_HEQUIV
00065 #define _PATH_HEQUIV    "/etc/hosts.equiv"
00066 #endif
00067
00068 #ifndef _PATH_HOSTS
00069 #define _PATH_HOSTS     "/etc/hosts"
00070 #endif
00071
00072 #ifndef _PATH_NETWORKS
00073 #define _PATH_NETWORKS  "/etc/networks"
00074 #endif
00075
00076 #ifndef _PATH_PROTOCOLS
00077 #define _PATH_PROTOCOLS "/etc/protocols"
00078 #endif
00079
00080 #ifndef _PATH_SERVICES
00081 #define _PATH_SERVICES  "/etc/services"
00082 #endif
00083
00084 #ifndef __SYS_W32API_H
00085 #include <sys/w32api.h>
00086 #endif
00087
00088 #ifndef __SYS_SOCKET_H
00089 #include <sys/socket.h> /* struct sockaddr */
00090 #endif
00091
00092 #ifndef __SYS_CDEFS_H
00093 #include <sys/cdefs.h>
00094 #endif
00095
00096
00097 /*
00098  * Structures returned by network data base library.  All addresses are
00099  * supplied in host order, and returned in network order (suitable for
00100  * use in system calls).
00101  */
00102 struct hostent {
00103         char    *h_name;        /* official name of host */
00104         char    **h_aliases;    /* alias list */
00105         int     h_addrtype;     /* host address type */
00106         int     h_length;       /* length of address */
00107         char    **h_addr_list;  /* list of addresses from name server */
00108 #define h_addr  h_addr_list[0]  /* address, for backward compatiblity */
00109 };
00110
00111 /*
00112  * Assumption here is that a network number
00113  * fits in 32 bits -- probably a poor one.
00114  */
00115 struct netent {
00116        char            *n_name;        /* official name of net */
00117        char            **n_aliases;    /* alias list */
00118        int             n_addrtype;     /* net address type */
00119        unsigned long   n_net;          /* network # */
00120      };
00121
00122 struct servent {
00123        char    *s_name;        /* official service name */
00124        char    **s_aliases;    /* alias list */
00125        int     s_port;         /* port # */
00126        char    *s_proto;       /* protocol to use */
00127      };
00128
00129 struct protoent {
00130        char    *p_name;        /* official protocol name */
00131        char    **p_aliases;    /* alias list */
00132        int     p_proto;        /* protocol # */
00133      };
00134
00135 struct addrinfo {
00136        int     ai_flags;       /* AI_PASSIVE, AI_CANONNAME */
00137        int     ai_family;      /* PF_xxx */
00138        int     ai_socktype;    /* SOCK_xxx */
00139        int     ai_protocol;    /* 0 or IPPROTO_xxx for IPv4 and IPv6 */
00140        int     ai_addrlen;     /* length of ai_addr */
00141        char   *ai_canonname;   /* canonical name for hostname */
00142        struct sockaddr  *ai_addr; /* binary address */
00143        struct addrinfo  *ai_next; /* next structure in linked list */
00144      };
00145
00146 /*
00147  * Error return codes from gethostbyname() and gethostbyaddr()
00148  * (left in extern int h_errno).
00149  */
00150 W32_DATA int h_errno;
00151
00152 #define NETDB_INTERNAL  -1      /* see errno */
00153 #define NETDB_SUCCESS   0       /* no problem */
00154 #define HOST_NOT_FOUND  1       /* Authoritative Answer Host not found */
00155 #define TRY_AGAIN       2       /* Non-Authoritive Host not found, or SERVERFAIL */
00156 #define NO_RECOVERY     3       /* Non recoverable errors, FORMERR, REFUSED, NOTIMP */
00157 #define NO_DATA         4       /* Valid name, no data record of requested type */
00158 #define NO_ADDRESS      NO_DATA /* no address, look for MX record */
00159
00160
00161 /*
00162  * Error return codes from getaddrinfo()
00163  */
00164 #define EAI_ADDRFAMILY   1  /* address family for hostname not supported */
00165 #define EAI_AGAIN        2  /* temporary failure in name resolution */
00166 #define EAI_BADFLAGS     3  /* invalid value for ai_flags */
00167 #define EAI_FAIL         4  /* non-recoverable failure in name resolution */
00168 #define EAI_FAMILY       5  /* ai_family not supported */
00169 #define EAI_MEMORY       6  /* memory allocation failure */
00170 #define EAI_NODATA       7  /* no address associated with hostname */
00171 #define EAI_NONAME       8  /* hostname nor servname provided, or not known */
00172 #define EAI_SERVICE      9  /* servname not supported for ai_socktype */
00173 #define EAI_SOCKTYPE    10  /* ai_socktype not supported */
00174 #define EAI_SYSTEM      11  /* system error returned in errno */
00175 #define EAI_BADHINTS    12
00176 #define EAI_PROTOCOL    13
00177 #define EAI_MAX         14
00178
00179 /*
00180  * Flag values for getaddrinfo()
00181  */
00182 #define AI_PASSIVE      0x00000001 /* get address to use bind() */
00183 #define AI_CANONNAME    0x00000002 /* fill ai_canonname */
00184 #define AI_NUMERICHOST  0x00000004 /* prevent name resolution */
00185
00186 /* valid flags for addrinfo
00187  */
00188 #define AI_MASK         (AI_PASSIVE | AI_CANONNAME | AI_NUMERICHOST)
00189
00190 #define AI_ALL          0x00000100 /* IPv6 and IPv4-mapped (with AI_V4MAPPED) */
00191 #define AI_V4MAPPED_CFG 0x00000200 /* accept IPv4-mapped if kernel supports */
00192 #define AI_ADDRCONFIG   0x00000400 /* only if any address is assigned */
00193 #define AI_V4MAPPED     0x00000800 /* accept IPv4-mapped IPv6 address */
00194
00195 /* special recommended flags for getipnodebyname
00196  */
00197 #define AI_DEFAULT      (AI_V4MAPPED_CFG | AI_ADDRCONFIG)
00198
00199 /*
00200  * Constants for getnameinfo()
00201  */
00202 #define NI_MAXHOST      1025
00203 #define NI_MAXSERV      32
00204
00205 /*
00206  * Flag values for getnameinfo()
00207  */
00208 #define NI_NOFQDN       0x00000001
00209 #define NI_NUMERICHOST  0x00000002
00210 #define NI_NAMEREQD     0x00000004
00211 #define NI_NUMERICSERV  0x00000008
00212 #define NI_DGRAM        0x00000010
00213 #define NI_WITHSCOPEID  0x00000020
00214
00215 /*
00216  * Scope delimit character
00217  */
00218 #define SCOPE_DELIMITER '%'
00219
00220 __BEGIN_DECLS
00221
00222 W32_FUNC void              W32_CALL endhostent     (void);
00223 W32_FUNC void              W32_CALL endnetent      (void);
00224 W32_FUNC void              W32_CALL endprotoent    (void);
00225 W32_FUNC void              W32_CALL endservent     (void);
00226
00227 W32_FUNC struct hostent  * W32_CALL gethostbyaddr  (const char *, int, int);
00228 W32_FUNC struct hostent  * W32_CALL gethostbyname  (const char *);
00229 W32_FUNC struct hostent  * W32_CALL gethostbyname2 (const char *, int af);
00230 W32_FUNC struct hostent  * W32_CALL gethostent     (void);
00231 W32_FUNC struct hostent  * W32_CALL getipnodebyaddr(const void *, size_t, int, int *);
00232 W32_FUNC struct hostent  * W32_CALL getipnodebyname(const char *, int, int, int *);
00233 W32_FUNC struct netent   * W32_CALL getnetbyaddr   (long, int);
00234 W32_FUNC struct netent   * W32_CALL getnetbyname   (const char *);
00235 W32_FUNC struct netent   * W32_CALL getnetent      (void);
00236 W32_FUNC struct protoent * W32_CALL getprotobyname (const char *);
00237 W32_FUNC struct protoent * W32_CALL getprotobynumber (int);
00238 W32_FUNC struct protoent * W32_CALL getprotoent    (void);
00239 W32_FUNC struct servent  * W32_CALL getservbyname  (const char *, const char *);
00240 W32_FUNC struct servent  * W32_CALL getservbyport  (int, const char *);
00241 W32_FUNC struct servent  * W32_CALL getservent     (void);
00242 W32_FUNC void              W32_CALL herror         (const char *);
00243 W32_FUNC const char      * W32_CALL hstrerror      (int);
00244 W32_FUNC void              W32_CALL sethostent     (int);
00245 W32_FUNC void              W32_CALL setnetent      (int);
00246 W32_FUNC void              W32_CALL setprotoent    (int);
00247 W32_FUNC void              W32_CALL setservent     (int);
00248
00249 W32_FUNC int W32_CALL getnameinfo (const struct sockaddr *sa, int salen,
00250                                    char *host, int hostlen,
00251                                    char *serv, int servlen, int flags);
00252
00253 W32_FUNC int W32_CALL getaddrinfo (const char *hostname, const char *servname,
00254                                    const struct addrinfo *hints, struct addrinfo **res);
00255
00256 W32_FUNC void   W32_CALL freeaddrinfo (struct addrinfo *ai);
00257 W32_FUNC void   W32_CALL freehostent  (struct hostent *);
00258 W32_FUNC char * W32_CALL gai_strerror (int ecode);
00259
00260 W32_FUNC int    W32_CALL if_nametoindex (const char *);
00261 W32_FUNC char * W32_CALL if_indextoname (int, char *);
00262
00263 W32_FUNC int  * W32_CALL __h_errno_location (void);
00264
00265 #if defined(_REENTRANT)
00266 W32_FUNC struct hostent * W32_CALL gethostbyaddr_r (
00267   const char *addr, int len, int type, struct hostent *result,
00268   char *buffer, int buflen, int *h_errnop);
00269
00270 W32_FUNC struct hostent * W32_CALL gethostbyname_r (
00271   const char *name, struct hostent *result,
00272   char *buffer, int buflen, int *h_errnop);
00273
00274 W32_FUNC struct hostent * W32_CALL gethostent_r (
00275   struct hostent *result, char *buffer, int buflen, int *h_errnop);
00276
00277 W32_FUNC struct netent * W32_CALL getnetbyaddr_r (
00278   long net, int type, struct netent *result, char *buffer, int buflen);
00279
00280 W32_FUNC struct netent * W32_CALL getnetbyname_r (
00281   const char *name, struct netent *result, char *buffer, int buflen);
00282
00283 W32_FUNC struct netent * W32_CALL getnetent_r (
00284   struct netent *result, char *buffer, int buflen);
00285
00286 W32_FUNC struct protoent * W32_CALL getprotobyname_r (
00287   const char *name, struct protoent *result, char *buffer, int buflen);
00288
00289 W32_FUNC struct protoent * W32_CALL getprotobynumber_r (
00290   int proto, struct protoent *result, char *buffer, int buflen);
00291
00292 W32_FUNC struct protoent * W32_CALL getprotoent_r (
00293   struct protoent *result, char *buffer, int buflen);
00294
00295 W32_FUNC struct servent * W32_CALL getservbyname_r (
00296   const char *name, const char *proto, struct servent *result,
00297   char *buffer, int buflen);
00298
00299 W32_FUNC struct servent * W32_CALL getservbyport_r (
00300   int port, const char *proto, struct servent *result,
00301   char *buffer, int buflen);
00302
00303 W32_FUNC struct servent * W32_CALL getservent_r (
00304   struct servent *result, char *buffer, int buflen);
00305
00306 #endif /* _REENTRANT */
00307
00308 __END_DECLS
00309
00310 #endif
Generated on Wed Jan 25 15:42:33 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/RESOLV.H Source File

inc/RESOLV.H

Go to the documentation of this file.
00001
00005 /*-
00006  * Copyright (c) 1983, 1987, 1989, 1993
00007  *      The Regents of the University of California.  All rights reserved.
00008  *
00009  * Redistribution and use in source and binary forms, with or without
00010  * modification, are permitted provided that the following conditions
00011  * are met:
00012  * 1. Redistributions of source code must retain the above copyright
00013  *    notice, this list of conditions and the following disclaimer.
00014  * 2. Redistributions in binary form must reproduce the above copyright
00015  *    notice, this list of conditions and the following disclaimer in the
00016  *    documentation and/or other materials provided with the distribution.
00017  * 3. All advertising materials mentioning features or use of this software
00018  *    must display the following acknowledgement:
00019  *      This product includes software developed by the University of
00020  *      California, Berkeley and its contributors.
00021  * 4. Neither the name of the University nor the names of its contributors
00022  *    may be used to endorse or promote products derived from this software
00023  *    without specific prior written permission.
00024  *
00025  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
00026  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00027  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00028  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
00029  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00030  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00031  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00032  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00033  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00034  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00035  * SUCH DAMAGE.
00036  *
00037  * -
00038  * Portions Copyright (c) 1993 by Digital Equipment Corporation.
00039  *
00040  * Permission to use, copy, modify, and distribute this software for any
00041  * purpose with or without fee is hereby granted, provided that the above
00042  * copyright notice and this permission notice appear in all copies, and that
00043  * the name of Digital Equipment Corporation not be used in advertising or
00044  * publicity pertaining to distribution of the document or software without
00045  * specific, written prior permission.
00046  *
00047  * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
00048  * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
00049  * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
00050  * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
00051  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
00052  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
00053  * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
00054  * SOFTWARE.
00055  * -
00056  * --Copyright--
00057  *
00058  *      @(#)resolv.h    8.1 (Berkeley) 6/2/93
00059  *      From Id: resolv.h,v 4.9.1.2 1993/05/17 09:59:01 vixie Exp
00060  *      $Id: resolv.h,v 1.7 1996/08/29 20:00:58 peter Exp $
00061  */
00062
00063 #ifndef _RESOLV_H_
00064 #define _RESOLV_H_
00065
00066 #include <stdio.h>
00067
00068 #ifndef __SYS_W32API_H
00069 #include <sys/w32api.h>
00070 #endif
00071
00072 #ifndef __SYS_PARAM_H
00073 #include <sys/param.h>
00074 #endif
00075
00076 #ifndef __SYS_WTYPES_H
00077 #include <sys/wtypes.h>
00078 #endif
00079
00080 #ifndef __SYS_CDEFS_H
00081 #include <sys/cdefs.h>
00082 #endif
00083
00084
00085 /*
00086  * revision information.  this is the release date in YYYYMMDD format.
00087  * it can change every day so the right thing to do with it is use it
00088  * in preprocessor commands such as "#if (__RES > 19931104)".  do not
00089  * compare for equality; rather, use it to determine whether your resolver
00090  * is new enough to contain a certain feature.
00091  */
00092
00093 #define __RES   19960229
00094
00095 /*
00096  * Resolver configuration file.
00097  * Normally not present, but may contain the address of the
00098  * inital name server(s) to query and the domain search list.
00099  */
00100
00101 #ifndef _PATH_RESCONF
00102 #define _PATH_RESCONF   "/etc/resolv.conf"
00103 #endif
00104
00105 /*
00106  * Global defines and variables for resolver stub.
00107  */
00108 #define MAXNS                   3       /* max # name servers we'll track */
00109 #define MAXDFLSRCH              3       /* # default domain levels to try */
00110 #define MAXDNSRCH               6       /* max # domains in search path */
00111 #define LOCALDOMAINPARTS        2       /* min levels in name that is "local" */
00112
00113 #define RES_TIMEOUT             5       /* min. seconds between retries */
00114 #define MAXRESOLVSORT           10      /* number of net to sort on */
00115 #define RES_MAXNDOTS            15      /* should reflect bit field size */
00116
00117 struct __res_state {
00118         int      retrans;               /* retransmition time interval */
00119         int      retry;                 /* number of times to retransmit */
00120         u_long   options;               /* option flags - see below. */
00121         int      nscount;               /* number of name servers */
00122         struct   sockaddr_in
00123                  nsaddr_list[MAXNS];    /* address of name server */
00124 #define nsaddr   nsaddr_list[0]         /* for backward compatibility */
00125         u_short  id;                    /* current packet id */
00126         char    *dnsrch[MAXDNSRCH+1];   /* components of domain to search */
00127         char     defdname[MAXDNAME];    /* default domain */
00128         u_long   pfcode;                /* RES_PRF_ flags - see below. */
00129         unsigned ndots:4;               /* threshold for initial abs. query */
00130         unsigned nsort:4;               /* number of elements in sort_list[] */
00131         char    unused[3];
00132         struct {
00133           struct in_addr  addr;
00134           u_long          mask;
00135       } sort_list[MAXRESOLVSORT];
00136         char pad[72];                   /* On an i386 this means 512b total. */
00137 };
00138
00139 /*
00140  * Resolver options (keep these in synch with res_debug.c, please)
00141  */
00142 #define RES_INIT        0x00000001      /* address initialized */
00143 #define RES_DEBUG       0x00000002      /* print debug messages */
00144 #define RES_AAONLY      0x00000004      /* authoritative answers only (!IMPL)*/
00145 #define RES_USEVC       0x00000008      /* use virtual circuit */
00146 #define RES_PRIMARY     0x00000010      /* query primary server only (!IMPL) */
00147 #define RES_IGNTC       0x00000020      /* ignore truncation errors */
00148 #define RES_RECURSE     0x00000040      /* recursion desired */
00149 #define RES_DEFNAMES    0x00000080      /* use default domain name */
00150 #define RES_STAYOPEN    0x00000100      /* Keep TCP socket open */
00151 #define RES_DNSRCH      0x00000200      /* search up local domain tree */
00152 #define RES_INSECURE1   0x00000400      /* type 1 security disabled */
00153 #define RES_INSECURE2   0x00000800      /* type 2 security disabled */
00154 #define RES_NOALIASES   0x00001000      /* shuts off HOSTALIASES feature */
00155 #define RES_USE_INET6   0x00002000      /* use/map IPv6 in gethostbyname() */
00156
00157 #define RES_DEFAULT     (RES_RECURSE | RES_DEFNAMES | RES_DNSRCH)
00158
00159 /*
00160  * Resolver "pfcode" values.  Used by dig.
00161  */
00162 #define RES_PRF_STATS   0x00000001
00163 /*                      0x00000002      */
00164 #define RES_PRF_CLASS   0x00000004
00165 #define RES_PRF_CMD     0x00000008
00166 #define RES_PRF_QUES    0x00000010
00167 #define RES_PRF_ANS     0x00000020
00168 #define RES_PRF_AUTH    0x00000040
00169 #define RES_PRF_ADD     0x00000080
00170 #define RES_PRF_HEAD1   0x00000100
00171 #define RES_PRF_HEAD2   0x00000200
00172 #define RES_PRF_TTLID   0x00000400
00173 #define RES_PRF_HEADX   0x00000800
00174 #define RES_PRF_QUERY   0x00001000
00175 #define RES_PRF_REPLY   0x00002000
00176 #define RES_PRF_INIT    0x00004000
00177 /*                      0x00008000      */
00178
00179 /* hooks are still experimental as of 4.9.2 */
00180 typedef enum {
00181         res_goahead,
00182         res_nextns,
00183         res_modified,
00184         res_done,
00185         res_error
00186       } res_sendhookact;
00187
00188 typedef res_sendhookact (*res_send_qhook)(struct sockaddr_in * const *ns,
00189                                           const u_char **query,
00190                                           int *querylen,
00191                                           u_char *ans,
00192                                           int anssiz,
00193                                           int *resplen);
00194
00195 typedef res_sendhookact (*res_send_rhook)(const struct sockaddr_in *ns,
00196                                           const u_char *query,
00197                                           int querylen,
00198                                           u_char *ans,
00199                                           int anssiz,
00200                                           int *resplen);
00201
00202 W32_DATA struct __res_state _res;
00203
00204 W32_DATA int h_errno;
00205
00206 /* Private routines shared between libc/net, named, nslookup and others. */
00207 #define res_hnok         __res_hnok
00208 #define res_ownok        __res_ownok
00209 #define res_mailok       __res_mailok
00210 #define res_dnok         __res_dnok
00211 #define loc_ntoa         __loc_ntoa
00212 #define loc_aton         __loc_aton
00213 #define dn_skipname      __dn_skipname
00214 #define fp_query         __fp_query
00215 #define fp_nquery        __fp_nquery
00216 #define hostalias        __hostalias
00217 #define putlong          __putlong
00218 #define putshort         __putshort
00219 #define p_class          __p_class
00220 #define p_time           __p_time
00221 #define p_type           __p_type
00222 #define p_cdnname        __p_cdnname
00223 #define p_cdname         __p_cdname
00224 #define p_fqname         __p_fqname
00225 #define p_rr             __p_rr
00226 #define p_option         __p_option
00227 #define res_randomid     __res_randomid
00228 #define res_isourserver  __res_isourserver
00229 #define res_nameinquery  __res_nameinquery
00230 #define res_queriesmatch __res_queriesmatch
00231
00232 __BEGIN_DECLS
00233
00234 W32_FUNC int      __res_hnok   (const char *);
00235 W32_FUNC int      __res_ownok  (const char *);
00236 W32_FUNC int      __res_mailok (const char *);
00237 W32_FUNC int      __res_dnok   (const char *);
00238 W32_FUNC int      __loc_aton   (const char *ascii, u_char *binary);
00239 W32_FUNC char *   __loc_ntoa   (const u_char *binary, char *ascii);
00240 W32_FUNC int      __dn_skipname(const u_char *, const u_char *);
00241 W32_FUNC void     __fp_resstat (struct __res_state *, FILE *);
00242 W32_FUNC void     __fp_query   (const u_char *, FILE *);
00243 W32_FUNC void     __fp_nquery  (const u_char *, int, FILE *);
00244 W32_FUNC char    *__hostalias  (const char *);
00245 W32_FUNC void     __putlong    (u_long,  u_char *);
00246 W32_FUNC void     __putshort   (u_short, u_char *);
00247 W32_FUNC char    *__p_time     (u_long);
00248 W32_FUNC void     __p_query    (const u_char *);
00249
00250 W32_FUNC const u_char *__p_cdnname (const u_char *, const u_char *, int, FILE *);
00251 W32_FUNC const u_char *__p_cdname  (const u_char *, const u_char *, FILE *);
00252 W32_FUNC const u_char *__p_fqname  (const u_char *, const u_char *, FILE *);
00253 W32_FUNC const u_char *__p_rr      (const u_char *, const u_char *, FILE *);
00254 W32_FUNC const char   *__p_type    (int);
00255 W32_FUNC const char   *__p_class   (int);
00256 W32_FUNC const char   *__p_option  (u_long option);
00257
00258 W32_FUNC int     dn_comp   (const char *, u_char *, int, u_char **, u_char **);
00259 W32_FUNC int     dn_expand (const u_char *, const u_char *, const u_char *, char *, int);
00260
00261 W32_FUNC int     res_init        (void);
00262 W32_FUNC u_short res_randomid    (void);
00263 W32_FUNC int     res_query       (const char *, int, int, u_char *, int);
00264 W32_FUNC int     res_search      (const char *, int, int, u_char *, int);
00265 W32_FUNC int     res_querydomain (const char *, const char *, int, int, u_char *, int);
00266 W32_FUNC int     res_mkquery     (int, const char *, int, int, const u_char *, int, const u_char *, u_char *, int);
00267 W32_FUNC int     res_send        (const u_char *, int, u_char *, int);
00268 W32_FUNC int     res_isourserver (const struct sockaddr_in *);
00269 W32_FUNC int     res_nameinquery (const char *, int, int, const u_char *, const u_char *);
00270 W32_FUNC int     res_queriesmatch(const u_char *, const u_char *, const u_char *, const u_char *);
00271
00272 W32_FUNC void    res_send_setqhook (res_send_qhook hook);
00273 W32_FUNC void    res_send_setrhook (res_send_rhook hook);
00274
00275 __END_DECLS
00276
00277 #endif /* !_RESOLV_H_ */
Generated on Wed Jan 25 15:42:33 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/SYSLOG.H Source File

inc/SYSLOG.H

Go to the documentation of this file.
00001
00004 /*
00005  * POSIX requires (AFAIK) this file in a base-dir
00006  */
00007 #ifndef __SYS_SYSLOG_H
00008 #include <sys/syslog.h>
00009 #endif
Generated on Wed Jan 25 15:42:33 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/TCP.H Source File

inc/TCP.H

Go to the documentation of this file.
00001
00005 /*
00006  * Waterloo TCP
00007  *
00008  * Copyright (c) 1990-1993 Erick Engelke
00009  *
00010  * Portions copyright others, see copyright.h for details.
00011  *
00012  * This library is free software; you can use it or redistribute under
00013  * the terms of the license included in LICENSE.H.
00014  *
00015  * This program is distributed in the hope that it will be useful,
00016  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018  * file LICENSE.H for more details.
00019  *
00020  */
00021
00022 #ifndef __WATT_TCP_H
00023 #define __WATT_TCP_H
00024
00025 /*
00026  * Version (major.minor.dev-rel), 8-bit each.
00027  */
00028 #define WATTCP_MAJOR_VER  2
00029 #define WATTCP_MINOR_VER  2
00030 #define WATTCP_DEVEL_REL  10
00031
00032 #define WATTCP_VER  ((WATTCP_MAJOR_VER << 16) + \
00033                      (WATTCP_MINOR_VER << 8) +  \
00034                      WATTCP_DEVEL_REL)
00035
00036 #define WATTCP_VER_STRING  "2.2.10"
00037
00038 #if !defined(RC_INVOKED)
00039
00040 #include <stdio.h>
00041 #include <sys/wtypes.h>  /* fd_set, iovec */
00042 #include <sys/wtime.h>   /* struct timeval, cdecl */
00043 #include <sys/swap.h>    /* intel(), intel16() */
00044 #include <sys/w32api.h>  /* W32_FUNC, W32_DATA etc. */
00045
00046 #ifdef __WATCOMC__
00047   #pragma read_only_directory;
00048 #endif
00049
00050 #ifdef __cplusplus
00051   extern "C" {
00052   #if 0  /* keep Emacs's auto-indent happy */
00053   }
00054   #endif
00055 #endif
00056
00057 W32_DATA const char *wattcpCopyright;  /* "See COPYRIGHT.H for details" */
00058
00059 W32_FUNC const char *wattcpVersion (void);      /* WatTCP target version/date */
00060 W32_FUNC const char *wattcpCapabilities (void); /* what's been compiled in */
00061
00062 #if !defined(WATT32_BUILD)
00063
00064 /*
00065  * Typedefs and constants
00066  */
00067 #ifndef BYTE
00068 #define BYTE   unsigned char
00069 #endif
00070
00071 #ifndef WORD
00072 #define WORD   unsigned short
00073 #endif
00074
00075 #ifndef DWORD
00076 #define DWORD  unsigned long
00077 #endif
00078
00079 #ifndef BOOL
00080 #define BOOL   int
00081 #endif
00082
00083 #ifndef sock_type
00084 #define sock_type  void
00085 #endif
00086
00087 /*
00088  * Old compatibility
00089  */
00090 #ifndef byte
00091 #define byte  unsigned char
00092 #endif
00093
00094 #ifndef word
00095 #define word  unsigned short
00096 #endif
00097
00098 #ifndef dword
00099 #define dword unsigned long
00100 #endif
00101
00102 #ifndef longword
00103 #define longword unsigned long
00104 #endif
00105
00106 /*
00107  * Basic typedefs
00108  */
00109 typedef BYTE  eth_address[6];
00110 typedef BYTE  ip6_address[16];
00111
00112 typedef int (*ProtoHandler) (void *sock, const BYTE *data, unsigned len,
00113                              const void *tcp_phdr, const void *udp_hdr);
00114
00115 typedef int (*UserHandler)  (void *sock);
00116
00117 #endif /* WATT32_BUILD */
00118
00119
00120 typedef struct {
00121         BYTE   undoc [4470];
00122       } tcp_Socket;
00123
00124 typedef struct {
00125         BYTE   undoc [1740];
00126       } udp_Socket;
00127
00128
00129 /* Silly C++ compilers needs this to supress warning at max warning level
00130  */
00131 typedef void (*VoidProc)(void);
00132
00133 #define MAX_COOKIES      10
00134 #define MAX_NAMESERVERS  10
00135 #define MAX_HOSTLEN      80
00136
00137 /* Modes for sock_mode()
00138  */
00139 #define TCP_MODE_BINARY  0x01   /* deprecated */
00140 #define TCP_MODE_ASCII   0x02   /* deprecated */
00141 #define SOCK_MODE_BINARY 0x01   /* new name */
00142 #define SOCK_MODE_ASCII  0x02   /* new name */
00143 #define UDP_MODE_CHK     0x04   /* defaults to checksum */
00144 #define UDP_MODE_NOCHK   0x08
00145 #define TCP_MODE_NAGLE   0x10   /* Nagle's algorithm */
00146 #define TCP_MODE_NONAGLE 0x20
00147
00148 /* wait-states for sock_sselect()
00149  */
00150 #define SOCKESTABLISHED  1
00151 #define SOCKDATAREADY    2
00152 #define SOCKCLOSED       4
00153
00154 /*
00155  * Hide "private" symbols by prefixing with "_w32_"
00156  */
00157 #undef  W32_NAMESPACE
00158 #define W32_NAMESPACE(x)   _w32_ ## x
00159
00160 #define init_misc          W32_NAMESPACE (init_misc)
00161 #define Random             W32_NAMESPACE (Random)
00162 #define set_timeout        W32_NAMESPACE (set_timeout)
00163 #define chk_timeout        W32_NAMESPACE (chk_timeout)
00164 #define cmp_timeout        W32_NAMESPACE (cmp_timeout)
00165 #define hires_timer        W32_NAMESPACE (hires_timer)
00166 #define set_timediff       W32_NAMESPACE (set_timediff)
00167 #define get_timediff       W32_NAMESPACE (get_timediff)
00168 #define timeval_diff       W32_NAMESPACE (timeval_diff)
00169
00170 #define my_ip_addr         W32_NAMESPACE (my_ip_addr)
00171 #define sin_mask           W32_NAMESPACE (sin_mask)
00172 #define sock_delay         W32_NAMESPACE (sock_delay)
00173 #define sock_inactive      W32_NAMESPACE (sock_inactive)
00174 #define sock_data_timeout  W32_NAMESPACE (sock_data_timeout)
00175 #define multihomes         W32_NAMESPACE (multihomes)
00176 #define block_tcp          W32_NAMESPACE (block_tcp)
00177 #define block_udp          W32_NAMESPACE (block_udp)
00178 #define block_ip           W32_NAMESPACE (block_ip)
00179 #define block_icmp         W32_NAMESPACE (block_icmp)
00180 #define last_cookie        W32_NAMESPACE (last_cookie)
00181 #define cookies            W32_NAMESPACE (cookies)
00182 #define survive_eth        W32_NAMESPACE (survive_eth)
00183 #define survive_bootp      W32_NAMESPACE (survive_bootp)
00184 #define survive_dhcp       W32_NAMESPACE (survive_dhcp)
00185 #define survive_rarp       W32_NAMESPACE (survive_rarp)
00186 #define loopback_handler   W32_NAMESPACE (loopback_handler)
00187 #define usr_init           W32_NAMESPACE (usr_init)
00188 #define usr_post_init      W32_NAMESPACE (usr_post_init)
00189 #define in_checksum        W32_NAMESPACE (in_checksum)
00190 #define aton               W32_NAMESPACE (aton)
00191 #define isaddr             W32_NAMESPACE (isaddr)
00192 #define _printf            W32_NAMESPACE (_printf)
00193 #define _outch             W32_NAMESPACE (_outch)
00194 #define outs               W32_NAMESPACE (outs)
00195 #define outsnl             W32_NAMESPACE (outsnl)
00196 #define outsn              W32_NAMESPACE (outsn)
00197 #define outhexes           W32_NAMESPACE (outhexes)
00198 #define outhex             W32_NAMESPACE (outhex)
00199 #define rip                W32_NAMESPACE (rip)
00200 #define parse_config_table W32_NAMESPACE (parse_config_table)
00201 #define init_timer_isr     W32_NAMESPACE (init_timer_isr)
00202 #define exit_timer_isr     W32_NAMESPACE (exit_timer_isr)
00203
00204 #undef  sock_init
00205 #define sock_init() watt_sock_init (sizeof(tcp_Socket), sizeof(udp_Socket))
00206
00207 W32_FUNC int         watt_sock_init (size_t, size_t);
00208 W32_FUNC const char *sock_init_err  (int rc);
00209
00210 W32_FUNC void sock_exit (void);
00211 W32_FUNC void dbug_init (void);  /* effective if compiled with `USE_DEBUG' */
00212 W32_FUNC void init_misc (void);  /* may be called before sock_init() */
00213 W32_FUNC void sock_sig_exit (const char *msg, int sigint);
00214
00215 #if !defined(WATT32_BUILD)
00216 /*
00217  * `s' is the pointer to a udp or tcp socket
00218  */
00219 W32_FUNC int    sock_read       (void *s, char *dp, int len);
00220 W32_FUNC int    sock_preread    (void *s, char *dp, int len);
00221 W32_FUNC int    sock_fastread   (void *s, char *dp, int len);
00222 W32_FUNC int    sock_write      (void *s, const char *dp, int len);
00223 W32_FUNC int    sock_enqueue    (void *s, const char *dp, int len);
00224 W32_FUNC int    sock_fastwrite  (void *s, const char *dp, int len);
00225 W32_FUNC size_t sock_setbuf     (void *s, char *buf, size_t len);
00226 W32_FUNC void   sock_flush      (void *s);
00227 W32_FUNC void   sock_noflush    (void *s);
00228 W32_FUNC void   sock_flushnext  (void *s);
00229 W32_FUNC int    sock_puts       (void *s, const char *dp);
00230 W32_FUNC WORD   sock_gets       (void *s, char *dp, int n);
00231 W32_FUNC BYTE   sock_putc       (void *s, char c);
00232 W32_FUNC int    sock_getc       (void *s);
00233 W32_FUNC WORD   sock_dataready  (void *s);
00234 W32_FUNC int    sock_established(void *s);
00235 W32_FUNC int    sock_close      (void *s);
00236 W32_FUNC int    sock_abort      (void *s);
00237 W32_FUNC void (*sock_yield      (void *s, VoidProc fn)) (void);
00238 W32_FUNC int    sock_mode       (void *s, WORD mode);
00239 W32_FUNC int    sock_sselect    (void *s, int waitstate);
00240 W32_FUNC int    sock_timeout    (void *s, int seconds);
00241 W32_FUNC int    sock_recv       (void *s, char *buf, unsigned len);
00242 W32_FUNC int    sock_recv_init  (void *s, char *buf, unsigned len);
00243 W32_FUNC int    sock_recv_from  (void *s, DWORD *ip, WORD *port, char *buf, unsigned len, int peek);
00244 W32_FUNC int    sock_recv_used  (void *s);
00245 W32_FUNC int    sock_keepalive  (void *s);
00246
00247 W32_FUNC size_t sock_rbsize     (const void *s);
00248 W32_FUNC size_t sock_rbused     (const void *s);
00249 W32_FUNC size_t sock_rbleft     (const void *s);
00250 W32_FUNC size_t sock_tbsize     (const void *s);
00251 W32_FUNC size_t sock_tbused     (const void *s);
00252 W32_FUNC size_t sock_tbleft     (const void *s);
00253
00254 W32_FUNC int MS_CDECL sock_printf (void *s, const char *fmt, ...)
00255   #if defined(__GNUC__)
00256   __attribute__((format(printf,2,3)))
00257   #endif
00258   ;
00259
00260 W32_FUNC int MS_CDECL sock_scanf (void *s, const char *fmt, ...)
00261   #if defined(__GNUC__)
00262   __attribute__((format(scanf,2,3)))
00263   #endif
00264   ;
00265
00266 /*
00267  * TCP or UDP specific stuff, must be used for open's and listens, but
00268  * sock stuff above is used for everything else
00269  */
00270 W32_FUNC int udp_open   (void *s, WORD lport, DWORD ina, WORD port, ProtoHandler handler);
00271 W32_FUNC int tcp_open   (void *s, WORD lport, DWORD ina, WORD port, ProtoHandler handler);
00272 W32_FUNC int udp_listen (void *s, WORD lport, DWORD ina, WORD port, ProtoHandler handler);
00273 W32_FUNC int tcp_listen (void *s, WORD lport, DWORD ina, WORD port, ProtoHandler handler, WORD timeout);
00274 W32_FUNC int tcp_established (const void *s);
00275
00276 #endif  /* WATT32_BUILD */
00277
00278
00279 W32_FUNC DWORD resolve    (const char *name);
00280 W32_FUNC int   resolve_ip (DWORD ip, char *name, int len);
00281 W32_FUNC DWORD lookup_host(const char *host, char *ip_str);
00282 W32_FUNC const char *dom_strerror (int err);
00283
00284 /*
00285  * less general functions
00286  */
00287 W32_FUNC int   tcp_cbreak (int mode);
00288
00289 W32_FUNC DWORD aton       (const char *name);
00290 W32_FUNC int   isaddr     (const char *name);
00291 W32_FUNC char *rip        (char *s);
00292 W32_FUNC int   watt_kbhit (void);
00293
00294 #define tcp_cbrk(mode)  tcp_cbreak(mode) /* old name */
00295
00296 /*
00297  * Set MD5 secret for TCP option 19 (RFC-2385).
00298  * Only if built with USE_TCP_MD5.
00299  */
00300 W32_FUNC const char *tcp_md5_secret (void *s, const char *secret);
00301
00302 /*
00303  * timers
00304  */
00305 W32_FUNC DWORD  set_timeout  (DWORD msec);
00306 W32_FUNC int    chk_timeout  (DWORD value);
00307 W32_FUNC int    cmp_timers   (DWORD t1, DWORD t2);
00308 W32_FUNC int    set_timediff (long msec);
00309 W32_FUNC long   get_timediff (DWORD now, DWORD t);
00310 W32_FUNC int    hires_timer  (int on);
00311 W32_FUNC double timeval_diff (const struct timeval *a, const struct timeval *b);
00312
00313 W32_FUNC void   init_timer_isr (void);
00314 W32_FUNC void   exit_timer_isr (void);
00315
00316 W32_FUNC void   init_userSuppliedTimerTick (void);
00317 W32_FUNC void   userTimerTick (DWORD);
00318
00319 W32_FUNC void   ip_timer_init (sock_type *s , unsigned delayseconds);
00320 W32_FUNC int    ip_timer_expired (const sock_type *s);
00321
00322 /*
00323  * TCP/IP system variables
00324  */
00325 W32_DATA DWORD my_ip_addr;
00326 W32_DATA DWORD sin_mask;       /* eg.  0xFFFFFE00L */
00327 W32_DATA int   sock_delay;
00328 W32_DATA int   sock_inactive;
00329 W32_DATA int   sock_data_timeout;
00330 W32_DATA WORD  multihomes;
00331
00332 W32_DATA int   block_tcp;
00333 W32_DATA int   block_udp;
00334 W32_DATA int   block_icmp;
00335 W32_DATA int   block_ip;
00336 W32_DATA WORD  last_cookie;
00337 W32_DATA DWORD cookies [MAX_COOKIES];
00338
00339 W32_DATA BOOL  survive_eth;
00340 W32_DATA BOOL  survive_bootp;
00341 W32_DATA BOOL  survive_dhcp;
00342 W32_DATA BOOL  survive_rarp;
00343
00344 W32_DATA void (*loopback_handler) (void *ip);
00345
00346 /*
00347  * things you probably won't need to know about
00348  */
00349
00350 /*
00351  * sock_debugdump
00352  *      - dump some socket control block parameters
00353  * used for testing the kernal, not recommended
00354  */
00355 W32_FUNC void sock_debugdump (const sock_type *s);
00356
00357 /*
00358  * tcp_config - read a configuration file
00359  *            - if special path desired, call after sock_init()
00360  *            - NULL reads path WATTCP.CFG env-var or from program's path
00361  * see sock_init();
00362  */
00363 W32_FUNC long tcp_config (const char *path);
00364
00365 /*
00366  * tcp_tick - must be called periodically by user application.
00367  *          - returns NULL when our socket closes
00368  */
00369 W32_FUNC WORD tcp_tick (sock_type *s);
00370
00371 /*
00372  * tcp_set_debug_state - set to 1,2 or reset 0
00373  */
00374 W32_FUNC void tcp_set_debug_state (WORD x);
00375
00376
00377 /*
00378  * name domain constants, etc.
00379  */
00380 #define def_domain       W32_NAMESPACE (def_domain)
00381 #define def_nameservers  W32_NAMESPACE (def_nameservers)
00382 #define dns_timeout      W32_NAMESPACE (dns_timeout)
00383 #define dom_errno        W32_NAMESPACE (dom_errno)
00384 #define last_nameserver  W32_NAMESPACE (last_nameserver)
00385 #define _mtu             W32_NAMESPACE (_mtu)
00386 #define _mss             W32_NAMESPACE (_mss)
00387 #define ctrace_on        W32_NAMESPACE (ctrace_on)
00388 #define has_rdtsc        W32_NAMESPACE (has_rdtsc)
00389 #define clocks_per_usec  W32_NAMESPACE (clocks_per_usec)
00390 #define psocket          W32_NAMESPACE (psocket)
00391 #define _inet_ntoa       W32_NAMESPACE (_inet_ntoa)
00392 #define _inet_addr       W32_NAMESPACE (_inet_addr)
00393
00394 W32_DATA char         *def_domain;
00395 W32_DATA int           dom_errno;
00396 W32_DATA DWORD         def_nameservers [MAX_NAMESERVERS];
00397 W32_DATA WORD          dns_timeout;
00398 W32_DATA WORD          last_nameserver;
00399 W32_DATA WORD         _watt_handle_cbreak;      /* ^C/^Break handle mode */
00400 W32_DATA volatile int _watt_cbroke;             /* ^C/^Break occured */
00401 W32_DATA unsigned     _mtu, _mss;
00402 W32_DATA int           ctrace_on;
00403 W32_DATA int           has_rdtsc;
00404 W32_DATA DWORD         clocks_per_usec;
00405
00406 /* Old compatibility
00407  */
00408 #define wathndlcbrk  _watt_handle_cbreak
00409 #define watcbroke    _watt_cbroke
00410
00411 /*
00412  * sock_wait_ .. macros
00413  */
00414
00415 /*
00416  * sock_wait_established()
00417  *      - Waits until connected or aborts if timeout etc.
00418  *
00419  * sock_wait_input()
00420  *      - Waits for received input on socket 's'.
00421  *      - May not be valid input for sock_gets()..  check returned length.
00422  *
00423  * sock_tick()
00424  *      - Do tick and jump on abort.
00425  *
00426  * sock_wait_closed()
00427  *      - Close socket and wait until fully closed.
00428  *        Discards all received data.
00429  *
00430  * All these macros jump to label sock_err with contents of *statusptr
00431  * set to
00432  *       1 on closed normally.
00433  *      -1 on error, call sockerr(s) for cause.
00434  *
00435  */
00436 #if !defined(WATT32_BUILD)
00437
00438 W32_FUNC int _ip_delay0 (void *s, int sec, UserHandler fn, void *statusptr);
00439 W32_FUNC int _ip_delay1 (void *s, int sec, UserHandler fn, void *statusptr);
00440 W32_FUNC int _ip_delay2 (void *s, int sec, UserHandler fn, void *statusptr);
00441
00442
00443 #define sock_wait_established(s,seconds,fn,statusptr) \
00444         do {                                          \
00445            if (_ip_delay0 (s,seconds,fn,statusptr))   \
00446               goto sock_err;                          \
00447         } while (0)
00448
00449 #define sock_wait_input(s,seconds,fn,statusptr)       \
00450         do {                                          \
00451            if (_ip_delay1 (s,seconds,fn,statusptr))   \
00452               goto sock_err;                          \
00453         } while (0)
00454
00455 #define sock_tick(s, statusptr)                       \
00456         do {                                          \
00457            if (!tcp_tick(s)) {                        \
00458               if (statusptr) *statusptr = -1;         \
00459               goto sock_err;                          \
00460            }                                          \
00461         } while (0)
00462
00463 #define sock_wait_closed(s,seconds,fn,statusptr)      \
00464         do {                                          \
00465            if (_ip_delay2(s,seconds,fn,statusptr))    \
00466               goto sock_err;                          \
00467         } while (0)
00468
00469 #endif  /* WATT32_BUILD */
00470
00471 /*
00472  * User hook for WATTCP.CFG initialisation file.
00473  */
00474 W32_DATA void (*usr_init) (const char *keyword, const char *value);
00475 W32_DATA void (*usr_post_init) (void);
00476
00477 enum config_tab_types {
00478      ARG_ATOI,        /* convert to int */
00479      ARG_ATOB,        /* convert to 8-bit byte */
00480      ARG_ATOW,        /* convert to 16-bit word */
00481      ARG_ATOIP,       /* convert to ip-address on host order */
00482      ARG_ATOX_B,      /* convert to hex-byte */
00483      ARG_ATOX_W,      /* convert to hex-word */
00484      ARG_ATOX_D,      /* convert to hex-word */
00485      ARG_STRDUP,      /* duplicate string value */
00486      ARG_STRCPY,      /* copy string value */
00487      ARG_RESOLVE,     /* resolve host to ip-address */
00488      ARG_FUNC         /* call convertion function */
00489    };
00490
00491 struct config_table {
00492        const char            *keyword;
00493        enum config_tab_types  type;
00494        void                  *arg_func;
00495      };
00496
00497
00498 W32_FUNC int parse_config_table (const struct config_table *tab,
00499                                  const char *section,
00500                                  const char *name,
00501                                  const char *value);
00502
00503 /*
00504  * Run with no config file (embedded/diskless)
00505  */
00506 W32_DATA int _watt_no_config;
00507
00508 W32_FUNC void tcp_inject_config (
00509               const struct config_table *cfg,
00510               const char                *key,
00511               const char                *value);
00512
00513 typedef long (*WattUserConfigFunc) (int pass, const struct config_table *cfg);
00514
00515 W32_FUNC WattUserConfigFunc _watt_user_config (WattUserConfigFunc fn);
00516
00517
00518 /*
00519  * Bypass standard handling of DHCP transient configuration
00520  */
00521 #include <sys/packon.h>
00522
00523 struct DHCP_config {
00524        DWORD  my_ip;
00525        DWORD  netmask;
00526        DWORD  gateway;
00527        DWORD  nameserver;
00528        DWORD  server;
00529        DWORD  iplease;
00530        DWORD  renewal;
00531        DWORD  rebind;
00532        DWORD  tcp_keep_intvl;
00533        BYTE   default_ttl;
00534        char   hostname [MAX_HOSTLEN+1];
00535        char   domain [MAX_HOSTLEN+1];
00536        char   loghost [MAX_HOSTLEN+1]; /* Only used if USE_BSD_FUNC defined */
00537      };
00538
00539 #include <sys/packoff.h>
00540
00541 enum DHCP_config_op {
00542      DHCP_OP_READ  = 0,
00543      DHCP_OP_WRITE = 1,
00544      DHCP_OP_ERASE = 2
00545    };
00546
00547 typedef int (*WattDHCPConfigFunc) (enum DHCP_config_op op,
00548                                    struct DHCP_config *cfg);
00549
00550 W32_FUNC WattDHCPConfigFunc dhcp_set_config_func (WattDHCPConfigFunc fn);
00551
00552
00553 /*
00554  * Various function-pointer hooks etc.
00555  */
00556 W32_DATA int (MS_CDECL *_printf) (const char *, ...);
00557 W32_DATA void (*_outch) (char c);
00558 W32_DATA int  (*_resolve_hook) (void);
00559 W32_DATA void (*wintr_chain) (void);
00560
00561 W32_DATA int (*tftp_writer) (const void *buf, unsigned length);
00562 W32_DATA int (*tftp_terminator) (void);
00563
00564 W32_FUNC void  outs    (const char *s);
00565 W32_FUNC void  outsnl  (const char *s);
00566 W32_FUNC void  outsn   (const char *s, int n);
00567 W32_FUNC void  outhexes(const char *s, int n);
00568 W32_FUNC void  outhex  (char ch);
00569
00570 W32_FUNC int   wintr_enable (void);
00571 W32_FUNC void  wintr_disable (void);
00572 W32_FUNC void  wintr_shutdown (void);
00573 W32_FUNC void  wintr_init (void);
00574
00575 W32_FUNC int   _ping     (DWORD host, DWORD num, const BYTE *pattern, long len);
00576 W32_FUNC DWORD _chk_ping (DWORD host, DWORD *ping_num);
00577
00578 W32_FUNC int   _eth_init         (void);
00579 W32_FUNC void  _eth_release      (void);
00580 W32_FUNC void *_eth_formatpacket (const void *eth_dest, WORD eth_type);
00581 W32_FUNC void  _eth_free         (const void *buf);
00582 W32_FUNC void *_eth_arrived      (WORD *type, BOOL *brdcast);
00583 W32_FUNC int   _eth_send         (WORD len, const void *sock, const char *file, unsigned line);
00584 W32_FUNC int   _eth_set_addr     (const void *addr);
00585 W32_FUNC BYTE  _eth_get_hwtype   (BYTE *hwtype, BYTE *hwlen);
00586
00587 W32_DATA void *(*_eth_recv_hook) (WORD *type);
00588 W32_DATA int   (*_eth_recv_peek) (void *mac_buf);
00589 W32_DATA int   (*_eth_xmit_hook) (const void *buf, unsigned len);
00590 W32_FUNC WORD    in_checksum     (const void *buf, unsigned len);
00591
00592 #define inchksum(buf,len)  in_checksum(buf, len)
00593
00594
00595 /*
00596  * BSD-socket similarities.
00597  * Refer <sys/socket.h> for the real thing.
00598  */
00599 #if !defined(WATT32_BUILD)
00600
00601 struct watt_sockaddr {     /* for _getpeername, _getsockname */
00602        WORD   s_type;
00603        WORD   s_port;
00604        DWORD  s_ip;
00605        BYTE   s_spares[6]; /* unused */
00606      };
00607
00608 W32_FUNC DWORD _gethostid   (void);
00609 W32_FUNC DWORD _sethostid   (DWORD ip);
00610 W32_FUNC int   _getsockname (const void *s, void *dest, int *len);
00611 W32_FUNC int   _getpeername (const void *s, void *dest, int *len);
00612
00613 W32_FUNC int   _chk_socket  (const void *s);
00614 W32_FUNC void  psocket      (const void *s);
00615
00616 #endif
00617
00618 W32_FUNC char *_inet_ntoa   (char *s, DWORD x);
00619 W32_FUNC DWORD _inet_addr   (const char *name);
00620
00621 W32_FUNC BOOL _arp_register (DWORD use, DWORD instead_of);
00622 W32_FUNC BOOL _arp_resolve  (DWORD ina, eth_address *res);
00623
00624 W32_FUNC int   addwattcpd (VoidProc p);
00625 W32_FUNC int   delwattcpd (VoidProc p);
00626
00627 W32_FUNC void _sock_debug_on  (void);
00628 W32_FUNC void _sock_debug_off (void);
00629
00630 #if !defined(WATT32_BUILD)
00631
00632 W32_FUNC const char *sockerr  (const void *s);   /* UDP / TCP */
00633 W32_FUNC void  sockerr_clear  (void *s);         /* UDP / TCP */
00634
00635 W32_FUNC const char *sockstate (const void *s);  /* UDP / TCP / Raw */
00636
00637 /*
00638  * Reduce internal states to "user-easy" states, GvB 2002-09
00639  */
00640 enum TCP_SIMPLE_STATE {
00641      TCP_CLOSED,
00642      TCP_LISTENING,
00643      TCP_OPENING,
00644      TCP_OPEN,
00645      TCP_CLOSING
00646    };
00647
00648 W32_FUNC enum TCP_SIMPLE_STATE tcp_simple_state (const tcp_Socket *s);
00649
00650 #endif  /* WATT32_BUILD */
00651
00652
00653 /*
00654  * BSD functions for read/write/select
00655  */
00656 W32_FUNC int close_s  (int s);
00657 W32_FUNC int write_s  (int s, const char *buf, int nbyte);
00658 W32_FUNC int read_s   (int s,       char *buf, int nbyte);
00659 W32_FUNC int writev_s (int s, const struct iovec *vector, size_t count);
00660 W32_FUNC int readv_s  (int s, const struct iovec *vector, size_t count);
00661
00662 W32_FUNC const sock_type *__get_sock_from_s (int s, int proto);
00663                             /* Use 'IPPROTO_x' for proto */
00664
00665 W32_FUNC int select_s (int num_sockets,
00666                        fd_set *read_events,
00667                        fd_set *write_events,
00668                        fd_set *except_events,
00669                        struct timeval *timeout);
00670
00671 /* The only BSD/Winsock replacement in this file.
00672  * Normally belongs in djgpp's <unistd.h>.
00673  */
00674 #ifndef __DJGPP__
00675 W32_FUNC int W32_CALL select (int num_sockets,
00676                               fd_set *read_events,
00677                               fd_set *write_events,
00678                               fd_set *except_events,
00679                               struct timeval *timeout);
00680 #endif
00681
00682 /* Duplicated from <sys/socket.h>
00683  */
00684 W32_FUNC int W32_CALL gethostname (char *name, int len);
00685
00686 /*
00687  * Multicast stuff (if built with `USE_MULTICAST')
00688  */
00689 W32_DATA int _multicast_on;
00690
00691 W32_FUNC int join_mcast_group  (DWORD ip);
00692 W32_FUNC int leave_mcast_group (DWORD ip);
00693 W32_FUNC int _ip4_is_multicast (DWORD ip);
00694 W32_FUNC int multi_to_eth      (DWORD ip, eth_address *eth);
00695 W32_FUNC int udp_SetTTL        (udp_Socket *s, BYTE ttl);
00696
00697
00698 /*
00699  * Commandline parsing
00700  */
00701 #if defined(__DJGPP__)
00702   #include <unistd.h>
00703
00704 #elif defined(__MINGW32__)
00705   #include <getopt.h>
00706
00707 #elif !defined(_GETOPT_H)  /* not using a local getopt.c */
00708   #define optarg    W32_NAMESPACE (optarg)
00709   #define optind    W32_NAMESPACE (optind)
00710   #define opterr    W32_NAMESPACE (opterr)
00711   #define optopt    W32_NAMESPACE (optopt)
00712   #define optswchar W32_NAMESPACE (optswchar)
00713   #define optmode   W32_NAMESPACE (optmode)
00714   #define getopt    W32_NAMESPACE (getopt)
00715
00716   W32_DATA char *optarg;       /* argument of current option                    */
00717   W32_DATA int   optind;       /* index of next argument; default=0: initialize */
00718   W32_DATA int   opterr;       /* 0=disable error messages; default=1: enable   */
00719   W32_DATA int   optopt;       /* option char returned from getopt()            */
00720   W32_DATA char *optswchar;    /* characters introducing options; default="-"   */
00721
00722   W32_DATA enum _optmode {
00723            GETOPT_UNIX,        /* options at start of argument list (default)   */
00724            GETOPT_ANY,         /* move non-options to the end                   */
00725            GETOPT_KEEP,        /* return options in order                       */
00726          } optmode;
00727
00728   W32_FUNC int getopt (int argc, char *const *argv, const char *opt_str);
00729 #endif
00730
00731
00732 /*
00733  * Statistics printing
00734  */
00735 W32_FUNC void print_mac_stats  (void);
00736 W32_FUNC void print_pkt_stats  (void);
00737 W32_FUNC void print_vjc_stats  (void);
00738 W32_FUNC void print_arp_stats  (void);
00739 W32_FUNC void print_pppoe_stats(void);
00740 W32_FUNC void print_ip4_stats  (void);
00741 W32_FUNC void print_ip6_stats  (void);
00742 W32_FUNC void print_icmp_stats (void);
00743 W32_FUNC void print_igmp_stats (void);
00744 W32_FUNC void print_udp_stats  (void);
00745 W32_FUNC void print_tcp_stats  (void);
00746 W32_FUNC void print_all_stats  (void);
00747 W32_FUNC void reset_stats      (void);
00748
00749 #if !defined(WATT32_BUILD)
00750 W32_FUNC int sock_stats (void *s, DWORD *days, WORD *inactive,
00751                          WORD *cwindow, DWORD *avg,  DWORD *sd);
00752 #endif
00753
00754
00755 /*
00756  * Controlling timer interrupt handler for background processing.
00757  * Not recommended, little tested
00758  */
00759 W32_FUNC void backgroundon  (void);
00760 W32_FUNC void backgroundoff (void);
00761 W32_FUNC void backgroundfn  (VoidProc func);
00762
00763
00764 /*
00765  * Misc functions
00766  */
00767 #if !defined(__DJGPP__) && !(defined(__WATCOMC__) && (__WATCOMC__ >= 1240))
00768   #define ffs W32_NAMESPACE (ffs)
00769   W32_FUNC int ffs (int mask);
00770 #endif
00771
00772 #if defined (__HIGHC__)
00773   W32_FUNC int system (const char *cmd);
00774   pragma Alias (system, "_mw_watt_system");
00775 #endif
00776
00777 W32_FUNC unsigned Random (unsigned a, unsigned b);
00778
00779
00780 /*
00781  * Tracing to RS-232 serial port, by Gundolf von Bachhaus <GBachhaus@gmx.net>
00782  * Watt-32 library must be compiled with `USE_RS232_DBG' (see .\src\config.h)
00783  */
00784 W32_FUNC int            trace2com_init (WORD portAddress, DWORD baudRate);
00785 W32_FUNC int MS_CDECL __trace2com      (const char *fmt, ...)
00786   #if defined(__GNUC__)
00787   __attribute__((format(printf,1,2)))
00788   #endif
00789   ;
00790
00791 #ifdef __cplusplus
00792 }
00793 #endif
00794
00795 #endif  /* RC_INVOKED */
00796 #endif  /* __WATT_TCP_H */
Generated on Wed Jan 25 15:42:33 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/WINSOCK2.H Source File

inc/WINSOCK2.H

00001 #ifndef _WATT32_FAKE_WINSOCK2_H
00002 #define _WATT32_FAKE_WINSOCK2_H
00003
00004 #ifndef __SYS_W32API_H
00005 #include <sys/w32api.h>
00006 #endif
00007
00008 #ifndef __SYS_SOCKET_H
00009 #include <sys/socket.h>
00010 #endif
00011
00012 #ifndef __SYS_WERRNO_H
00013 #include <sys/werrno.h>
00014 #endif
00015
00016 #if !defined(WIN32) && !defined(_WIN32)
00017 #error This file is only for Watt-32 targeting Windows programs.
00018 #endif
00019
00020 #if !defined(_WATT32_FAKE_WINSOCK_H)
00021
00022 #define WSADESCRIPTION_LEN  256
00023 #define WSASYS_STATUS_LEN   128
00024
00025 typedef struct WSAData {
00026         unsigned short wVersion;
00027         unsigned short wHighVersion;
00028         char           szDescription[WSADESCRIPTION_LEN+1];
00029         char           szSystemStatus[WSASYS_STATUS_LEN+1];
00030         unsigned short iMaxSockets;
00031         unsigned short iMaxUdpDg;
00032         char          *lpVendorInfo;
00033       } WSADATA, *LPWSADATA;
00034
00035 W32_FUNC int __stdcall WSAStartup (unsigned short wVersionRequired,
00036                                    WSADATA *WSAData);
00037
00038
00039 #ifndef FD_SETSIZE
00040 #define FD_SETSIZE  64
00041 #endif
00042
00043 /*
00044  * Needed if user compiled with the normal <winsock*.h> and just relinked
00045  * with Watt-32 (import) library.
00046  */
00047 typedef struct winsock_fd_set {
00048         unsigned int fd_count;               /* how many are SET? */
00049         int          fd_array [FD_SETSIZE];  /* an array of sockets */
00050       } winsock_fd_set;
00051
00052 W32_FUNC int __stdcall __WSAFDIsSet (int s, winsock_fd_set *fd);
00053
00054 #endif  /* _WATT32_FAKE_WINSOCK_H */
00055 #endif  /* _WATT32_FAKE_WINSOCK2_H */
00056
Generated on Wed Jan 25 15:42:34 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/WS2TCPIP.H Source File

inc/WS2TCPIP.H

00001 #ifndef _WATT32_FAKE_WS2TCPIP_H
00002 #define _WATT32_FAKE_WS2TCPIP_H
00003
00004 #ifndef __SYS_SOCKET_H
00005 #include <sys/socket.h>
00006 #endif
00007
00008 #if !defined(WIN32) && !defined(_WIN32)
00009 #error This file is only for Watt-32 targeting Windows programs.
00010 #endif
00011
00012 #endif
00013
Generated on Wed Jan 25 15:42:34 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/arpa/FTP.H Source File

inc/arpa/FTP.H

Go to the documentation of this file.
00001
00005 /*
00006  * Copyright (c) 1983, 1989 Regents of the University of California.
00007  * All rights reserved.
00008  *
00009  * Redistribution and use in source and binary forms, with or without
00010  * modification, are permitted provided that the following conditions
00011  * are met:
00012  * 1. Redistributions of source code must retain the above copyright
00013  *    notice, this list of conditions and the following disclaimer.
00014  * 2. Redistributions in binary form must reproduce the above copyright
00015  *    notice, this list of conditions and the following disclaimer in the
00016  *    documentation and/or other materials provided with the distribution.
00017  * 3. All advertising materials mentioning features or use of this software
00018  *    must display the following acknowledgement:
00019  *      This product includes software developed by the University of
00020  *      California, Berkeley and its contributors.
00021  * 4. Neither the name of the University nor the names of its contributors
00022  *    may be used to endorse or promote products derived from this software
00023  *    without specific prior written permission.
00024  *
00025  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
00026  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00027  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00028  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
00029  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00030  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00031  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00032  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00033  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00034  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00035  * SUCH DAMAGE.
00036  *
00037  *      @(#)ftp.h       8.1 (Berkeley) 6/2/93
00038  */
00039
00040 #ifndef __ARPA_FTP_H
00041 #define __ARPA_FTP_H
00042
00043 /* Definitions for FTP; see RFC-765. */
00044
00045 /*
00046  * Reply codes.
00047  */
00048 #define PRELIM          1       /* positive preliminary */
00049 #define COMPLETE        2       /* positive completion */
00050 #define CONTINUE        3       /* positive intermediate */
00051 #define TRANSIENT       4       /* transient negative completion */
00052 #undef  ERROR                   /* <wingdi.h> */
00053 #define ERROR           5       /* permanent negative completion */
00054
00055 /*
00056  * Type codes
00057  */
00058 #define TYPE_A          1       /* ASCII */
00059 #define TYPE_E          2       /* EBCDIC */
00060 #define TYPE_I          3       /* image */
00061 #define TYPE_L          4       /* local byte size */
00062
00063 #ifdef FTP_NAMES
00064 const char *typenames[] =  {"0", "ASCII", "EBCDIC", "Image", "Local" };
00065 #endif
00066
00067 /*
00068  * Form codes
00069  */
00070 #define FORM_N          1       /* non-print */
00071 #define FORM_T          2       /* telnet format effectors */
00072 #define FORM_C          3       /* carriage control (ASA) */
00073 #ifdef FTP_NAMES
00074 const char *formnames[] =  {"0", "Nonprint", "Telnet", "Carriage-control" };
00075 #endif
00076
00077 /*
00078  * Structure codes
00079  */
00080 #define STRU_F          1       /* file (no record structure) */
00081 #define STRU_R          2       /* record structure */
00082 #define STRU_P          3       /* page structure */
00083 #ifdef FTP_NAMES
00084 const char *strunames[] =  {"0", "File", "Record", "Page" };
00085 #endif
00086
00087 /*
00088  * Mode types
00089  */
00090 #define MODE_S          1       /* stream */
00091 #define MODE_B          2       /* block */
00092 #define MODE_C          3       /* compressed */
00093 #ifdef FTP_NAMES
00094 const char *modenames[] =  {"0", "Stream", "Block", "Compressed" };
00095 #endif
00096
00097 /*
00098  * Protection levels
00099  */
00100 #define PROT_C          1       /* clear */
00101 #define PROT_S          2       /* safe */
00102 #define PROT_P          3       /* private */
00103 #define PROT_E          4       /* confidential */
00104
00105 #ifdef FTP_NAMES
00106 const char *levelnames[] =  {"0", "Clear", "Safe", "Private", "Confidential" };
00107 #endif
00108
00109 #if defined(KERBEROS) && defined(NOENCRYPTION)
00110  /* Define away krb_rd_priv and krb_mk_priv.  Don't need them anyway.
00111   * This might not be the best place for this ...
00112   */
00113   #define krb_rd_priv(o,l,ses,s,h,c,m) krb_rd_safe(o,l,s,h,c,m)
00114   #define krb_mk_priv(i,o,l,ses,s,h,c) krb_mk_safe(i,o,l,s,h,c)
00115 #endif
00116
00117 /*
00118  * Record Tokens
00119  */
00120 #define REC_ESC         '\377'  /* Record-mode Escape */
00121 #define REC_EOR         '\001'  /* Record-mode End-of-Record */
00122 #define REC_EOF         '\002'  /* Record-mode End-of-File */
00123
00124 /*
00125  * Block Header
00126  */
00127 #define BLK_EOR         0x80    /* Block is End-of-Record */
00128 #define BLK_EOF         0x40    /* Block is End-of-File */
00129 #define BLK_ERRORS      0x20    /* Block is suspected of containing errors */
00130 #define BLK_RESTART     0x10    /* Block is Restart Marker */
00131
00132 #define BLK_BYTECOUNT   2       /* Bytes in this block */
00133
00134 #endif
Generated on Wed Jan 25 15:42:32 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/arpa/INET.H Source File

inc/arpa/INET.H

Go to the documentation of this file.
00001
00005 /* Modified for emx by hv and em 1994
00006  *
00007  * Copyright (c) 1983, 1993
00008  *      The Regents of the University of California.  All rights reserved.
00009  *
00010  * Redistribution and use in source and binary forms, with or without
00011  * modification, are permitted provided that the following conditions
00012  * are met:
00013  * 1. Redistributions of source code must retain the above copyright
00014  *    notice, this list of conditions and the following disclaimer.
00015  * 2. Redistributions in binary form must reproduce the above copyright
00016  *    notice, this list of conditions and the following disclaimer in the
00017  *    documentation and/or other materials provided with the distribution.
00018  * 3. All advertising materials mentioning features or use of this software
00019  *    must display the following acknowledgement:
00020  *      This product includes software developed by the University of
00021  *      California, Berkeley and its contributors.
00022  * 4. Neither the name of the University nor the names of its contributors
00023  *    may be used to endorse or promote products derived from this software
00024  *    without specific prior written permission.
00025  *
00026  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
00027  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00028  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00029  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
00030  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00031  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00032  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00033  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00034  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00035  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00036  * SUCH DAMAGE.
00037  *
00038  *      @(#)inet.h      8.1 (Berkeley) 6/2/93
00039  *      From: Id: inet.h,v 8.5 1997/01/29 08:48:09 vixie Exp $
00040  */
00041
00042 #ifndef __ARPA_INET_H
00043 #define __ARPA_INET_H
00044
00045 #ifndef __SYS_W32API_H
00046 #include <sys/w32api.h>
00047 #endif
00048
00049 #ifndef __SYS_TYPES_H
00050 #include <sys/wtypes.h>
00051 #endif
00052
00053 #ifndef __SYS_CDEFS_H
00054 #include <sys/cdefs.h>
00055 #endif
00056
00057 #ifndef __NETINET_IN_H
00058 #include <netinet/in.h>
00059 #endif
00060
00061
00062 __BEGIN_DECLS
00063
00064 W32_FUNC int            ascii2addr   (int, const char *, void *);
00065 W32_FUNC char          *addr2ascii   (int, const void *, int, char *);
00066
00067 W32_FUNC struct in_addr W32_CALL inet_makeaddr (u_long, u_long);
00068 W32_FUNC u_long         W32_CALL inet_addr     (const char*);
00069 W32_FUNC u_long         W32_CALL inet_lnaof    (struct in_addr);
00070 W32_FUNC u_long         W32_CALL inet_netof    (struct in_addr);
00071 W32_FUNC u_long         W32_CALL inet_network  (const char*);
00072 W32_FUNC int            W32_CALL inet_aton     (const char *s, struct in_addr *adr);
00073 W32_FUNC char*          W32_CALL inet_ntoa     (struct in_addr);
00074 W32_FUNC char*          W32_CALL inet_ntoa_r   (struct in_addr adr, char *buf, int buflen);
00075
00076 W32_FUNC char          *W32_CALL inet_nsap_ntoa(int binlen, const u_char *binary, char *ascii);
00077 W32_FUNC u_int          W32_CALL inet_nsap_addr(const char *ascii, u_char *binary, int maxlen);
00078 W32_FUNC const char    *W32_CALL inet_ntop     (int af, const void *src, char *dst, size_t size);
00079 W32_FUNC int            W32_CALL inet_pton     (int af, const char *src, void *dst);
00080
00081 __END_DECLS
00082
00083 #endif  /* !__ARPA_INET_H_ */
Generated on Wed Jan 25 15:42:32 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/arpa/NAMESER.H Source File

inc/arpa/NAMESER.H

Go to the documentation of this file.
00001
00005 /*
00006  * Copyright (c) 1983, 1989, 1993
00007  *        The Regents of the University of California.  All rights reserved.
00008  *
00009  * Redistribution and use in source and binary forms, with or without
00010  * modification, are permitted provided that the following conditions
00011  * are met:
00012  * 1. Redistributions of source code must retain the above copyright
00013  *    notice, this list of conditions and the following disclaimer.
00014  * 2. Redistributions in binary form must reproduce the above copyright
00015  *    notice, this list of conditions and the following disclaimer in the
00016  *    documentation and/or other materials provided with the distribution.
00017  * 3. All advertising materials mentioning features or use of this software
00018  *    must display the following acknowledgement:
00019  *        This product includes software developed by the University of
00020  *        California, Berkeley and its contributors.
00021  * 4. Neither the name of the University nor the names of its contributors
00022  *    may be used to endorse or promote products derived from this software
00023  *    without specific prior written permission.
00024  *
00025  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
00026  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00027  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00028  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
00029  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00030  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00031  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00032  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00033  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00034  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00035  * SUCH DAMAGE.
00036  *
00037  * -
00038  * Portions Copyright (c) 1993 by Digital Equipment Corporation.
00039  *
00040  * Permission to use, copy, modify, and distribute this software for any
00041  * purpose with or without fee is hereby granted, provided that the above
00042  * copyright notice and this permission notice appear in all copies, and that
00043  * the name of Digital Equipment Corporation not be used in advertising or
00044  * publicity pertaining to distribution of the document or software without
00045  * specific, written prior permission.
00046  *
00047  * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
00048  * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
00049  * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
00050  * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
00051  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
00052  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
00053  * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
00054  * SOFTWARE.
00055  * -
00056  * --Copyright--
00057  *
00058  *      @(#)nameser.h        8.2 (Berkeley) 2/16/94
00059  *        From Id: nameser.h,v 4.9.1.15 1994/07/19 22:51:24 vixie Exp
00060  *        $Id: nameser.h,v 1.8 1996/08/29 20:01:00 peter Exp $
00061  */
00062
00063 #ifndef __ARPA_NAMESER_H
00064 #define __ARPA_NAMESER_H
00065
00066 #ifndef __SYS_W32API_H
00067 #include <sys/w32api.h>
00068 #endif
00069
00070 #ifndef __SYS_PARAM_H
00071 #include <sys/param.h>
00072 #endif
00073
00074 #ifndef __SYS_WTYPES_H
00075 #include <sys/wtypes.h>
00076 #endif
00077
00078 #ifndef __SYS_CDEFS_H
00079 #include <sys/cdefs.h>
00080 #endif
00081
00082 /*
00083  * revision information.  this is the release date in YYYYMMDD format.
00084  * it can change every day so the right thing to do with it is use it
00085  * in preprocessor commands such as "#if (__BIND > 19931104)".  do not
00086  * compare for equality; rather, use it to determine whether your resolver
00087  * is new enough to contain a certain feature.
00088  */
00089
00090 #define __BIND    19960801  /* interface version stamp */
00091
00092 /*
00093  * Define constants based on rfc883
00094  */
00095 #define PACKETSZ     512               /* maximum packet size */
00096 #define MAXDNAME    1025               /* maximum domain name */
00097 #define MAXCDNAME    255               /* maximum compressed domain name */
00098 #define MAXLABEL      63               /* maximum length of domain label */
00099 #define HFIXEDSZ      12               /* #/bytes of fixed data in header */
00100 #define QFIXEDSZ       4               /* #/bytes of fixed data in query */
00101 #define RRFIXEDSZ     10               /* #/bytes of fixed data in r record */
00102 #define INT32SZ        4               /* for systems without 32-bit ints */
00103 #define INT16SZ        2               /* for systems without 16-bit ints */
00104 #define INADDRSZ       4               /* IPv4 T_A */
00105 #define IN6ADDRSZ     16               /* IPv6 T_AAAA */
00106
00107
00108 /*
00109  * Internet nameserver port number
00110  */
00111 #define NAMESERVER_PORT  53
00112
00113 /*
00114  * Currently defined opcodes
00115  */
00116 #define QUERY          0x0             /* standard query */
00117 #define IQUERY         0x1             /* inverse query */
00118 #define STATUS         0x2             /* nameserver status query */
00119 #define NS_NOTIFY_OP   0x4             /* notify secondary of SOA change */
00120
00121 #ifdef ALLOW_UPDATES
00122         /* non standard - supports ALLOW_UPDATES stuff from Mike Schwartz */
00123 # define UPDATEA       0x9             /* add resource record */
00124 # define UPDATED       0xa             /* delete a specific resource record */
00125 # define UPDATEDA      0xb             /* delete all named resource record */
00126 # define UPDATEM       0xc             /* modify a specific resource record */
00127 # define UPDATEMA      0xd             /* modify all named resource record */
00128 # define ZONEINIT      0xe             /* initial zone transfer */
00129 # define ZONEREF       0xf             /* incremental zone referesh */
00130 #endif
00131
00132 /*
00133  * Currently defined response codes
00134  */
00135 #if !defined(WIN32) && !defined(_WIN32)  /* <winerror.h> value is okay */
00136 #define NOERROR        0               /* no error */
00137 #endif
00138 #define FORMERR        1               /* format error */
00139 #define SERVFAIL       2               /* server failure */
00140 #define NXDOMAIN       3               /* non existent domain */
00141 #define NOTIMP         4               /* not implemented */
00142 #define REFUSED        5               /* query refused */
00143
00144 #ifdef ALLOW_UPDATES
00145         /* non standard */
00146 # define NOCHANGE      0xf             /* update failed to change db */
00147 #endif
00148
00149 /*
00150  * Type values for resources and queries
00151  */
00152 #define T_A            1               /* host address */
00153 #define T_NS           2               /* authoritative server */
00154 #define T_MD           3               /* mail destination */
00155 #define T_MF           4               /* mail forwarder */
00156 #define T_CNAME        5               /* canonical name */
00157 #define T_SOA          6               /* start of authority zone */
00158 #define T_MB           7               /* mailbox domain name */
00159 #define T_MG           8               /* mail group member */
00160 #define T_MR           9               /* mail rename name */
00161 #define T_NULL         10              /* null resource record */
00162 #define T_WKS          11              /* well known service */
00163 #define T_PTR          12              /* domain name pointer */
00164 #define T_HINFO        13              /* host information */
00165 #define T_MINFO        14              /* mailbox information */
00166 #define T_MX           15              /* mail routing information */
00167 #define T_TXT          16              /* text strings */
00168 #define T_RP           17              /* responsible person */
00169 #define T_AFSDB        18              /* AFS cell database */
00170 #define T_X25          19              /* X_25 calling address */
00171 #define T_ISDN         20              /* ISDN calling address */
00172 #define T_RT           21              /* router */
00173 #define T_NSAP         22              /* NSAP address */
00174 #define T_NSAP_PTR     23              /* reverse NSAP lookup (deprecated) */
00175 #define T_SIG          24              /* security signature */
00176 #define T_KEY          25              /* security key */
00177 #define T_PX           26              /* X.400 mail mapping */
00178 #define T_GPOS         27              /* geographical position (withdrawn) */
00179 #define T_AAAA         28              /* IP6 Address */
00180 #define T_LOC          29              /* Location Information */
00181 #define T_NXT          30              /* Next Valid Name in Zone */
00182 #define T_EID          31              /* Endpoint identifier */
00183 #define T_NIMLOC       32              /* Nimrod locator */
00184 #define T_SRV          33              /* Server selection */
00185 #define T_ATMA         34              /* ATM Address */
00186 #define T_NAPTR        35              /* Naming Authority PoinTeR */
00187         /* non standard */
00188 #define T_UINFO       100              /* user (finger) information */
00189 #define T_UID         101              /* user ID */
00190 #define T_GID         102              /* group ID */
00191 #define T_UNSPEC      103              /* Unspecified format (binary data) */
00192         /* Query type values which do not appear in resource records */
00193 #define T_IXFR        251              /* incremental zone transfer */
00194 #define T_AXFR        252              /* transfer zone of authority */
00195 #define T_MAILB       253              /* transfer mailbox records */
00196 #define T_MAILA       254              /* transfer mail agent records */
00197 #define T_ANY         255              /* wildcard match */
00198
00199 #define T_WINS        0xFF01           /* WINS name lookup */
00200 #define T_WINSR       0xFF02           /* WINS reverse lookup */
00201
00202 /*
00203  * Values for class field
00204  */
00205
00206 #define C_IN          1                /* the arpa internet */
00207 #define C_CHAOS       3                /* for chaos net (MIT) */
00208 #define C_HS          4                /* for Hesiod name server (MIT) (XXX) */
00209         /* Query class values which do not appear in resource records */
00210 #define C_ANY         255              /* wildcard match */
00211
00212 /*
00213  * Status return codes for T_UNSPEC conversion routines
00214  */
00215 #define CONV_SUCCESS    0
00216 #define CONV_OVERFLOW   (-1)
00217 #define CONV_BADFMT     (-2)
00218 #define CONV_BADCKSUM   (-3)
00219 #define CONV_BADBUFLEN  (-4)
00220
00221 #include <sys/packon.h>
00222
00223 /*
00224  * Structure for query header.  The order of the fields is machine- and
00225  * compiler-dependent, depending on the byte/bit order and the layout
00226  * of bit fields.  We use bit fields only in int variables, as this
00227  * is all ANSI requires.  This requires a somewhat confusing rearrangement.
00228  */
00229
00230 typedef struct {
00231         unsigned  id :16;          /* query identification number */
00232
00233         /* fields in third byte */
00234         unsigned  rd :1;           /* recursion desired */
00235         unsigned  tc :1;           /* truncated message */
00236         unsigned  aa :1;           /* authoritative answer */
00237         unsigned  opcode :4;       /* purpose of message */
00238         unsigned  qr :1;           /* response flag */
00239
00240         /* fields in fourth byte */
00241         unsigned  rcode :4;        /* response code */
00242         unsigned  cd: 1;           /* checking disabled by resolver */
00243         unsigned  ad: 1;           /* authentic data from named */
00244         unsigned  unused :1;       /* unused bits (MBZ as of 4.9.3a3) */
00245         unsigned  ra :1;           /* recursion available */
00246
00247         /* remaining bytes */
00248         unsigned  qdcount :16;     /* number of question entries */
00249         unsigned  ancount :16;     /* number of answer entries */
00250         unsigned  nscount :16;     /* number of authority entries */
00251         unsigned  arcount :16;     /* number of resource entries */
00252       } HEADER;
00253
00254
00255 /*
00256  * Defines for handling compressed domain names
00257  */
00258 #define INDIR_MASK  0xc0
00259
00260 /*
00261  * Structure for passing resource records around.
00262  */
00263 struct rrec {
00264        u_short  r_zone;            /* zone number */
00265        u_short  r_class;           /* class number */
00266        u_short  r_type;            /* type number */
00267        u_long   r_ttl;             /* time to live */
00268        int      r_size;            /* size of data area */
00269        char    *r_data;            /* pointer to data */
00270      };
00271
00272 #include <sys/packoff.h>
00273
00274
00275 __BEGIN_DECLS
00276
00277 W32_FUNC u_short _getshort (const u_char *);
00278 W32_FUNC u_long  _getlong  (const u_char *);
00279
00280 __END_DECLS
00281
00282 /*
00283  * Inline versions of get/put short/long.  Pointer is advanced.
00284  *
00285  * These macros demonstrate the property of C whereby it can be
00286  * portable or it can be elegant but rarely both.
00287  */
00288 #define GETSHORT(s, cp) do { \
00289         register u_char *t_cp = (u_char *)(cp); \
00290         (s) = ((u_short)t_cp[0] << 8) \
00291             | ((u_short)t_cp[1]); \
00292         (cp) += INT16SZ; \
00293       } while (0)
00294
00295 #define GETLONG(l, cp) do { \
00296         register u_char *t_cp = (u_char *)(cp); \
00297         (l) = ((u_long)t_cp[0] << 24) \
00298             | ((u_long)t_cp[1] << 16) \
00299             | ((u_long)t_cp[2] << 8) \
00300             | ((u_long)t_cp[3]); \
00301         (cp) += INT32SZ; \
00302       } while (0)
00303
00304 #define PUTSHORT(s, cp) do { \
00305         register u_short t_s = (u_short)(s); \
00306         register u_char *t_cp = (u_char *)(cp); \
00307         *t_cp++ = (u_char) (t_s >> 8); \
00308         *t_cp   = (u_char) t_s; \
00309         (cp) += INT16SZ; \
00310       } while (0)
00311
00312 #define PUTLONG(l, cp) do { \
00313         register u_long t_l = (u_long)(l); \
00314         register u_char *t_cp = (u_char *)(cp); \
00315         *t_cp++ = (u_char) (t_l >> 24); \
00316         *t_cp++ = (u_char) (t_l >> 16); \
00317         *t_cp++ = (u_char) (t_l >> 8); \
00318         *t_cp   = (u_char) t_l; \
00319         (cp) += INT32SZ; \
00320       } while (0)
00321
00322 #endif
Generated on Wed Jan 25 15:42:32 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/arpa/TELNET.H Source File

inc/arpa/TELNET.H

Go to the documentation of this file.
00001
00005 /*
00006  * Copyright (c) 1983, 1993
00007  *      The Regents of the University of California.  All rights reserved.
00008  *
00009  * Redistribution and use in source and binary forms, with or without
00010  * modification, are permitted provided that the following conditions
00011  * are met:
00012  * 1. Redistributions of source code must retain the above copyright
00013  *    notice, this list of conditions and the following disclaimer.
00014  * 2. Redistributions in binary form must reproduce the above copyright
00015  *    notice, this list of conditions and the following disclaimer in the
00016  *    documentation and/or other materials provided with the distribution.
00017  * 3. All advertising materials mentioning features or use of this software
00018  *    must display the following acknowledgement:
00019  *      This product includes software developed by the University of
00020  *      California, Berkeley and its contributors.
00021  * 4. Neither the name of the University nor the names of its contributors
00022  *    may be used to endorse or promote products derived from this software
00023  *    without specific prior written permission.
00024  *
00025  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
00026  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00027  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00028  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
00029  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00030  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00031  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00032  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00033  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00034  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00035  * SUCH DAMAGE.
00036  *
00037  *      @(#)telnet.h    8.2 (Berkeley) 12/15/93
00038  */
00039
00040 #ifndef __ARPA_TELNET_H
00041 #define __ARPA_TELNET_H
00042
00043 #ifndef __SYS_W32API_H
00044 #include <sys/w32api.h>
00045 #endif
00046
00047 /*
00048  * Definitions for the TELNET protocol.
00049  */
00050 #define IAC     255             /* interpret as command: */
00051 #define DONT    254             /* you are not to use option */
00052 #define DO      253             /* please, you use option */
00053 #define WONT    252             /* I won't use option */
00054 #define WILL    251             /* I will use option */
00055 #define SB      250             /* interpret as subnegotiation */
00056 #define GA      249             /* you may reverse the line */
00057 #define EL      248             /* erase the current line */
00058 #define EC      247             /* erase the current character */
00059 #define AYT     246             /* are you there */
00060 #define AO      245             /* abort output--but let prog finish */
00061 #define IP      244             /* interrupt process--permanently */
00062 #define BREAK   243             /* break */
00063 #define DM      242             /* data mark--for connect. cleaning */
00064 #define NOP     241             /* nop */
00065 #define SE      240             /* end sub negotiation */
00066 #define EOR     239             /* end of record (transparent mode) */
00067 #define ABORT   238             /* Abort process */
00068 #define SUSP    237             /* Suspend process */
00069 #define xEOF    236             /* End of file: EOF is already used... */
00070
00071 #define SYNCH   242             /* for telfunc calls */
00072
00073 #ifdef TELCMDS
00074   const char *telcmds[] = {
00075              "EOF", "SUSP", "ABORT", "EOR",
00076              "SE", "NOP", "DMARK", "BRK", "IP", "AO", "AYT", "EC",
00077              "EL", "GA", "SB", "WILL", "WONT", "DO", "DONT", "IAC", 0
00078            };
00079 #else
00080   W32_DATA const char *telcmds[];
00081 #endif
00082
00083 #define TELCMD_FIRST    xEOF
00084 #define TELCMD_LAST     IAC
00085 #define TELCMD_OK(x)    ((unsigned int)(x) <= TELCMD_LAST && \
00086                          (unsigned int)(x) >= TELCMD_FIRST)
00087 #define TELCMD(x)       telcmds[(x)-TELCMD_FIRST]
00088
00089 /* telnet options
00090  */
00091 #define TELOPT_BINARY         0   /* 8-bit data path */
00092 #define TELOPT_ECHO           1   /* echo */
00093 #define TELOPT_RCP            2   /* prepare to reconnect */
00094 #define TELOPT_SGA            3   /* suppress go ahead */
00095 #define TELOPT_NAMS           4   /* approximate message size */
00096 #define TELOPT_STATUS         5   /* give status */
00097 #define TELOPT_TM             6   /* timing mark */
00098 #define TELOPT_RCTE           7   /* remote controlled transmission and echo */
00099 #define TELOPT_NAOL           8   /* negotiate about output line width */
00100 #define TELOPT_NAOP           9   /* negotiate about output page size */
00101 #define TELOPT_NAOCRD         10  /* negotiate about CR disposition */
00102 #define TELOPT_NAOHTS         11  /* negotiate about horizontal tabstops */
00103 #define TELOPT_NAOHTD         12  /* negotiate about horizontal tab disposition */
00104 #define TELOPT_NAOFFD         13  /* negotiate about formfeed disposition */
00105 #define TELOPT_NAOVTS         14  /* negotiate about vertical tab stops */
00106 #define TELOPT_NAOVTD         15  /* negotiate about vertical tab disposition */
00107 #define TELOPT_NAOLFD         16  /* negotiate about output LF disposition */
00108 #define TELOPT_XASCII         17  /* extended ascic character set */
00109 #define TELOPT_LOGOUT         18  /* force logout */
00110 #define TELOPT_BM             19  /* byte macro */
00111 #define TELOPT_DET            20  /* data entry terminal */
00112 #define TELOPT_SUPDUP         21  /* supdup protocol */
00113 #define TELOPT_SUPDUPOUTPUT   22  /* supdup output */
00114 #define TELOPT_SNDLOC         23  /* send location */
00115 #define TELOPT_TTYPE          24  /* terminal type */
00116 #define TELOPT_EOR            25  /* end or record */
00117 #define TELOPT_TUID           26  /* TACACS user identification */
00118 #define TELOPT_OUTMRK         27  /* output marking */
00119 #define TELOPT_TTYLOC         28  /* terminal location number */
00120 #define TELOPT_3270REGIME     29  /* 3270 regime */
00121 #define TELOPT_X3PAD          30  /* X.3 PAD */
00122 #define TELOPT_NAWS           31  /* window size */
00123 #define TELOPT_TSPEED         32  /* terminal speed */
00124 #define TELOPT_LFLOW          33  /* remote flow control */
00125 #define TELOPT_LINEMODE       34  /* Linemode option */
00126 #define TELOPT_XDISPLOC       35  /* X Display Location */
00127 #define TELOPT_OLD_ENVIRON    36  /* Old - Environment variables */
00128 #define TELOPT_AUTHENTICATION 37  /* Authenticate */
00129 #define TELOPT_ENCRYPT        38  /* Encryption option */
00130 #define TELOPT_NEW_ENVIRON    39  /* New - Environment variables */
00131 #define TELOPT_EXOPL         255  /* extended-options-list */
00132
00133 #define NTELOPTS   (1+TELOPT_NEW_ENVIRON)
00134
00135 #ifdef TELOPTS
00136   const char *telopts[NTELOPTS+1] = {
00137         "BINARY", "ECHO", "RCP", "SUPPRESS GO AHEAD", "NAME",
00138         "STATUS", "TIMING MARK", "RCTE", "NAOL", "NAOP",
00139         "NAOCRD", "NAOHTS", "NAOHTD", "NAOFFD", "NAOVTS",
00140         "NAOVTD", "NAOLFD", "EXTEND ASCII", "LOGOUT", "BYTE MACRO",
00141         "DATA ENTRY TERMINAL", "SUPDUP", "SUPDUP OUTPUT",
00142         "SEND LOCATION", "TERMINAL TYPE", "END OF RECORD",
00143         "TACACS UID", "OUTPUT MARKING", "TTYLOC",
00144         "3270 REGIME", "X.3 PAD", "NAWS", "TSPEED", "LFLOW",
00145         "LINEMODE", "XDISPLOC", "OLD-ENVIRON", "AUTHENTICATION",
00146         "ENCRYPT", "NEW-ENVIRON", 0
00147       };
00148   #define TELOPT_FIRST    TELOPT_BINARY
00149   #define TELOPT_LAST     TELOPT_NEW_ENVIRON
00150   #define TELOPT_OK(x)    ((unsigned int)(x) <= TELOPT_LAST)
00151   #define TELOPT(x)       telopts[(x)-TELOPT_FIRST]
00152 #endif
00153
00154 /* sub-option qualifiers
00155  */
00156 #define TELQUAL_IS         0       /* option is... */
00157 #define TELQUAL_SEND       1       /* send option */
00158 #define TELQUAL_INFO       2       /* ENVIRON: informational version of IS */
00159 #define TELQUAL_REPLY      2       /* AUTHENTICATION: client version of IS */
00160 #define TELQUAL_NAME       3       /* AUTHENTICATION: client version of IS */
00161
00162 #define LFLOW_OFF          0       /* Disable remote flow control */
00163 #define LFLOW_ON           1       /* Enable remote flow control */
00164 #define LFLOW_RESTART_ANY  2       /* Restart output on any char */
00165 #define LFLOW_RESTART_XON  3       /* Restart output only on XON */
00166
00167 /* LINEMODE suboptions
00168  */
00169 #define LM_MODE         1
00170 #define LM_FORWARDMASK  2
00171 #define LM_SLC          3
00172
00173 #define MODE_EDIT       0x01
00174 #define MODE_TRAPSIG    0x02
00175 #define MODE_ACK        0x04
00176 #define MODE_SOFT_TAB   0x08
00177 #define MODE_LIT_ECHO   0x10
00178
00179 #define MODE_MASK       0x1f
00180
00181 /* Not part of protocol, but needed to simplify things...
00182  */
00183 #define MODE_FLOW       0x0100
00184 #define MODE_ECHO       0x0200
00185 #define MODE_INBIN      0x0400
00186 #define MODE_OUTBIN     0x0800
00187 #define MODE_FORCE      0x1000
00188
00189 #define SLC_SYNCH       1
00190 #define SLC_BRK         2
00191 #define SLC_IP          3
00192 #define SLC_AO          4
00193 #define SLC_AYT         5
00194 #define SLC_EOR         6
00195 #define SLC_ABORT       7
00196 #define SLC_EOF         8
00197 #define SLC_SUSP        9
00198 #define SLC_EC          10
00199 #define SLC_EL          11
00200 #define SLC_EW          12
00201 #define SLC_RP          13
00202 #define SLC_LNEXT       14
00203 #define SLC_XON         15
00204 #define SLC_XOFF        16
00205 #define SLC_FORW1       17
00206 #define SLC_FORW2       18
00207 #define SLC_MCL         19
00208 #define SLC_MCR         20
00209 #define SLC_MCWL        21
00210 #define SLC_MCWR        22
00211 #define SLC_MCBOL       23
00212 #define SLC_MCEOL       24
00213 #define SLC_INSRT       25
00214 #define SLC_OVER        26
00215 #define SLC_ECR         27
00216 #define SLC_EWR         28
00217 #define SLC_EBOL        29
00218 #define SLC_EEOL        30
00219
00220 #define NSLC            30
00221
00222 /*
00223  * For backwards compatability, we define SLC_NAMES to be the
00224  * list of names if SLC_NAMES is not defined.
00225  */
00226 #define SLC_NAMELIST    "0", "SYNCH", "BRK", "IP", "AO", "AYT", "EOR",  \
00227                         "ABORT", "EOF", "SUSP", "EC", "EL", "EW", "RP", \
00228                         "LNEXT", "XON", "XOFF", "FORW1", "FORW2",       \
00229                         "MCL", "MCR", "MCWL", "MCWR", "MCBOL",          \
00230                         "MCEOL", "INSRT", "OVER", "ECR", "EWR",         \
00231                         "EBOL", "EEOL",                                 \
00232                         0
00233 #ifdef SLC_NAMES
00234   const char *slc_names[] = { SLC_NAMELIST };
00235 #else
00236   W32_DATA const char *slc_names[];
00237   #define SLC_NAMES SLC_NAMELIST
00238 #endif
00239
00240 #define SLC_NAME_OK(x)  ((unsigned int)(x) <= NSLC)
00241 #define SLC_NAME(x)     slc_names[x]
00242
00243 #define SLC_NOSUPPORT   0
00244 #define SLC_CANTCHANGE  1
00245 #define SLC_VARIABLE    2
00246 #define SLC_DEFAULT     3
00247 #define SLC_LEVELBITS   0x03
00248
00249 #define SLC_FUNC        0
00250 #define SLC_FLAGS       1
00251 #define SLC_VALUE       2
00252
00253 #define SLC_ACK         0x80
00254 #define SLC_FLUSHIN     0x40
00255 #define SLC_FLUSHOUT    0x20
00256
00257 #define OLD_ENV_VAR     1
00258 #define OLD_ENV_VALUE   0
00259 #define NEW_ENV_VAR     0
00260 #define NEW_ENV_VALUE   1
00261 #define ENV_ESC         2
00262 #define ENV_USERVAR     3
00263
00264 /*
00265  * AUTHENTICATION suboptions
00266  */
00267
00268 /* Who is authenticating who ...
00269  */
00270 #define AUTH_WHO_CLIENT         0       /* Client authenticating server */
00271 #define AUTH_WHO_SERVER         1       /* Server authenticating client */
00272 #define AUTH_WHO_MASK           1
00273
00274 /* Amount of authentication done
00275  */
00276 #define AUTH_HOW_ONE_WAY        0
00277 #define AUTH_HOW_MUTUAL         2
00278 #define AUTH_HOW_MASK           2
00279
00280 #define AUTHTYPE_NULL           0
00281 #define AUTHTYPE_KERBEROS_V4    1
00282 #define AUTHTYPE_KERBEROS_V5    2
00283 #define AUTHTYPE_SPX            3
00284 #define AUTHTYPE_MINK           4
00285 #define AUTHTYPE_SRP            5
00286 #define AUTHTYPE_CNT            6
00287
00288 #define AUTHTYPE_TEST           99
00289
00290 #ifdef  AUTH_NAMES
00291   const char *authtype_names[] = {
00292              "NULL", "KERBEROS_V4", "KERBEROS_V5", "SPX", "MINK", "SRP", 0
00293            };
00294 #else
00295   W32_DATA const char *authtype_names[];
00296 #endif
00297
00298 #define AUTHTYPE_NAME_OK(x)     ((unsigned int)(x) < AUTHTYPE_CNT)
00299 #define AUTHTYPE_NAME(x)        authtype_names[x]
00300
00301 /*
00302  * ENCRYPTion suboptions
00303  */
00304 #define ENCRYPT_IS              0       /* I pick encryption type ... */
00305 #define ENCRYPT_SUPPORT         1       /* I support encryption types ... */
00306 #define ENCRYPT_REPLY           2       /* Initial setup response */
00307 #define ENCRYPT_START           3       /* Am starting to send encrypted */
00308 #define ENCRYPT_END             4       /* Am ending encrypted */
00309 #define ENCRYPT_REQSTART        5       /* Request you start encrypting */
00310 #define ENCRYPT_REQEND          6       /* Request you send encrypting */
00311 #define ENCRYPT_ENC_KEYID       7
00312 #define ENCRYPT_DEC_KEYID       8
00313 #define ENCRYPT_CNT             9
00314
00315 #define ENCTYPE_ANY             0
00316 #define ENCTYPE_DES_CFB64       1
00317 #define ENCTYPE_DES_OFB64       2
00318 #define ENCTYPE_CAST5_40_CFB64  8
00319 #define ENCTYPE_CAST5_40_OFB64  9
00320 #define ENCTYPE_CAST128_CFB64   10
00321 #define ENCTYPE_CAST128_OFB64   11
00322 #define ENCTYPE_CNT             12
00323
00324 #ifdef  ENCRYPT_NAMES
00325   const char *encrypt_names[] = {
00326         "IS", "SUPPORT", "REPLY", "START", "END",
00327         "REQUEST-START", "REQUEST-END", "ENC-KEYID", "DEC-KEYID",
00328         0
00329   };
00330   const char *enctype_names[] = {
00331         "ANY", "DES_CFB64",  "DES_OFB64",  "UNKNOWN",  "UNKNOWN",  "UNKNOWN",
00332         "UNKNOWN",  "UNKNOWN",  "CAST5_40_CFB64",  "CAST5_40_OFB64",
00333         "CAST128_CFB64",  "CAST128_OFB64",  0,
00334   };
00335 #else
00336   W32_DATA const char *encrypt_names[];
00337   W32_DATA const char *enctype_names[];
00338 #endif
00339
00340
00341 #define ENCRYPT_NAME_OK(x)  ((unsigned int)(x) < ENCRYPT_CNT)
00342 #define ENCRYPT_NAME(x)     encrypt_names[x]
00343
00344 #define ENCTYPE_NAME_OK(x)  ((unsigned int)(x) < ENCTYPE_CNT)
00345 #define ENCTYPE_NAME(x)     enctype_names[x]
00346
00347 #endif
Generated on Wed Jan 25 15:42:32 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/arpa/TFTP.H Source File

inc/arpa/TFTP.H

Go to the documentation of this file.
00001
00005 /*
00006  * Copyright (c) 1983, 1993
00007  *      The Regents of the University of California.  All rights reserved.
00008  *
00009  * Redistribution and use in source and binary forms, with or without
00010  * modification, are permitted provided that the following conditions
00011  * are met:
00012  * 1. Redistributions of source code must retain the above copyright
00013  *    notice, this list of conditions and the following disclaimer.
00014  * 2. Redistributions in binary form must reproduce the above copyright
00015  *    notice, this list of conditions and the following disclaimer in the
00016  *    documentation and/or other materials provided with the distribution.
00017  * 3. All advertising materials mentioning features or use of this software
00018  *    must display the following acknowledgement:
00019  *      This product includes software developed by the University of
00020  *      California, Berkeley and its contributors.
00021  * 4. Neither the name of the University nor the names of its contributors
00022  *    may be used to endorse or promote products derived from this software
00023  *    without specific prior written permission.
00024  *
00025  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
00026  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00027  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00028  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
00029  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00030  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00031  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00032  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00033  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00034  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00035  * SUCH DAMAGE.
00036  *
00037  *      @(#)tftp.h      8.1 (Berkeley) 6/2/93
00038  * $FreeBSD: /repoman/r/ncvs/src/include/arpa/tftp.h,v 1.3.6.1 2002/08/14 21:59:26 peter Exp $
00039  */
00040
00041 #ifndef __ARPA_TFTP_H
00042 #define __ARPA_TFTP_H
00043
00044 /*
00045  * Trivial File Transfer Protocol (IEN-133)
00046  */
00047 #define SEGSIZE         512             /* data segment size */
00048
00049 /*
00050  * Packet types.
00051  */
00052 #define RRQ     01                      /* read request */
00053 #define WRQ     02                      /* write request */
00054 #define DATA    03                      /* data packet */
00055 #define ACK     04                      /* acknowledgement */
00056 #undef  ERROR                           /* In <wingdi.h> */
00057 #define ERROR   05                      /* error code */
00058 #define OACK    06                      /* option acknowledgement */
00059
00060 #include <sys/packon.h>
00061
00062 struct tftphdr {
00063        unsigned short   th_opcode;      /* packet type */
00064        union {
00065          unsigned short tu_block;       /* block # */
00066          unsigned short tu_code;        /* error code */
00067          char           tu_stuff[1];    /* request packet stuff */
00068        } th_u;
00069        char             th_data[1];     /* data or error string */
00070      };
00071
00072 #include <sys/packoff.h>
00073
00074 #define th_block        th_u.tu_block
00075 #define th_code         th_u.tu_code
00076 #define th_stuff        th_u.tu_stuff
00077 #define th_msg          th_data
00078
00079 /*
00080  * Error codes.
00081  */
00082 #define EUNDEF          0               /* not defined */
00083 #define ENOTFOUND       1               /* file not found */
00084 #define EACCESS         2               /* access violation */
00085 #define ENOSPACE        3               /* disk full or allocation exceeded */
00086 #define EBADOP          4               /* illegal TFTP operation */
00087 #define EBADID          5               /* unknown transfer ID */
00088 #define EEXISTS         6               /* file already exists */
00089 #define ENOUSER         7               /* no such user */
00090 #define EOPTNEG         8               /* option negotiation failed */
00091
00092 #endif
Generated on Wed Jan 25 15:42:40 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/net/BPF.H Source File

inc/net/BPF.H

Go to the documentation of this file.
00001
00004 /*
00005  * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
00006  *      The Regents of the University of California.  All rights reserved.
00007  *
00008  * This code is derived from the Stanford/CMU enet packet filter,
00009  * (net/enet.c) distributed as part of 4.3BSD, and code contributed
00010  * to Berkeley by Steven McCanne and Van Jacobson both of Lawrence
00011  * Berkeley Laboratory.
00012  *
00013  * Redistribution and use in source and binary forms, with or without
00014  * modification, are permitted provided that the following conditions
00015  * are met:
00016  * 1. Redistributions of source code must retain the above copyright
00017  *    notice, this list of conditions and the following disclaimer.
00018  * 2. Redistributions in binary form must reproduce the above copyright
00019  *    notice, this list of conditions and the following disclaimer in the
00020  *    documentation and/or other materials provided with the distribution.
00021  * 3. All advertising materials mentioning features or use of this software
00022  *    must display the following acknowledgement:
00023  *      This product includes software developed by the University of
00024  *      California, Berkeley and its contributors.
00025  * 4. Neither the name of the University nor the names of its contributors
00026  *    may be used to endorse or promote products derived from this software
00027  *    without specific prior written permission.
00028  *
00029  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
00030  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00031  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00032  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
00033  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00034  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00035  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00036  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00037  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00038  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00039  * SUCH DAMAGE.
00040  *
00041  *      @(#)bpf.h       8.1 (Berkeley) 6/10/93
00042  * @(#) Header: bpf.h,v 1.36 97/06/12 14:29:53 leres Exp  (LBL)
00043  */
00044
00045 #ifndef __NET_BPF_H
00046 #define __NET_BPF_H
00047
00048 #ifndef __SYS_WTYPES_H
00049 #include <sys/wtypes.h>
00050 #endif
00051
00052 #ifndef __SYS_WTIME_H
00053 #include <sys/wtime.h>
00054 #endif
00055
00056 /* BSD style release date */
00057 #define BPF_RELEASE 199606
00058
00059 typedef long      bpf_int32;
00060 typedef u_int32_t bpf_u_int32;
00061
00062 /*
00063  * Alignment macros.  BPF_WORDALIGN rounds up to the next
00064  * even multiple of BPF_ALIGNMENT.
00065  */
00066 #define BPF_ALIGNMENT    sizeof(long)
00067 #define BPF_WORDALIGN(x) (((x)+(BPF_ALIGNMENT-1)) & ~(BPF_ALIGNMENT-1))
00068
00069 #define BPF_MAXINSNS     512
00070 #define BPF_MAXBUFSIZE   0x8000
00071 #define BPF_MINBUFSIZE   32
00072
00073 /*
00074  *  Structure for BIOCSETF.
00075  */
00076 struct bpf_program {
00077        u_int            bf_len;
00078        struct bpf_insn *bf_insns;
00079      };
00080
00081 /*
00082  * Struct returned by BIOCGSTATS.
00083  */
00084 struct bpf_stat {
00085        u_int bs_recv;          /* number of packets received */
00086        u_int bs_drop;          /* number of packets dropped */
00087      };
00088
00089 /*
00090  * Struct return by BIOCVERSION.  This represents the version number of
00091  * the filter language described by the instruction encodings below.
00092  * bpf understands a program iff kernel_major == filter_major &&
00093  * kernel_minor >= filter_minor, that is, if the value returned by the
00094  * running kernel has the same major number and a minor number equal
00095  * equal to or less than the filter being downloaded.  Otherwise, the
00096  * results are undefined, meaning an error may be returned or packets
00097  * may be accepted haphazardly.
00098  * It has nothing to do with the source code version.
00099  */
00100 struct bpf_version {
00101        u_short bv_major;
00102        u_short bv_minor;
00103      };
00104
00105 /* Current version number of filter architecture. */
00106 #define BPF_MAJOR_VERSION 1
00107 #define BPF_MINOR_VERSION 1
00108
00109 /*
00110  * BPF ioctls
00111  *
00112  * The first set is for compatibility with Sun's pcc style
00113  * header files.  If your using gcc, we assume that you
00114  * have run fixincludes so the latter set should work.
00115  */
00116 #if (defined(sun) || defined(ibm032)) && !defined(__GNUC__)
00117 #  define BIOCGBLEN       _IOR(B,102, u_int)
00118 #  define BIOCSBLEN       _IOWR(B,102, u_int)
00119 #  define BIOCSETF        _IOW(B,103, struct bpf_program)
00120 #  define BIOCFLUSH       _IO(B,104)
00121 #  define BIOCPROMISC     _IO(B,105)
00122 #  define BIOCGDLT        _IOR(B,106, u_int)
00123 #  define BIOCGETIF       _IOR(B,107, struct ifreq)
00124 #  define BIOCSETIF       _IOW(B,108, struct ifreq)
00125 #  define BIOCSRTIMEOUT   _IOW(B,109, struct timeval)
00126 #  define BIOCGRTIMEOUT   _IOR(B,110, struct timeval)
00127 #  define BIOCGSTATS      _IOR(B,111, struct bpf_stat)
00128 #  define BIOCIMMEDIATE   _IOW(B,112, u_int)
00129 #  define BIOCVERSION     _IOR(B,113, struct bpf_version)
00130 #  define BIOCSTCPF       _IOW(B,114, struct bpf_program)
00131 #  define BIOCSUDPF       _IOW(B,115, struct bpf_program)
00132 #else
00133 #  define BIOCGBLEN       _IOR('B',102, u_int)
00134 #  define BIOCSBLEN       _IOWR('B',102, u_int)
00135 #  define BIOCSETF        _IOW('B',103, struct bpf_program)
00136 #  define BIOCFLUSH       _IO('B',104)
00137 #  define BIOCPROMISC     _IO('B',105)
00138 #  define BIOCGDLT        _IOR('B',106, u_int)
00139 #  define BIOCGETIF       _IOR('B',107, struct ifreq)
00140 #  define BIOCSETIF       _IOW('B',108, struct ifreq)
00141 #  define BIOCSRTIMEOUT   _IOW('B',109, struct timeval)
00142 #  define BIOCGRTIMEOUT   _IOR('B',110, struct timeval)
00143 #  define BIOCGSTATS      _IOR('B',111, struct bpf_stat)
00144 #  define BIOCIMMEDIATE   _IOW('B',112, u_int)
00145 #  define BIOCVERSION     _IOR('B',113, struct bpf_version)
00146 #  define BIOCSTCPF       _IOW('B',114, struct bpf_program)
00147 #  define BIOCSUDPF       _IOW('B',115, struct bpf_program)
00148 #endif
00149
00150 /*
00151  * Structure prepended to each packet.
00152  */
00153 struct bpf_hdr {
00154        struct timeval bh_tstamp;      /* time stamp */
00155        u_int32_t      bh_caplen;      /* length of captured portion */
00156        u_int32_t      bh_datalen;     /* original length of packet */
00157        u_int16_t      bh_hdrlen;      /* length of bpf header (this struct */
00158      };                               /* plus alignment padding) */
00159
00160 /*
00161  * Because the structure above is not a multiple of 4 bytes, some compilers
00162  * will insist on inserting padding; hence, sizeof(struct bpf_hdr) won't work.
00163  * Only the kernel needs to know about it; applications use bh_hdrlen.
00164  * XXX To save a few bytes on 32-bit machines, we avoid end-of-struct
00165  * XXX padding by using the size of the header data elements.  This is
00166  * XXX fail-safe: on new machines, we just use the 'safe' sizeof.
00167  */
00168 #define SIZEOF_BPF_HDR sizeof(struct bpf_hdr)
00169
00170 /*
00171  * Data-link level type codes.
00172  */
00173 #define DLT_NULL        0       /* no link-layer encapsulation */
00174 #define DLT_EN10MB      1       /* Ethernet (10Mb) */
00175 #define DLT_EN3MB       2       /* Experimental Ethernet (3Mb) */
00176 #define DLT_AX25        3       /* Amateur Radio AX.25 */
00177 #define DLT_PRONET      4       /* Proteon ProNET Token Ring */
00178 #define DLT_CHAOS       5       /* Chaos */
00179 #define DLT_IEEE802     6       /* IEEE 802 Networks */
00180 #define DLT_ARCNET      7       /* ARCNET */
00181 #define DLT_SLIP        8       /* Serial Line IP */
00182 #define DLT_PPP         9       /* Point-to-point Protocol */
00183 #define DLT_FDDI        10      /* FDDI */
00184 #define DLT_ATM_RFC1483 11      /* LLC/SNAP encapsulated atm */
00185 #define DLT_RAW         12      /* raw IP */
00186 #define DLT_SLIP_BSDOS  13      /* BSD/OS Serial Line IP */
00187 #define DLT_PPP_BSDOS   14      /* BSD/OS Point-to-point Protocol */
00188 #define DLT_LANE8023    15      /* LANE 802.3(Ethernet) */
00189 #define DLT_CIP         16      /* ATM Classical IP */
00190
00191
00192 /*
00193  * The instruction encondings.
00194  */
00195 /* instruction classes */
00196 #define BPF_CLASS(code) ((code) & 0x07)
00197 #define         BPF_LD          0x00
00198 #define         BPF_LDX         0x01
00199 #define         BPF_ST          0x02
00200 #define         BPF_STX         0x03
00201 #define         BPF_ALU         0x04
00202 #define         BPF_JMP         0x05
00203 #define         BPF_RET         0x06
00204 #define         BPF_MISC        0x07
00205
00206 /* ld/ldx fields */
00207 #define BPF_SIZE(code)  ((code) & 0x18)
00208 #define         BPF_W           0x00
00209 #define         BPF_H           0x08
00210 #define         BPF_B           0x10
00211 #define BPF_MODE(code)  ((code) & 0xe0)
00212 #define         BPF_IMM         0x00
00213 #define         BPF_ABS         0x20
00214 #define         BPF_IND         0x40
00215 #define         BPF_MEM         0x60
00216 #define         BPF_LEN         0x80
00217 #define         BPF_MSH         0xa0
00218
00219 /* alu/jmp fields */
00220 #define BPF_OP(code)    ((code) & 0xf0)
00221 #define         BPF_ADD         0x00
00222 #define         BPF_SUB         0x10
00223 #define         BPF_MUL         0x20
00224 #define         BPF_DIV         0x30
00225 #define         BPF_OR          0x40
00226 #define         BPF_AND         0x50
00227 #define         BPF_LSH         0x60
00228 #define         BPF_RSH         0x70
00229 #define         BPF_NEG         0x80
00230 #define         BPF_JA          0x00
00231 #define         BPF_JEQ         0x10
00232 #define         BPF_JGT         0x20
00233 #define         BPF_JGE         0x30
00234 #define         BPF_JSET        0x40
00235 #define BPF_SRC(code)   ((code) & 0x08)
00236 #define         BPF_K           0x00
00237 #define         BPF_X           0x08
00238
00239 /* ret - BPF_K and BPF_X also apply */
00240 #define BPF_RVAL(code)  ((code) & 0x18)
00241 #define         BPF_A           0x10
00242
00243 /* misc */
00244 #define BPF_MISCOP(code) ((code) & 0xf8)
00245 #define         BPF_TAX         0x00
00246 #define         BPF_TXA         0x80
00247
00248 /*
00249  * The instruction data structure.
00250  */
00251 struct bpf_insn {
00252        u_int16_t code;
00253        u_char    jt;
00254        u_char    jf;
00255        int32_t   k;
00256      };
00257
00258 /*
00259  * Macros for insn array initializers.
00260  */
00261 #define BPF_STMT(code, k)          { (u_int16_t)(code), 0, 0, k }
00262 #define BPF_JUMP(code, k, jt, jf)  { (u_int16_t)(code), jt, jf, k }
00263
00264 u_int bpf_filter (struct bpf_insn *, u_char *, u_int, u_int);
00265
00266 /*
00267  * Number of scratch memory words (for BPF_LD|BPF_MEM and BPF_ST).
00268  */
00269 #define BPF_MEMWORDS 16
00270
00271 #endif
Generated on Wed Jan 25 15:42:32 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/net/BPFDESC.H Source File

inc/net/BPFDESC.H

Go to the documentation of this file.
00001
00005 /*      $NetBSD: bpfdesc.h,v 1.13 1997/10/09 18:58:12 christos Exp $    */
00006
00007 /*
00008  * Copyright (c) 1990, 1991, 1993
00009  *      The Regents of the University of California.  All rights reserved.
00010  *
00011  * This code is derived from the Stanford/CMU enet packet filter,
00012  * (net/enet.c) distributed as part of 4.3BSD, and code contributed
00013  * to Berkeley by Steven McCanne and Van Jacobson both of Lawrence
00014  * Berkeley Laboratory.
00015  *
00016  * Redistribution and use in source and binary forms, with or without
00017  * modification, are permitted provided that the following conditions
00018  * are met:
00019  * 1. Redistributions of source code must retain the above copyright
00020  *    notice, this list of conditions and the following disclaimer.
00021  * 2. Redistributions in binary form must reproduce the above copyright
00022  *    notice, this list of conditions and the following disclaimer in the
00023  *    documentation and/or other materials provided with the distribution.
00024  * 3. All advertising materials mentioning features or use of this software
00025  *    must display the following acknowledgement:
00026  *      This product includes software developed by the University of
00027  *      California, Berkeley and its contributors.
00028  * 4. Neither the name of the University nor the names of its contributors
00029  *    may be used to endorse or promote products derived from this software
00030  *    without specific prior written permission.
00031  *
00032  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
00033  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00034  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00035  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
00036  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00037  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00038  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00039  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00040  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00041  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00042  * SUCH DAMAGE.
00043  *
00044  *      @(#)bpfdesc.h   8.1 (Berkeley) 6/10/93
00045  *
00046  * @(#) Header: bpfdesc.h,v 1.14 96/06/16 22:28:07 leres Exp  (LBL)
00047  */
00048
00049 #ifndef __NET_BPF_DESC_H
00050 #define __NET_BPF_DESC_H
00051
00052 /*
00053  * Descriptor associated with each open bpf file.
00054  */
00055 struct bpf_d {
00056         struct bpf_d    *bd_next;       /* Linked list of descriptors */
00057         /*
00058          * Buffer slots: two mbuf clusters buffer the incoming packets.
00059          *   The model has three slots.  Sbuf is always occupied.
00060          *   sbuf (store) - Receive interrupt puts packets here.
00061          *   hbuf (hold) - When sbuf is full, put cluster here and
00062          *                 wakeup read (replace sbuf with fbuf).
00063          *   fbuf (free) - When read is done, put cluster here.
00064          * On receiving, if sbuf is full and fbuf is 0, packet is dropped.
00065          */
00066         caddr_t         bd_sbuf;        /* store slot */
00067         caddr_t         bd_hbuf;        /* hold slot */
00068         caddr_t         bd_fbuf;        /* free slot */
00069         int             bd_slen;        /* current length of store buffer */
00070         int             bd_hlen;        /* current length of hold buffer */
00071
00072         int             bd_bufsize;     /* absolute length of buffers */
00073
00074         struct bpf_if * bd_bif;         /* interface descriptor */
00075         u_long          bd_rtout;       /* Read timeout in 'ticks' */
00076         struct bpf_insn *bd_filter;     /* filter code */
00077         u_long          bd_rcount;      /* number of packets received */
00078         u_long          bd_dcount;      /* number of packets dropped */
00079
00080         u_char          bd_promisc;     /* true if listening promiscuously */
00081         u_char          bd_state;       /* idle, waiting, or timed out */
00082         u_char          bd_immediate;   /* true to return on packet arrival */
00083         int             bd_async;       /* non-zero if packet reception should generate signal */
00084         int             bd_pgid;        /* process or group id for signal */
00085 #if BSD < 199103
00086         u_char          bd_selcoll;     /* true if selects collide */
00087         int             bd_timedout;
00088         struct proc *   bd_selproc;     /* process that last selected us */
00089 #else
00090         u_char          bd_pad;         /* explicit alignment */
00091         struct selinfo  bd_sel;         /* bsd select info */
00092 #endif
00093 };
00094
00095 /*
00096  * Descriptor associated with each attached hardware interface.
00097  */
00098 struct bpf_if {
00099         struct bpf_if *bif_next;        /* list of all interfaces */
00100         struct bpf_d *bif_dlist;        /* descriptor list */
00101         struct bpf_if **bif_driverp;    /* pointer into softc */
00102         u_int bif_dlt;                  /* link layer type */
00103         u_int bif_hdrlen;               /* length of header (with padding) */
00104         struct ifnet *bif_ifp;          /* correspoding interface */
00105 };
00106
00107 #endif
Generated on Wed Jan 25 15:42:32 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/net/ETHERTYP.H Source File

inc/net/ETHERTYP.H

Go to the documentation of this file.
00001
00005 /*      $NetBSD: ethertypes.h,v 1.2 1997/03/15 18:12:19 is Exp $        */
00006
00007 /*
00008  * Copyright (c) 1982, 1986, 1993
00009  *      The Regents of the University of California.  All rights reserved.
00010  *
00011  * Redistribution and use in source and binary forms, with or without
00012  * modification, are permitted provided that the following conditions
00013  * are met:
00014  * 1. Redistributions of source code must retain the above copyright
00015  *    notice, this list of conditions and the following disclaimer.
00016  * 2. Redistributions in binary form must reproduce the above copyright
00017  *    notice, this list of conditions and the following disclaimer in the
00018  *    documentation and/or other materials provided with the distribution.
00019  * 3. All advertising materials mentioning features or use of this software
00020  *    must display the following acknowledgement:
00021  *      This product includes software developed by the University of
00022  *      California, Berkeley and its contributors.
00023  * 4. Neither the name of the University nor the names of its contributors
00024  *    may be used to endorse or promote products derived from this software
00025  *    without specific prior written permission.
00026  *
00027  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
00028  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00029  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00030  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
00031  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00032  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00033  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00034  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00035  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00036  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00037  * SUCH DAMAGE.
00038  *
00039  *      @(#)if_ether.h  8.1 (Berkeley) 6/10/93
00040  */
00041
00042 /*
00043  * Ethernet protocol types.
00044  *
00045  * According to "assigned numbers", the Ethernet protocol numbers are also
00046  * used as ARP protocol type numbers.
00047  *
00048  * I factor them out here to avoid pulling all the Ethernet header file
00049  * into the hardware independent ARP code. -is
00050  */
00051
00052 #ifndef __NET_ETHERTYPE_H
00053 #define __NET_ETHERTYPE_H
00054
00055 #define ETHERTYPE_PUP           0x0200  /* PUP protocol */
00056 #define ETHERTYPE_IP            0x0800  /* IP protocol */
00057 #define ETHERTYPE_ARP           0x0806  /* address resolution protocol */
00058 #define ETHERTYPE_REVARP        0x8035  /* reverse addr resolution protocol */
00059
00060 /*
00061  * The ETHERTYPE_NTRAILER packet types starting at ETHERTYPE_TRAIL have
00062  * (type-ETHERTYPE_TRAIL)*512 bytes of data followed
00063  * by an ETHER type (as given above) and then the (variable-length) header.
00064  */
00065 #define ETHERTYPE_TRAIL         0x1000          /* Trailer packet */
00066 #define ETHERTYPE_NTRAILER      16
00067
00068 #endif
Generated on Wed Jan 25 15:42:32 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/net/IF.H Source File

inc/net/IF.H

Go to the documentation of this file.
00001
00005 /*      $NetBSD: if.h,v 1.29 1997/10/02 19:41:57 is Exp $       */
00006
00007 /*
00008  * Copyright (c) 1982, 1986, 1989, 1993
00009  *      The Regents of the University of California.  All rights reserved.
00010  *
00011  * Redistribution and use in source and binary forms, with or without
00012  * modification, are permitted provided that the following conditions
00013  * are met:
00014  * 1. Redistributions of source code must retain the above copyright
00015  *    notice, this list of conditions and the following disclaimer.
00016  * 2. Redistributions in binary form must reproduce the above copyright
00017  *    notice, this list of conditions and the following disclaimer in the
00018  *    documentation and/or other materials provided with the distribution.
00019  * 3. All advertising materials mentioning features or use of this software
00020  *    must display the following acknowledgement:
00021  *      This product includes software developed by the University of
00022  *      California, Berkeley and its contributors.
00023  * 4. Neither the name of the University nor the names of its contributors
00024  *    may be used to endorse or promote products derived from this software
00025  *    without specific prior written permission.
00026  *
00027  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
00028  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00029  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00030  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
00031  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00032  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00033  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00034  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00035  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00036  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00037  * SUCH DAMAGE.
00038  *
00039  *      @(#)if.h        8.1 (Berkeley) 6/10/93
00040  */
00041
00042 #ifndef __NET_IF_H
00043 #define __NET_IF_H
00044
00045 #include <sys/queue.h>
00046
00047 /*
00048  * Structures defining a network interface, providing a packet
00049  * transport mechanism (ala level 0 of the PUP protocols).
00050  *
00051  * Each interface accepts output datagrams of a specified maximum
00052  * length, and provides higher level routines with input datagrams
00053  * received from its medium.
00054  *
00055  * Output occurs when the routine if_output is called, with four parameters:
00056  *      (*ifp->if_output)(ifp, m, dst, rt)
00057  * Here m is the mbuf chain to be sent and dst is the destination address.
00058  * The output routine encapsulates the supplied datagram if necessary,
00059  * and then transmits it on its medium.
00060  *
00061  * On input, each interface unwraps the data received by it, and either
00062  * places it on the input queue of a internetwork datagram routine
00063  * and posts the associated software interrupt, or passes the datagram to a raw
00064  * packet input routine.
00065  *
00066  * Routines exist for locating interfaces by their addresses
00067  * or for locating a interface on a certain network, as well as more general
00068  * routing and gateway routines maintaining information used to locate
00069  * interfaces.  These routines live in the files if.c and route.c
00070  */
00071 #ifndef __SYS_WTIME_H
00072 #include <sys/wtime.h>
00073 #endif
00074
00075 struct mbuf;
00076 struct rtentry;
00077 struct ether_header;
00078 struct proc   { int dummy; };
00079 struct socket { int dummy; };
00080
00081 /*
00082  * Structure defining statistics and other data kept regarding a network
00083  * interface.
00084  */
00085 struct  if_data {
00086         /* generic interface information */
00087         u_char  ifi_type;               /* ethernet, tokenring, etc. */
00088         u_char  ifi_addrlen;            /* media address length */
00089         u_char  ifi_hdrlen;             /* media header length */
00090         u_long  ifi_mtu;                /* maximum transmission unit */
00091         u_long  ifi_metric;             /* routing metric (external only) */
00092         u_long  ifi_baudrate;           /* linespeed */
00093         /* volatile statistics */
00094         u_long  ifi_ipackets;           /* packets received on interface */
00095         u_long  ifi_ierrors;            /* input errors on interface */
00096         u_long  ifi_opackets;           /* packets sent on interface */
00097         u_long  ifi_oerrors;            /* output errors on interface */
00098         u_long  ifi_collisions;         /* collisions on csma interfaces */
00099         u_long  ifi_ibytes;             /* total number of octets received */
00100         u_long  ifi_obytes;             /* total number of octets sent */
00101         u_long  ifi_imcasts;            /* packets received via multicast */
00102         u_long  ifi_omcasts;            /* packets sent via multicast */
00103         u_long  ifi_iqdrops;            /* dropped on input, this interface */
00104         u_long  ifi_noproto;            /* destined for unsupported protocol */
00105         struct  timeval ifi_lastchange; /* last updated */
00106 };
00107
00108 /*
00109  * Structure defining a queue for a network interface.
00110  *
00111  * (Would like to call this struct ``if'', but C isn't PL/1.)
00112  */
00113 TAILQ_HEAD(ifnet_head, ifnet);          /* the actual queue head */
00114
00115 /*
00116  * Length of interface external name, including terminating '\0'.
00117  * Note: this is the same size as a generic device's external name.
00118  */
00119 #define IFNAMSIZ        16
00120
00121 #ifndef IF_NAMESIZE
00122 #define IF_NAMESIZE     IFNAMSIZ
00123 #endif
00124
00125 struct ifnet {                          /* and the entries */
00126         void    *if_softc;              /* lower-level data for this if */
00127         TAILQ_ENTRY(ifnet) if_list;         /* all struct ifnets are chained */
00128         TAILQ_HEAD(xx, ifaddr) if_addrlist; /* linked list of addresses per if */
00129         char    if_xname[IFNAMSIZ];     /* external name (name + unit) */
00130         int     if_pcount;              /* number of promiscuous listeners */
00131         caddr_t if_bpf;                 /* packet filter structure */
00132         u_short if_index;               /* numeric abbreviation for this if */
00133         short   if_timer;               /* time 'til if_watchdog called */
00134         short   if_flags;               /* up/down, broadcast, etc. */
00135         short   if__pad1;               /* be nice to m68k ports */
00136         struct  if_data if_data;        /* statistics and other data about if */
00137 /* procedure handles */
00138         int     (*if_output)            /* output routine (enqueue) */
00139                 (struct ifnet *, struct mbuf *, struct sockaddr *,
00140                  struct rtentry *);
00141         void    (*if_start)             /* initiate output routine */
00142                 (struct ifnet *);
00143         int     (*if_ioctl)             /* ioctl routine */
00144                 (struct ifnet *, u_long, caddr_t);
00145         int     (*if_reset)             /* XXX bus reset routine */
00146                 (struct ifnet *);
00147         void    (*if_watchdog)          /* timer routine */
00148                 (struct ifnet *);
00149         struct  ifqueue {
00150                   struct  mbuf *ifq_head;
00151                   struct  mbuf *ifq_tail;
00152                   int     ifq_len;
00153                   int     ifq_maxlen;
00154                   int     ifq_drops;
00155                 } if_snd;               /* output queue */
00156         struct  sockaddr_dl *if_sadl;   /* pointer to our sockaddr_dl */
00157         u_int8_t *if_broadcastaddr;     /* linklevel broadcast bytestring */
00158 };
00159
00160 #define if_mtu          if_data.ifi_mtu
00161 #define if_type         if_data.ifi_type
00162 #define if_addrlen      if_data.ifi_addrlen
00163 #define if_hdrlen       if_data.ifi_hdrlen
00164 #define if_metric       if_data.ifi_metric
00165 #define if_baudrate     if_data.ifi_baudrate
00166 #define if_ipackets     if_data.ifi_ipackets
00167 #define if_ierrors      if_data.ifi_ierrors
00168 #define if_opackets     if_data.ifi_opackets
00169 #define if_oerrors      if_data.ifi_oerrors
00170 #define if_collisions   if_data.ifi_collisions
00171 #define if_ibytes       if_data.ifi_ibytes
00172 #define if_obytes       if_data.ifi_obytes
00173 #define if_imcasts      if_data.ifi_imcasts
00174 #define if_omcasts      if_data.ifi_omcasts
00175 #define if_iqdrops      if_data.ifi_iqdrops
00176 #define if_noproto      if_data.ifi_noproto
00177 #define if_lastchange   if_data.ifi_lastchange
00178
00179 #define IFF_UP          0x1             /* interface is up */
00180 #define IFF_BROADCAST   0x2             /* broadcast address valid */
00181 #define IFF_DEBUG       0x4             /* turn on debugging */
00182 #define IFF_LOOPBACK    0x8             /* is a loopback net */
00183 #define IFF_POINTOPOINT 0x10            /* interface is point-to-point link */
00184 #define IFF_NOTRAILERS  0x20            /* avoid use of trailers */
00185 #define IFF_RUNNING     0x40            /* resources allocated */
00186 #define IFF_NOARP       0x80            /* no address resolution protocol */
00187 #define IFF_PROMISC     0x100           /* receive all packets */
00188 #define IFF_ALLMULTI    0x200           /* receive all multicast packets */
00189 #define IFF_OACTIVE     0x400           /* transmission in progress */
00190 #define IFF_SIMPLEX     0x800           /* can't hear own transmissions */
00191 #define IFF_LINK0       0x1000          /* per link layer defined bit */
00192 #define IFF_LINK1       0x2000          /* per link layer defined bit */
00193 #define IFF_LINK2       0x4000          /* per link layer defined bit */
00194 #define IFF_MULTICAST   0x8000          /* supports multicast */
00195
00196 /* flags set internally only: */
00197 #define IFF_CANTCHANGE \
00198         (IFF_BROADCAST|IFF_POINTOPOINT|IFF_RUNNING|IFF_OACTIVE|\
00199             IFF_SIMPLEX|IFF_MULTICAST|IFF_ALLMULTI)
00200
00201 /*
00202  * Output queues (ifp->if_snd) and internetwork datagram level (pup level 1)
00203  * input routines have queues of messages stored on ifqueue structures
00204  * (defined above).  Entries are added to and deleted from these structures
00205  * by these macros, which should be called with ipl raised to splimp().
00206  */
00207 #define IF_QFULL(ifq)           ((ifq)->ifq_len >= (ifq)->ifq_maxlen)
00208 #define IF_DROP(ifq)            ((ifq)->ifq_drops++)
00209 #define IF_ENQUEUE(ifq, m) { \
00210         (m)->m_nextpkt = 0; \
00211         if ((ifq)->ifq_tail == 0) \
00212                 (ifq)->ifq_head = m; \
00213         else \
00214                 (ifq)->ifq_tail->m_nextpkt = m; \
00215         (ifq)->ifq_tail = m; \
00216         (ifq)->ifq_len++; \
00217 }
00218 #define IF_PREPEND(ifq, m) { \
00219         (m)->m_nextpkt = (ifq)->ifq_head; \
00220         if ((ifq)->ifq_tail == 0) \
00221                 (ifq)->ifq_tail = (m); \
00222         (ifq)->ifq_head = (m); \
00223         (ifq)->ifq_len++; \
00224 }
00225 #define IF_DEQUEUE(ifq, m) { \
00226         (m) = (ifq)->ifq_head; \
00227         if (m) { \
00228                 if (((ifq)->ifq_head = (m)->m_nextpkt) == 0) \
00229                         (ifq)->ifq_tail = 0; \
00230                 (m)->m_nextpkt = 0; \
00231                 (ifq)->ifq_len--; \
00232         } \
00233 }
00234
00235 #define IFQ_MAXLEN      50
00236 #define IFNET_SLOWHZ    1               /* granularity is 1 second */
00237
00238 /*
00239  * The ifaddr structure contains information about one address
00240  * of an interface.  They are maintained by the different address families,
00241  * are allocated and attached when an address is set, and are linked
00242  * together so all addresses for an interface can be located.
00243  */
00244 struct ifaddr {
00245         struct  sockaddr *ifa_addr;     /* address of interface */
00246         struct  sockaddr *ifa_dstaddr;  /* other end of p-to-p link */
00247 #define ifa_broadaddr   ifa_dstaddr     /* broadcast address interface */
00248         struct  sockaddr *ifa_netmask;  /* used to determine subnet */
00249         struct  ifnet *ifa_ifp;         /* back-pointer to interface */
00250         TAILQ_ENTRY(ifaddr) ifa_list;   /* list of addresses for interface */
00251         void    (*ifa_rtrequest)        /* check or clean routes (+ or -)'d */
00252                 (int, struct rtentry *, struct sockaddr *);
00253         u_short ifa_flags;              /* mostly rt_flags for cloning */
00254         short   ifa_refcnt;             /* count of references */
00255         int     ifa_metric;             /* cost of going out this interface */
00256 };
00257 #define IFA_ROUTE       RTF_UP          /* route installed */
00258
00259 /*
00260  * Message format for use in obtaining information about interfaces
00261  * from sysctl and the routing socket.
00262  */
00263 struct if_msghdr {
00264         u_short ifm_msglen;     /* to skip over non-understood messages */
00265         u_char  ifm_version;    /* future binary compatability */
00266         u_char  ifm_type;       /* message type */
00267         int     ifm_addrs;      /* like rtm_addrs */
00268         int     ifm_flags;      /* value of if_flags */
00269         u_short ifm_index;      /* index for associated ifp */
00270         struct  if_data ifm_data;/* statistics and other data about if */
00271 };
00272
00273 /*
00274  * Message format for use in obtaining information about interface addresses
00275  * from sysctl and the routing socket.
00276  */
00277 struct ifa_msghdr {
00278         u_short ifam_msglen;    /* to skip over non-understood messages */
00279         u_char  ifam_version;   /* future binary compatability */
00280         u_char  ifam_type;      /* message type */
00281         int     ifam_addrs;     /* like rtm_addrs */
00282         int     ifam_flags;     /* value of ifa_flags */
00283         u_short ifam_index;     /* index for associated ifp */
00284         int     ifam_metric;    /* value of ifa_metric */
00285 };
00286
00287 /*
00288  * Interface request structure used for socket
00289  * ioctl's.  All interface ioctl's must have parameter
00290  * definitions which begin with ifr_name.  The
00291  * remainder may be interface specific.
00292  */
00293 struct ifreq {
00294         char    ifr_name[IFNAMSIZ];             /* if name, e.g. "en0" */
00295         union {
00296                 struct  sockaddr ifru_addr;
00297                 struct  sockaddr ifru_dstaddr;
00298                 struct  sockaddr ifru_hwaddr;
00299                 struct  sockaddr ifru_broadaddr;
00300                 short   ifru_flags;
00301                 int     ifru_metric;
00302                 int     ifru_mtu;
00303                 caddr_t ifru_data;
00304         } ifr_ifru;
00305 #define ifr_addr        ifr_ifru.ifru_addr      /* address */
00306 #define ifr_dstaddr     ifr_ifru.ifru_dstaddr   /* other end of p-to-p link */
00307 #define ifr_hwaddr      ifr_ifru.ifru_hwaddr    /* hardware address */
00308 #define ifr_broadaddr   ifr_ifru.ifru_broadaddr /* broadcast address */
00309 #define ifr_flags       ifr_ifru.ifru_flags     /* flags */
00310 #define ifr_metric      ifr_ifru.ifru_metric    /* metric */
00311 #define ifr_mtu         ifr_ifru.ifru_mtu       /* mtu */
00312 #define ifr_media       ifr_ifru.ifru_metric    /* media options (overload) */
00313 #define ifr_data        ifr_ifru.ifru_data      /* for use by interface */
00314 };
00315
00316 struct ifaliasreq {
00317         char    ifra_name[IFNAMSIZ];            /* if name, e.g. "en0" */
00318         struct  sockaddr ifra_addr;
00319         struct  sockaddr ifra_dstaddr;
00320 #define ifra_broadaddr  ifra_dstaddr
00321         struct  sockaddr ifra_mask;
00322 };
00323
00324 struct ifmediareq {
00325         char    ifm_name[IFNAMSIZ];     /* if name, e.g. "en0" */
00326         int     ifm_current;            /* current media options */
00327         int     ifm_mask;               /* don't care mask */
00328         int     ifm_status;             /* media status */
00329         int     ifm_active;             /* active options */
00330         int     ifm_count;              /* # entries in ifm_ulist array */
00331         int     *ifm_ulist;             /* media words */
00332 };
00333
00334 /*
00335  * Structure used in SIOCGIFCONF request.
00336  * Used to retrieve interface configuration
00337  * for machine (useful for programs which
00338  * must know all networks accessible).
00339  */
00340 struct  ifconf {
00341         int     ifc_len;                /* size of associated buffer */
00342         union {
00343                 caddr_t ifcu_buf;
00344                 struct  ifreq *ifcu_req;
00345         } ifc_ifcu;
00346 #define ifc_buf ifc_ifcu.ifcu_buf       /* buffer address */
00347 #define ifc_req ifc_ifcu.ifcu_req       /* array of structures returned */
00348 };
00349
00350 #ifndef __NET_IF_ARP_H
00351 #include <net/if_arp.h>
00352 #endif
00353
00354 #endif
Generated on Wed Jan 25 15:42:32 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/net/IF_ARC.H Source File

inc/net/IF_ARC.H

Go to the documentation of this file.
00001
00005 /*      $NetBSD: if_arc.h,v 1.6 1997/03/15 18:12:30 is Exp $    */
00006
00007 /*
00008  * Copyright (c) 1982, 1986, 1993
00009  *      The Regents of the University of California.  All rights reserved.
00010  *
00011  * Redistribution and use in source and binary forms, with or without
00012  * modification, are permitted provided that the following conditions
00013  * are met:
00014  * 1. Redistributions of source code must retain the above copyright
00015  *    notice, this list of conditions and the following disclaimer.
00016  * 2. Redistributions in binary form must reproduce the above copyright
00017  *    notice, this list of conditions and the following disclaimer in the
00018  *    documentation and/or other materials provided with the distribution.
00019  * 3. All advertising materials mentioning features or use of this software
00020  *    must display the following acknowledgement:
00021  *      This product includes software developed by the University of
00022  *      California, Berkeley and its contributors.
00023  * 4. Neither the name of the University nor the names of its contributors
00024  *    may be used to endorse or promote products derived from this software
00025  *    without specific prior written permission.
00026  *
00027  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
00028  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00029  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00030  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
00031  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00032  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00033  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00034  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00035  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00036  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00037  * SUCH DAMAGE.
00038  *
00039  * from: NetBSD: if_ether.h,v 1.10 1994/06/29 06:37:55 cgd Exp
00040  *       @(#)if_ether.h 8.1 (Berkeley) 6/10/93
00041  */
00042
00043 #ifndef __NET_IF_ARC_H
00044 #define __NET_IF_ARC_H
00045
00046 #include <sys/packon.h>
00047
00048 /*
00049  * Arcnet address - 1 octets
00050  * don't know who uses this.
00051  */
00052 struct arc_addr {
00053         u_int8_t  arc_addr_octet[1];
00054 };
00055
00056 /*
00057  * Structure of a 2.5MB/s Arcnet header.
00058  * as given to interface code.
00059  */
00060 struct  arc_header {
00061         u_int8_t  arc_shost;
00062         u_int8_t  arc_dhost;
00063         u_int8_t  arc_type;
00064         /*
00065          * only present for newstyle encoding with LL fragmentation.
00066          * Don't use sizeof(anything), use ARC_HDR{,NEW}LEN instead.
00067          */
00068         u_int8_t  arc_flag;
00069         u_int16_t arc_seqid;
00070
00071         /*
00072          * only present in exception packets (arc_flag == 0xff)
00073          */
00074         u_int8_t  arc_type2;    /* same as arc_type */
00075         u_int8_t  arc_flag2;    /* real flag value */
00076         u_int16_t arc_seqid2;   /* real seqid value */
00077 };
00078
00079 #define ARC_ADDR_LEN            1
00080
00081 #define ARC_HDRLEN              3
00082 #define ARC_HDRNEWLEN           6
00083
00084 /* these lengths are data link layer length - 2*ARC_ADDR_LEN */
00085 #define ARC_MIN_LEN             1
00086 #define ARC_MIN_FORBID_LEN      254
00087 #define ARC_MAX_FORBID_LEN      256
00088 #define ARC_MAX_LEN             508
00089
00090
00091 /* RFC 1051 */
00092 #define ARCTYPE_IP_OLD          240     /* IP protocol */
00093 #define ARCTYPE_ARP_OLD         241     /* address resolution protocol */
00094
00095 /* RFC 1201 */
00096 #define ARCTYPE_IP              212     /* IP protocol */
00097 #define ARCTYPE_ARP             213     /* address resolution protocol */
00098 #define ARCTYPE_REVARP          214     /* reverse addr resolution protocol */
00099
00100 #define ARCTYPE_ATALK           221     /* Appletalk */
00101 #define ARCTYPE_BANIAN          247     /* Banyan Vines */
00102 #define ARCTYPE_IPX             250     /* Novell IPX */
00103
00104 #define ARCMTU                  507
00105 #define ARCMIN                  0
00106
00107 struct  arccom {
00108         struct    ifnet ac_if;          /* network-visible interface */
00109
00110         u_int16_t ac_seqid;             /* seq. id used by PHDS encap. */
00111
00112         struct ac_frag {
00113                 u_int8_t  af_maxflag;   /* from first packet */
00114                 u_int8_t  af_lastseen;  /* last split flag seen */
00115                 u_int16_t af_seqid;
00116                 struct mbuf *af_packet;
00117         } ac_fragtab[256];              /* indexed by sender ll address */
00118
00119 };
00120
00121 #include <sys/packoff.h>
00122
00123 #endif
Generated on Wed Jan 25 15:42:32 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/net/IF_ARP.H Source File

inc/net/IF_ARP.H

Go to the documentation of this file.
00001
00005 /*      $NetBSD: if_arp.h,v 1.12 1997/09/08 02:06:30 mikel Exp $        */
00006
00007 /*
00008  * Copyright (c) 1986, 1993
00009  *      The Regents of the University of California.  All rights reserved.
00010  *
00011  * Redistribution and use in source and binary forms, with or without
00012  * modification, are permitted provided that the following conditions
00013  * are met:
00014  * 1. Redistributions of source code must retain the above copyright
00015  *    notice, this list of conditions and the following disclaimer.
00016  * 2. Redistributions in binary form must reproduce the above copyright
00017  *    notice, this list of conditions and the following disclaimer in the
00018  *    documentation and/or other materials provided with the distribution.
00019  * 3. All advertising materials mentioning features or use of this software
00020  *    must display the following acknowledgement:
00021  *      This product includes software developed by the University of
00022  *      California, Berkeley and its contributors.
00023  * 4. Neither the name of the University nor the names of its contributors
00024  *    may be used to endorse or promote products derived from this software
00025  *    without specific prior written permission.
00026  *
00027  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
00028  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00029  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00030  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
00031  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00032  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00033  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00034  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00035  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00036  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00037  * SUCH DAMAGE.
00038  *
00039  *      @(#)if_arp.h    8.1 (Berkeley) 6/10/93
00040  */
00041
00042 #ifndef __NET_IF_ARP_H
00043 #define __NET_IF_ARP_H
00044 /*
00045  * Address Resolution Protocol.
00046  *
00047  * See RFC 826 for protocol description.  ARP packets are variable
00048  * in size; the arphdr structure defines the fixed-length portion.
00049  * Protocol type values are the same as those for 10 Mb/s Ethernet.
00050  * It is followed by the variable-sized fields ar_sha, arp_spa,
00051  * arp_tha and arp_tpa in that order, according to the lengths
00052  * specified.  Field names used correspond to RFC 826.
00053  */
00054
00055 #include <sys/packon.h>
00056
00057 struct  arphdr {
00058         u_int16_t ar_hrd;       /* format of hardware address */
00059 #define ARPHRD_ETHER    1       /* ethernet hardware format */
00060 #define ARPHRD_TOKEN    6       /* TokenRing hardware format */
00061 #define ARPHRD_ARCNET   7       /* ethernet hardware format */
00062 #define ARPHRD_FRELAY   15      /* frame relay hardware format */
00063 #define ARPHRD_STRIP    23      /* Ricochet Starmode Radio hardware format */
00064         u_int16_t ar_pro;       /* format of protocol address */
00065         u_int8_t  ar_hln;       /* length of hardware address */
00066         u_int8_t  ar_pln;       /* length of protocol address */
00067         u_int16_t ar_op;        /* one of: */
00068 #define ARPOP_REQUEST   1       /* request to resolve address */
00069 #define ARPOP_REPLY     2       /* response to previous request */
00070 #define ARPOP_REVREQUEST 3      /* request protocol address given hardware */
00071 #define ARPOP_REVREPLY  4       /* response giving protocol address */
00072 #define ARPOP_INVREQUEST 8      /* request to identify peer */
00073 #define ARPOP_INVREPLY  9       /* response identifying peer */
00074 /*
00075  * The remaining fields are variable in size,
00076  * according to the sizes above.
00077  */
00078 #ifdef COMMENT_ONLY
00079         u_int8_t  ar_sha[];     /* sender hardware address */
00080         u_int8_t  ar_spa[];     /* sender protocol address */
00081         u_int8_t  ar_tha[];     /* target hardware address */
00082         u_int8_t  ar_tpa[];     /* target protocol address */
00083 #endif
00084 #ifdef __GNUC__                 /* only GNU C allows zero arrays */
00085         u_int8_t  ar_remain[0]; /* minimum size, normally bigger */
00086   #define ar_sha(ap) (((ap)->ar_remain)+0)
00087   #define ar_spa(ap) (((ap)->ar_remain)+(ap)->ar_hln)
00088   #define ar_tha(ap) (((ap)->ar_remain)+(ap)->ar_hln+(ap)->ar_pln)
00089   #define ar_tpa(ap) (((ap)->ar_remain)+2*(ap)->ar_hln+(ap)->ar_pln)
00090 #else
00091   #define ar_sha(ap) (((ap)->ar_op)+2)
00092   #define ar_spa(ap) (((ap)->ar_op)+2+(ap)->ar_hln)
00093   #define ar_tha(ap) (((ap)->ar_op)+2+(ap)->ar_hln+(ap)->ar_pln)
00094   #define ar_tpa(ap) (((ap)->ar_op)+2+2*(ap)->ar_hln+(ap)->ar_pln)
00095 #endif
00096 };
00097
00098
00099 /*
00100  * ARP ioctl request
00101  */
00102 struct arpreq {
00103         struct  sockaddr arp_pa;                /* protocol address */
00104         struct  sockaddr arp_ha;                /* hardware address */
00105         int     arp_flags;                      /* flags */
00106 };
00107
00108 #include <sys/packoff.h>
00109
00110 /*  arp_flags and at_flags field values */
00111 #define ATF_INUSE       0x01    /* entry in use */
00112 #define ATF_COM         0x02    /* completed entry (enaddr valid) */
00113 #define ATF_PERM        0x04    /* permanent entry */
00114 #define ATF_PUBL        0x08    /* publish entry (respond for other host) */
00115 #define ATF_USETRAILERS 0x10    /* has requested trailers */
00116
00117 #endif
Generated on Wed Jan 25 15:42:32 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/net/IF_ATM.H Source File

inc/net/IF_ATM.H

Go to the documentation of this file.
00001
00005 /*      $NetBSD: if_atm.h,v 1.7 1996/11/09 23:02:27 chuck Exp $       */
00006
00007 /*
00008  *
00009  * Copyright (c) 1996 Charles D. Cranor and Washington University.
00010  * All rights reserved.
00011  *
00012  * Redistribution and use in source and binary forms, with or without
00013  * modification, are permitted provided that the following conditions
00014  * are met:
00015  * 1. Redistributions of source code must retain the above copyright
00016  *    notice, this list of conditions and the following disclaimer.
00017  * 2. Redistributions in binary form must reproduce the above copyright
00018  *    notice, this list of conditions and the following disclaimer in the
00019  *    documentation and/or other materials provided with the distribution.
00020  * 3. All advertising materials mentioning features or use of this software
00021  *    must display the following acknowledgement:
00022  *      This product includes software developed by Charles D. Cranor and
00023  *      Washington University.
00024  * 4. The name of the author may not be used to endorse or promote products
00025  *    derived from this software without specific prior written permission.
00026  *
00027  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
00028  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00029  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
00030  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
00031  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
00032  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00033  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00034  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00035  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00036  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00037  */
00038
00039 /*
00040  * net/if_atm.h
00041  */
00042
00043 #ifndef __NET_IF_ATM_H
00044 #define __NET_IF_ATM_H
00045
00046 #if defined(__NetBSD__) || defined(__OpenBSD__) || defined(__bsdi__)
00047 #define RTALLOC1(A,B)           rtalloc1((A),(B))
00048 #elif defined(__FreeBSD__)
00049 #define RTALLOC1(A,B)           rtalloc1((A),(B),0UL)
00050 #endif
00051
00052 #include <sys/packon.h>
00053
00054 /*
00055  * pseudo header for packet transmission
00056  */
00057
00058 struct atm_pseudohdr {
00059   u_int8_t atm_ph[4];   /* flags+VPI+VCI1(msb)+VCI2(lsb) */
00060 };
00061
00062 #define ATM_PH_FLAGS(X) ((X)->atm_ph[0])
00063 #define ATM_PH_VPI(X)   ((X)->atm_ph[1])
00064 #define ATM_PH_VCI(X)   ((((X)->atm_ph[2]) << 8) | ((X)->atm_ph[3]))
00065 #define ATM_PH_SETVCI(X,V) { \
00066         (X)->atm_ph[2] = ((V) >> 8) & 0xff; \
00067         (X)->atm_ph[3] = ((V) & 0xff); \
00068 }
00069
00070 #define ATM_PH_AAL5    0x01     /* use AAL5? (0 == aal0) */
00071 #define ATM_PH_LLCSNAP 0x02     /* use the LLC SNAP encoding (iff aal5) */
00072
00073 #define ATM_PH_DRIVER7  0x40    /* reserve for driver's use */
00074 #define ATM_PH_DRIVER8  0x80    /* reserve for driver's use */
00075
00076 #define ATMMTU          9180    /* ATM MTU size for IP */
00077                                 /* XXX: could be 9188 with LLC/SNAP according
00078                                         to comer */
00079
00080 /* user's ioctl hook for raw atm mode */
00081 #define SIOCRAWATM      _IOWR('a', 122, int)    /* set driver's raw mode */
00082
00083 /* atm_pseudoioctl: turns on and off RX VCIs  [for internal use only!] */
00084 struct atm_pseudoioctl {
00085   struct atm_pseudohdr aph;
00086   void *rxhand;
00087 };
00088 #define SIOCATMENA      _IOWR('a', 123, struct atm_pseudoioctl) /* enable */
00089 #define SIOCATMDIS      _IOWR('a', 124, struct atm_pseudoioctl) /* disable */
00090
00091 /*
00092  * XXX forget all the garbage in if_llc.h and do it the easy way
00093  */
00094
00095 #define ATMLLC_HDR "\252\252\3\0\0\0"
00096 struct atmllc {
00097   u_int8_t llchdr[6];   /* aa.aa.03.00.00.00 */
00098   u_int8_t type[2];     /* "ethernet" type */
00099 };
00100
00101 #include <sys/packoff.h>
00102
00103 /* ATM_LLC macros: note type code in host byte order */
00104 #define ATM_LLC_TYPE(X) (((X)->type[0] << 8) | ((X)->type[1]))
00105 #define ATM_LLC_SETTYPE(X,V) { \
00106         (X)->type[1] = ((V) >> 8) & 0xff; \
00107         (X)->type[0] = ((V) & 0xff); \
00108 }
00109
00110 #endif
Generated on Wed Jan 25 15:42:32 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/net/IF_DL.H Source File

inc/net/IF_DL.H

Go to the documentation of this file.
00001
00005 /*      $NetBSD: if_dl.h,v 1.8 1995/03/26 20:30:13 jtc Exp $    */
00006
00007 /*
00008  * Copyright (c) 1990, 1993
00009  *      The Regents of the University of California.  All rights reserved.
00010  *
00011  * Redistribution and use in source and binary forms, with or without
00012  * modification, are permitted provided that the following conditions
00013  * are met:
00014  * 1. Redistributions of source code must retain the above copyright
00015  *    notice, this list of conditions and the following disclaimer.
00016  * 2. Redistributions in binary form must reproduce the above copyright
00017  *    notice, this list of conditions and the following disclaimer in the
00018  *    documentation and/or other materials provided with the distribution.
00019  * 3. All advertising materials mentioning features or use of this software
00020  *    must display the following acknowledgement:
00021  *      This product includes software developed by the University of
00022  *      California, Berkeley and its contributors.
00023  * 4. Neither the name of the University nor the names of its contributors
00024  *    may be used to endorse or promote products derived from this software
00025  *    without specific prior written permission.
00026  *
00027  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
00028  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00029  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00030  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
00031  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00032  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00033  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00034  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00035  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00036  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00037  * SUCH DAMAGE.
00038  *
00039  *      @(#)if_dl.h     8.1 (Berkeley) 6/10/93
00040  */
00041 #ifndef __NET_IF_DL_H
00042 #define __NET_IF_DL_H
00043
00044 #ifndef __SYS_W32API_H
00045 #include <sys/w32api.h>
00046 #endif
00047
00048 #ifndef __SYS_CDEFS_H
00049 #include <sys/cdefs.h>
00050 #endif
00051
00052 /*
00053  * A Link-Level Sockaddr may specify the interface in one of two
00054  * ways: either by means of a system-provided index number (computed
00055  * anew and possibly differently on every reboot), or by a human-readable
00056  * string such as "il0" (for managerial convenience).
00057  *
00058  * Census taking actions, such as something akin to SIOCGCONF would return
00059  * both the index and the human name.
00060  *
00061  * High volume transactions (such as giving a link-level ``from'' address
00062  * in a recvfrom or recvmsg call) may be likely only to provide the indexed
00063  * form, (which requires fewer copy operations and less space).
00064  *
00065  * The form and interpretation  of the link-level address is purely a matter
00066  * of convention between the device driver and its consumers; however, it is
00067  * expected that all drivers for an interface of a given if_type will agree.
00068  */
00069
00070 /*
00071  * Structure of a Link-Level sockaddr:
00072  */
00073 struct sockaddr_dl {
00074         u_char    sdl_len;      /* Total length of sockaddr */
00075         u_char    sdl_family;   /* AF_DLI */
00076         u_int16_t sdl_index;    /* if != 0, system given index for interface */
00077         u_char    sdl_type;     /* interface type */
00078         u_char    sdl_nlen;     /* interface name length, no trailing 0 reqd. */
00079         u_char    sdl_alen;     /* link level address length */
00080         u_char    sdl_slen;     /* link layer selector length */
00081         char      sdl_data[12]; /* minimum work area, can be larger;
00082                                    contains both if name and ll address */
00083 };
00084
00085 #define LLADDR(s) ((caddr_t)((s)->sdl_data + (s)->sdl_nlen))
00086
00087
00088 __BEGIN_DECLS
00089
00090 W32_FUNC void  link_addr (const char *, struct sockaddr_dl *);
00091 W32_FUNC char *link_ntoa (const struct sockaddr_dl *);
00092
00093 __END_DECLS
00094
00095 #endif
Generated on Wed Jan 25 15:42:32 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/net/IF_ETHER.H Source File

inc/net/IF_ETHER.H

00001
00004 #include <netinet/if_ether.h>
00005
Generated on Wed Jan 25 15:42:32 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/net/IF_FDDI.H Source File

inc/net/IF_FDDI.H

Go to the documentation of this file.
00001
00004 #include <netinet/if_fddi.h>
Generated on Wed Jan 25 15:42:32 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/net/IF_LLC.H Source File

inc/net/IF_LLC.H

Go to the documentation of this file.
00001
00005 /*      $NetBSD: if_llc.h,v 1.9 1997/05/02 21:08:54 christos Exp $      */
00006
00007 /*
00008  * Copyright (c) 1988, 1993
00009  *      The Regents of the University of California.  All rights reserved.
00010  *
00011  * Redistribution and use in source and binary forms, with or without
00012  * modification, are permitted provided that the following conditions
00013  * are met:
00014  * 1. Redistributions of source code must retain the above copyright
00015  *    notice, this list of conditions and the following disclaimer.
00016  * 2. Redistributions in binary form must reproduce the above copyright
00017  *    notice, this list of conditions and the following disclaimer in the
00018  *    documentation and/or other materials provided with the distribution.
00019  * 3. All advertising materials mentioning features or use of this software
00020  *    must display the following acknowledgement:
00021  *      This product includes software developed by the University of
00022  *      California, Berkeley and its contributors.
00023  * 4. Neither the name of the University nor the names of its contributors
00024  *    may be used to endorse or promote products derived from this software
00025  *    without specific prior written permission.
00026  *
00027  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
00028  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00029  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00030  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
00031  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00032  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00033  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00034  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00035  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00036  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00037  * SUCH DAMAGE.
00038  *
00039  *      @(#)if_llc.h    8.1 (Berkeley) 6/10/93
00040  */
00041 #ifndef __NET_IF_LLC_H
00042 #define __NET_IF_LLC_H
00043
00044 /*
00045  * IEEE 802.2 Link Level Control headers, for use in conjunction with
00046  * 802.{3,4,5} media access control methods.
00047  *
00048  * Headers here do not use bit fields due to shortcommings in many
00049  * compilers.
00050  */
00051
00052 #include <sys/packon.h>
00053
00054 struct llc {
00055         u_int8_t llc_dsap;
00056         u_int8_t llc_ssap;
00057         union {
00058             struct {
00059                 u_int8_t control;
00060                 u_int8_t format_id;
00061                 u_int8_t class;
00062                 u_int8_t window_x2;
00063             } type_u;
00064             struct {
00065                 u_int8_t num_snd_x2;
00066                 u_int8_t num_rcv_x2;
00067             } type_i;
00068             struct {
00069                 u_int8_t control;
00070                 u_int8_t num_rcv_x2;
00071             } type_s;
00072             struct {
00073                 u_int8_t control;
00074                 /*
00075                  * We cannot put the following fields in a structure because
00076                  * the structure rounding might cause padding.
00077                  */
00078                 u_int8_t frmr_rej_pdu0;
00079                 u_int8_t frmr_rej_pdu1;
00080                 u_int8_t frmr_control;
00081                 u_int8_t frmr_control_ext;
00082                 u_int8_t frmr_cause;
00083             } type_frmr;
00084             struct {
00085                 u_int8_t  control;
00086                 u_int8_t  org_code[3];
00087                 u_int16_t ether_type;
00088             } type_snap;
00089             struct {
00090                 u_int8_t control;
00091                 u_int8_t control_ext;
00092             } type_raw;
00093         } llc_un;
00094 };
00095
00096 struct frmrinfo {
00097         u_int8_t frmr_rej_pdu0;
00098         u_int8_t frmr_rej_pdu1;
00099         u_int8_t frmr_control;
00100         u_int8_t frmr_control_ext;
00101         u_int8_t frmr_cause;
00102 };
00103
00104 #include <sys/packoff.h>
00105
00106 #define llc_control             llc_un.type_u.control
00107 #define llc_control_ext         llc_un.type_raw.control_ext
00108 #define llc_fid                 llc_un.type_u.format_id
00109 #define llc_class               llc_un.type_u.class
00110 #define llc_window              llc_un.type_u.window_x2
00111 #define llc_frmrinfo            llc_un.type_frmr.frmr_rej_pdu0
00112 #define llc_frmr_pdu0           llc_un.type_frmr.frmr_rej_pdu0
00113 #define llc_frmr_pdu1           llc_un.type_frmr.frmr_rej_pdu1
00114 #define llc_frmr_control        llc_un.type_frmr.frmr_control
00115 #define llc_frmr_control_ext    llc_un.type_frmr.frmr_control_ext
00116 #define llc_frmr_cause          llc_un.type_frmr.frmr_cause
00117
00118 /*
00119  * Don't use sizeof(struct llc_un) for LLC header sizes
00120  */
00121 #define LLC_ISFRAMELEN 4
00122 #define LLC_UFRAMELEN  3
00123 #define LLC_FRMRLEN    7
00124
00125 /*
00126  * Unnumbered LLC format commands
00127  */
00128 #define LLC_UI          0x3
00129 #define LLC_UI_P        0x13
00130 #define LLC_DISC        0x43
00131 #define LLC_DISC_P      0x53
00132 #define LLC_UA          0x63
00133 #define LLC_UA_P        0x73
00134 #define LLC_TEST        0xe3
00135 #define LLC_TEST_P      0xf3
00136 #define LLC_FRMR        0x87
00137 #define LLC_FRMR_P      0x97
00138 #define LLC_DM          0x0f
00139 #define LLC_DM_P        0x1f
00140 #define LLC_XID         0xaf
00141 #define LLC_XID_P       0xbf
00142 #define LLC_SABME       0x6f
00143 #define LLC_SABME_P     0x7f
00144
00145 /*
00146  * Supervisory LLC commands
00147  */
00148 #define LLC_RR          0x01
00149 #define LLC_RNR         0x05
00150 #define LLC_REJ         0x09
00151
00152 /*
00153  * Info format - dummy only
00154  */
00155 #define LLC_INFO        0x00
00156
00157 /*
00158  * ISO PDTR 10178 contains among others
00159  */
00160 #define LLC_X25_LSAP    0x7e
00161 #define LLC_SNAP_LSAP   0xaa
00162 #define LLC_ISO_LSAP    0xfe
00163
00164 #endif
Generated on Wed Jan 25 15:42:32 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/net/IF_MEDIA.H Source File

inc/net/IF_MEDIA.H

Go to the documentation of this file.
00001
00005 /*      $NetBSD: if_media.h,v 1.3 1997/03/26 01:19:27 thorpej Exp $     */
00006
00007 /*
00008  * Copyright (c) 1997
00009  *      Jonathan Stone and Jason R. Thorpe.  All rights reserved.
00010  *
00011  * This software is derived from information provided by Matt Thomas.
00012  *
00013  * Redistribution and use in source and binary forms, with or without
00014  * modification, are permitted provided that the following conditions
00015  * are met:
00016  * 1. Redistributions of source code must retain the above copyright
00017  *    notice, this list of conditions and the following disclaimer.
00018  * 2. Redistributions in binary form must reproduce the above copyright
00019  *    notice, this list of conditions and the following disclaimer in the
00020  *    documentation and/or other materials provided with the distribution.
00021  * 3. All advertising materials mentioning features or use of this software
00022  *    must display the following acknowledgement:
00023  *      This product includes software developed by Jonathan Stone
00024  *      and Jason R. Thorpe for the NetBSD Project.
00025  * 4. The names of the authors may not be used to endorse or promote products
00026  *    derived from this software without specific prior written permission.
00027  *
00028  * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
00029  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00030  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
00031  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
00032  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00033  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00034  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
00035  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00036  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00037  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00038  * SUCH DAMAGE.
00039  */
00040
00041 #ifndef __NET_IF_MEDIA_H
00042 #define __NET_IF_MEDIA_H
00043
00044 /*
00045  * Prototypes and definitions for BSD/OS-compatible network interface
00046  * media selection.
00047  *
00048  * Where it is safe to do so, this code strays slightly from the BSD/OS
00049  * design.  Software which uses the API (device drivers, basically)
00050  * shouldn't notice any difference.
00051  *
00052  * Many thanks to Matt Thomas for providing the information necessary
00053  * to implement this interface.
00054  */
00055
00056
00057 /*
00058  * if_media Options word:
00059  *      Bits    Use
00060  *      ----    -------
00061  *      0-3     Media variant
00062  *      4       RFU
00063  *      5-7     Media type
00064  *      8-15    Type specific options
00065  *      16-19   RFU
00066  *      20-27   Shared (global) options
00067  *      28-31   Instance
00068  */
00069
00070 /*
00071  * Ethernet
00072  */
00073 #define IFM_ETHER       0x00000020
00074 #define IFM_10_T        3               /* 10BaseT - RJ45 */
00075 #define IFM_10_2        4               /* 10Base2 - Thinnet */
00076 #define IFM_10_5        5               /* 10Base5 - AUI */
00077 #define IFM_100_TX      6               /* 100BaseTX - RJ45 */
00078 #define IFM_100_FX      7               /* 100BaseFX - Fiber */
00079 #define IFM_100_T4      8               /* 100BaseT4 - 4 pair cat 3 */
00080 #define IFM_100_VG      9               /* 100VG-AnyLAN */
00081 #define IFM_100_T2      10              /* 100BaseT2 */
00082
00083 /*
00084  * Token ring
00085  */
00086 #define IFM_TOKEN       0x00000040
00087 #define IFM_TOK_STP4    3               /* Shielded twisted pair 4m - DB9 */
00088 #define IFM_TOK_STP16   4               /* Shielded twisted pair 16m - DB9 */
00089 #define IFM_TOK_UTP4    5               /* Unshielded twisted pair 4m - RJ45 */
00090 #define IFM_TOK_UTP16   6               /* Unshielded twisted pair 16m - RJ45 */
00091 #define IFM_TOK_ETR     0x00000200      /* Early token release */
00092 #define IFM_TOK_SRCRT   0x00000400      /* Enable source routing features */
00093 #define IFM_TOK_ALLR    0x00000800      /* All routes / Single route bcast */
00094
00095 /*
00096  * FDDI
00097  */
00098 #define IFM_FDDI        0x00000060
00099 #define IFM_FDDI_SMF    3               /* Single-mode fiber */
00100 #define IFM_FDDI_MMF    4               /* Multi-mode fiber */
00101 #define IFM_FDDI_UTP    5               /* CDDI / UTP */
00102 #define IFM_FDDI_DA     0x00000100      /* Dual attach / single attach */
00103
00104 /*
00105  * Shared media sub-types
00106  */
00107 #define IFM_AUTO        0               /* Autoselect best media */
00108 #define IFM_MANUAL      1               /* Jumper/dipswitch selects media */
00109 #define IFM_NONE        2               /* Deselect all media */
00110
00111 /*
00112  * Shared options
00113  */
00114 #define IFM_FDX         0x00100000      /* Force full duplex */
00115 #define IFM_HDX         0x00200000      /* Force half duplex */
00116 #define IFM_FLAG0       0x01000000      /* Driver defined flag */
00117 #define IFM_FLAG1       0x02000000      /* Driver defined flag */
00118 #define IFM_FLAG2       0x04000000      /* Driver defined flag */
00119 #define IFM_LOOP        0x08000000      /* Put hardware in loopback */
00120
00121 /*
00122  * Masks
00123  */
00124 #define IFM_NMASK       0x000000e0      /* Network type */
00125 #define IFM_TMASK       0x0000000f      /* Media sub-type */
00126 #define IFM_IMASK       0xf0000000      /* Instance */
00127 #define IFM_ISHIFT      28              /* Instance shift */
00128 #define IFM_OMASK       0x0000ff00      /* Type specific options */
00129 #define IFM_GMASK       0x0ff00000      /* Global options */
00130
00131 /*
00132  * Status bits
00133  */
00134 #define IFM_AVALID      0x00000001      /* Active bit valid */
00135 #define IFM_ACTIVE      0x00000002      /* Interface attached to working net */
00136
00137 /*
00138  * Macros to extract various bits of information from the media word.
00139  */
00140 #define IFM_TYPE(x)     ((x) & IFM_NMASK)
00141 #define IFM_SUBTYPE(x)  ((x) & IFM_TMASK)
00142 #define IFM_INST(x)     (((x) & IFM_IMASK) >> IFM_ISHIFT)
00143
00144 /*
00145  * NetBSD extension not defined in the BSDI API.  This is used in various
00146  * places to get the canonical description for a given type/subtype.
00147  *
00148  * NOTE: all but the top-level type descriptions must contain NO whitespace!
00149  * Otherwise, parsing these in ifconfig(8) would be a nightmare.
00150  */
00151 struct ifmedia_description {
00152         int     ifmt_word;              /* word value; may be masked */
00153         const char *ifmt_string;        /* description */
00154 };
00155
00156 #define IFM_TYPE_DESCRIPTIONS {                                         \
00157         { IFM_ETHER,    "Ethernet" },                                   \
00158         { IFM_TOKEN,    "Token ring" },                                 \
00159         { IFM_FDDI,     "FDDI" },                                       \
00160         { 0, NULL },                                                    \
00161 }
00162
00163 #define IFM_SUBTYPE_ETHERNET_DESCRIPTIONS {                             \
00164         { IFM_10_T,     "10baseT/UTP" },                                \
00165         { IFM_10_2,     "10base2/BNC" },                                \
00166         { IFM_10_5,     "10base5/AUI" },                                \
00167         { IFM_100_TX,   "100baseTX" },                                  \
00168         { IFM_100_FX,   "100baseFX" },                                  \
00169         { IFM_100_T4,   "100baseT4" },                                  \
00170         { IFM_100_VG,   "100baseVG" },                                  \
00171         { IFM_100_T2,   "100baseT2" },                                  \
00172         { 0, NULL },                                                    \
00173 }
00174
00175 #define IFM_SUBTYPE_ETHERNET_ALIASES {                                  \
00176         { IFM_10_T,     "UTP" },                                        \
00177         { IFM_10_T,     "10UTP" },                                      \
00178         { IFM_10_2,     "BNC" },                                        \
00179         { IFM_10_2,     "10BNC" },                                      \
00180         { IFM_10_5,     "AUI" },                                        \
00181         { IFM_10_5,     "10AUI" },                                      \
00182         { IFM_100_TX,   "100TX" },                                      \
00183         { IFM_100_FX,   "100FX" },                                      \
00184         { IFM_100_T4,   "100T4" },                                      \
00185         { IFM_100_VG,   "100VG" },                                      \
00186         { IFM_100_T2,   "100T2" },                                      \
00187         { 0, NULL },                                                    \
00188 }
00189
00190 #define IFM_SUBTYPE_ETHERNET_OPTION_DESCRIPTIONS {                      \
00191         { 0, NULL },                                                    \
00192 }
00193
00194 #define IFM_SUBTYPE_TOKENRING_DESCRIPTIONS {                            \
00195         { IFM_TOK_STP4, "DB9/4Mbit" },                                  \
00196         { IFM_TOK_STP16, "DB9/16Mbit" },                                \
00197         { IFM_TOK_UTP4, "UTP/4Mbit" },                                  \
00198         { IFM_TOK_UTP16, "UTP/16Mbit" },                                \
00199         { 0, NULL },                                                    \
00200 }
00201
00202 #define IFM_SUBTYPE_TOKENRING_ALIASES {                                 \
00203         { IFM_TOK_STP4, "4STP" },                                       \
00204         { IFM_TOK_STP16, "16STP" },                                     \
00205         { IFM_TOK_UTP4, "4UTP" },                                       \
00206         { IFM_TOK_UTP16, "16UTP" },                                     \
00207         { 0, NULL },                                                    \
00208 }
00209
00210 #define IFM_SUBTYPE_TOKENRING_OPTION_DESCRIPTIONS {                     \
00211         { IFM_TOK_ETR,  "EarlyTokenRelease" },                          \
00212         { IFM_TOK_SRCRT, "SourceRouting" },                             \
00213         { IFM_TOK_ALLR, "AllRoutes" },                                  \
00214         { 0, NULL },                                                    \
00215 }
00216
00217 #define IFM_SUBTYPE_FDDI_DESCRIPTIONS {                                 \
00218         { IFM_FDDI_SMF, "Single-mode" },                                \
00219         { IFM_FDDI_MMF, "Multi-mode" },                                 \
00220         { IFM_FDDI_UTP, "UTP" },                                        \
00221         { 0, NULL },                                                    \
00222 }
00223
00224 #define IFM_SUBTYPE_FDDI_ALIASES {                                      \
00225         { IFM_FDDI_SMF, "SMF" },                                        \
00226         { IFM_FDDI_MMF, "MMF" },                                        \
00227         { IFM_FDDI_UTP, "CDDI" },                                       \
00228         { 0, NULL },                                                    \
00229 }
00230
00231 #define IFM_SUBTYPE_FDDI_OPTION_DESCRIPTIONS {                          \
00232         { IFM_FDDI_DA, "Dual-attach" },                                 \
00233         { 0, NULL },                                                    \
00234 }
00235
00236 #define IFM_SUBTYPE_SHARED_DESCRIPTIONS {                               \
00237         { IFM_AUTO,     "autoselect" },                                 \
00238         { IFM_MANUAL,   "manual" },                                     \
00239         { IFM_NONE,     "none" },                                       \
00240         { 0, NULL },                                                    \
00241 }
00242
00243 #define IFM_SUBTYPE_SHARED_ALIASES {                                    \
00244         { IFM_AUTO,     "auto" },                                       \
00245         { 0, NULL },                                                    \
00246 }
00247
00248 #define IFM_SHARED_OPTION_DESCRIPTIONS {                                \
00249         { IFM_FDX,      "full-duplex" },                                \
00250         { IFM_HDX,      "half-duplex" },                                \
00251         { IFM_FLAG0,    "flag0" },                                      \
00252         { IFM_FLAG1,    "flag1" },                                      \
00253         { IFM_FLAG2,    "flag2" },                                      \
00254         { IFM_LOOP,     "hw-loopback" },                                \
00255         { 0, NULL },                                                    \
00256 }
00257
00258 #endif
Generated on Wed Jan 25 15:42:32 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/net/IF_PACKE.H Source File

inc/net/IF_PACKE.H

Go to the documentation of this file.
00001
00005 #ifndef __LINUX_IF_PACKET_H
00006 #define __LINUX_IF_PACKET_H
00007
00008 struct sockaddr_pkt
00009 {
00010     unsigned short spkt_family;
00011     unsigned char  spkt_device[14];
00012     unsigned short spkt_protocol;
00013 };
00014
00015 struct sockaddr_ll
00016 {
00017     unsigned short   sll_family;
00018     unsigned short   sll_protocol;
00019     int              sll_ifindex;
00020     unsigned short   sll_hatype;
00021     unsigned char    sll_pkttype;
00022     unsigned char    sll_halen;
00023     unsigned char    sll_addr[8];
00024 };
00025
00026 /* Packet types */
00027
00028 #define PACKET_HOST         0        /* To us */
00029 #define PACKET_BROADCAST    1        /* To all */
00030 #define PACKET_MULTICAST    2        /* To group */
00031 #define PACKET_OTHERHOST    3        /* To someone else */
00032 #define PACKET_OUTGOING     4        /* Outgoing of any type */
00033
00034 /* These ones are invisible by user level */
00035 #define PACKET_LOOPBACK     5        /* MC/BRD frame looped back */
00036 #define PACKET_FASTROUTE    6        /* Fastrouted frame */
00037
00038 /* Packet socket options */
00039
00040 #define PACKET_ADD_MEMBERSHIP   1
00041 #define PACKET_DROP_MEMBERSHIP  2
00042 #define PACKET_RECV_OUTPUT      3
00043
00044 /* Value 4 is still used by obsolete turbo-packet. */
00045 #define PACKET_RX_RING          5
00046 #define PACKET_STATISTICS       6
00047 #define PACKET_COPY_THRESH      7
00048
00049 struct tpacket_stats
00050 {
00051     unsigned int    tp_packets;
00052     unsigned int    tp_drops;
00053 };
00054
00055 struct tpacket_hdr
00056 {
00057     unsigned long    tp_status;
00058 #define TP_STATUS_KERNEL        0
00059 #define TP_STATUS_USER          1
00060 #define TP_STATUS_COPY          2
00061 #define TP_STATUS_LOSING        4
00062 #define TP_STATUS_CSUMNOTREADY  8
00063     unsigned int    tp_len;
00064     unsigned int    tp_snaplen;
00065     unsigned short  tp_mac;
00066     unsigned short  tp_net;
00067     unsigned int    tp_sec;
00068     unsigned int    tp_usec;
00069 };
00070
00071 #define TPACKET_ALIGNMENT  16
00072 #define TPACKET_ALIGN(x)  (((x)+TPACKET_ALIGNMENT-1) & ~(TPACKET_ALIGNMENT-1))
00073 #define TPACKET_HDRLEN    (TPACKET_ALIGN(sizeof(struct tpacket_hdr)) + sizeof(struct sockaddr_ll))
00074
00075 /*
00076    Frame structure:
00077
00078    - Start. Frame must be aligned to TPACKET_ALIGNMENT=16
00079    - struct tpacket_hdr
00080    - pad to TPACKET_ALIGNMENT=16
00081    - struct sockaddr_ll
00082    - Gap, chosen so that packet data (Start+tp_net) alignes to TPACKET_ALIGNMENT=16
00083    - Start+tp_mac: [ Optional MAC header ]
00084    - Start+tp_net: Packet data, aligned to TPACKET_ALIGNMENT=16.
00085    - Pad to align to TPACKET_ALIGNMENT=16
00086  */
00087
00088 struct tpacket_req
00089 {
00090     unsigned int    tp_block_size;  /* Minimal size of contiguous block */
00091     unsigned int    tp_block_nr;    /* Number of blocks */
00092     unsigned int    tp_frame_size;  /* Size of frame */
00093     unsigned int    tp_frame_nr;    /* Total number of frames */
00094 };
00095
00096 struct packet_mreq
00097 {
00098     int             mr_ifindex;
00099     unsigned short  mr_type;
00100     unsigned short  mr_alen;
00101     unsigned char   mr_address[8];
00102 };
00103
00104 #define PACKET_MR_MULTICAST  0
00105 #define PACKET_MR_PROMISC    1
00106 #define PACKET_MR_ALLMULTI   2
00107
00108 #endif
Generated on Wed Jan 25 15:42:32 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/net/IF_PPP.H Source File

inc/net/IF_PPP.H

Go to the documentation of this file.
00001
00005 /*      $NetBSD: if_ppp.h,v 1.14 1997/05/17 21:12:02 christos Exp $     */
00006 /*      Id: if_ppp.h,v 1.16 1997/04/30 05:46:04 paulus Exp      */
00007
00008 /*
00009  * if_ppp.h - Point-to-Point Protocol definitions.
00010  *
00011  * Copyright (c) 1989 Carnegie Mellon University.
00012  * All rights reserved.
00013  *
00014  * Redistribution and use in source and binary forms are permitted
00015  * provided that the above copyright notice and this paragraph are
00016  * duplicated in all such forms and that any documentation,
00017  * advertising materials, and other materials related to such
00018  * distribution and use acknowledge that the software was developed
00019  * by Carnegie Mellon University.  The name of the
00020  * University may not be used to endorse or promote products derived
00021  * from this software without specific prior written permission.
00022  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
00023  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
00024  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00025  */
00026
00027 #ifndef __NET_IF_PPP_H
00028 #define __NET_IF_PPP_H
00029
00030 /*
00031  * Bit definitions for flags.
00032  */
00033 #define SC_COMP_PROT    0x00000001      /* protocol compression (output) */
00034 #define SC_COMP_AC      0x00000002      /* header compression (output) */
00035 #define SC_COMP_TCP     0x00000004      /* TCP (VJ) compression (output) */
00036 #define SC_NO_TCP_CCID  0x00000008      /* disable VJ connection-id comp. */
00037 #define SC_REJ_COMP_AC  0x00000010      /* reject adrs/ctrl comp. on input */
00038 #define SC_REJ_COMP_TCP 0x00000020      /* reject TCP (VJ) comp. on input */
00039 #define SC_CCP_OPEN     0x00000040      /* Look at CCP packets */
00040 #define SC_CCP_UP       0x00000080      /* May send/recv compressed packets */
00041 #define SC_DEBUG        0x00010000      /* enable debug messages */
00042 #define SC_LOG_INPKT    0x00020000      /* log contents of good pkts recvd */
00043 #define SC_LOG_OUTPKT   0x00040000      /* log contents of pkts sent */
00044 #define SC_LOG_RAWIN    0x00080000      /* log all chars received */
00045 #define SC_LOG_FLUSH    0x00100000      /* log all chars flushed */
00046 #define SC_RCV_B7_0     0x01000000      /* have rcvd char with bit 7 = 0 */
00047 #define SC_RCV_B7_1     0x02000000      /* have rcvd char with bit 7 = 1 */
00048 #define SC_RCV_EVNP     0x04000000      /* have rcvd char with even parity */
00049 #define SC_RCV_ODDP     0x08000000      /* have rcvd char with odd parity */
00050 #define SC_MASK         0x0fff00ff      /* bits that user can change */
00051
00052 /*
00053  * State bits in sc_flags, not changeable by user.
00054  */
00055 #define SC_TIMEOUT      0x00000400      /* timeout is currently pending */
00056 #define SC_VJ_RESET     0x00000800      /* need to reset VJ decomp */
00057 #define SC_COMP_RUN     0x00001000      /* compressor has been inited */
00058 #define SC_DECOMP_RUN   0x00002000      /* decompressor has been inited */
00059 #define SC_DC_ERROR     0x00004000      /* non-fatal decomp error detected */
00060 #define SC_DC_FERROR    0x00008000      /* fatal decomp error detected */
00061 #define SC_TBUSY        0x10000000      /* xmitter doesn't need a packet yet */
00062 #define SC_PKTLOST      0x20000000      /* have lost or dropped a packet */
00063 #define SC_FLUSH        0x40000000      /* flush input until next PPP_FLAG */
00064 #define SC_ESCAPED      0x80000000      /* saw a PPP_ESCAPE */
00065
00066 /*
00067  * Ioctl definitions.
00068  */
00069
00070 struct npioctl {
00071     int         protocol;       /* PPP procotol, e.g. PPP_IP */
00072     enum NPmode mode;
00073 };
00074
00075 /* Structure describing a CCP configuration option, for PPPIOCSCOMPRESS */
00076 struct ppp_option_data {
00077         u_char  *ptr;
00078         u_int   length;
00079         int     transmit;
00080 };
00081
00082 struct ifpppstatsreq {
00083     char ifr_name[IFNAMSIZ];
00084     struct ppp_stats stats;
00085 };
00086
00087 struct ifpppcstatsreq {
00088     char ifr_name[IFNAMSIZ];
00089     struct ppp_comp_stats stats;
00090 };
00091
00092 /*
00093  * Ioctl definitions.
00094  */
00095
00096 #define PPPIOCGFLAGS    _IOR('t', 90, int)      /* get configuration flags */
00097 #define PPPIOCSFLAGS    _IOW('t', 89, int)      /* set configuration flags */
00098 #define PPPIOCGASYNCMAP _IOR('t', 88, int)      /* get async map */
00099 #define PPPIOCSASYNCMAP _IOW('t', 87, int)      /* set async map */
00100 #define PPPIOCGUNIT     _IOR('t', 86, int)      /* get ppp unit number */
00101 #define PPPIOCGRASYNCMAP _IOR('t', 85, int)     /* get receive async map */
00102 #define PPPIOCSRASYNCMAP _IOW('t', 84, int)     /* set receive async map */
00103 #define PPPIOCGMRU      _IOR('t', 83, int)      /* get max receive unit */
00104 #define PPPIOCSMRU      _IOW('t', 82, int)      /* set max receive unit */
00105 #define PPPIOCSMAXCID   _IOW('t', 81, int)      /* set VJ max slot ID */
00106 #define PPPIOCGXASYNCMAP _IOR('t', 80, ext_accm) /* get extended ACCM */
00107 #define PPPIOCSXASYNCMAP _IOW('t', 79, ext_accm) /* set extended ACCM */
00108 #define PPPIOCXFERUNIT  _IO('t', 78)            /* transfer PPP unit */
00109 #define PPPIOCSCOMPRESS _IOW('t', 77, struct ppp_option_data)
00110 #define PPPIOCGNPMODE   _IOWR('t', 76, struct npioctl) /* get NP mode */
00111 #define PPPIOCSNPMODE   _IOW('t', 75, struct npioctl)  /* set NP mode */
00112 #define PPPIOCGIDLE     _IOR('t', 74, struct ppp_idle) /* get idle time */
00113 #ifdef PPP_FILTER
00114 #define PPPIOCSPASS     _IOW('t', 71, struct bpf_program) /* set pass filter */
00115 #define PPPIOCSACTIVE   _IOW('t', 70, struct bpf_program) /* set active filt */
00116 #endif /* PPP_FILTER */
00117
00118 /* PPPIOC[GS]MTU are alternatives to SIOC[GS]IFMTU, used under Ultrix */
00119 #define PPPIOCGMTU      _IOR('t', 73, int)      /* get interface MTU */
00120 #define PPPIOCSMTU      _IOW('t', 72, int)      /* set interface MTU */
00121
00122 /*
00123  * These two are interface ioctls so that pppstats can do them on
00124  * a socket without having to open the serial device.
00125  */
00126 #define SIOCGPPPSTATS   _IOWR('i', 123, struct ifpppstatsreq)
00127 #define SIOCGPPPCSTATS  _IOWR('i', 122, struct ifpppcstatsreq)
00128
00129 #ifndef ifr_mtu
00130 #define ifr_mtu ifr_ifru.ifru_metric
00131 #endif
00132
00133 #endif
Generated on Wed Jan 25 15:42:32 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/net/IF_PPPVA.H Source File

inc/net/IF_PPPVA.H

Go to the documentation of this file.
00001
00005 /*      $NetBSD: if_pppvar.h,v 1.7 1997/05/17 21:12:03 christos Exp $   */
00006 /*      Id: if_pppvar.h,v 1.3 1996/07/01 01:04:37 paulus Exp     */
00007
00008 /*
00009  * if_pppvar.h - private structures and declarations for PPP.
00010  *
00011  * Copyright (c) 1994 The Australian National University.
00012  * All rights reserved.
00013  *
00014  * Permission to use, copy, modify, and distribute this software and its
00015  * documentation is hereby granted, provided that the above copyright
00016  * notice appears in all copies.  This software is provided without any
00017  * warranty, express or implied. The Australian National University
00018  * makes no representations about the suitability of this software for
00019  * any purpose.
00020  *
00021  * IN NO EVENT SHALL THE AUSTRALIAN NATIONAL UNIVERSITY BE LIABLE TO ANY
00022  * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
00023  * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
00024  * THE AUSTRALIAN NATIONAL UNIVERSITY HAVE BEEN ADVISED OF THE POSSIBILITY
00025  * OF SUCH DAMAGE.
00026  *
00027  * THE AUSTRALIAN NATIONAL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
00028  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
00029  * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
00030  * ON AN "AS IS" BASIS, AND THE AUSTRALIAN NATIONAL UNIVERSITY HAS NO
00031  * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS,
00032  * OR MODIFICATIONS.
00033  *
00034  * Copyright (c) 1989 Carnegie Mellon University.
00035  * All rights reserved.
00036  *
00037  * Redistribution and use in source and binary forms are permitted
00038  * provided that the above copyright notice and this paragraph are
00039  * duplicated in all such forms and that any documentation,
00040  * advertising materials, and other materials related to such
00041  * distribution and use acknowledge that the software was developed
00042  * by Carnegie Mellon University.  The name of the
00043  * University may not be used to endorse or promote products derived
00044  * from this software without specific prior written permission.
00045  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
00046  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
00047  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00048  */
00049
00050 #ifndef __NET_IF_PPPVAR_H
00051 #define __NET_IF_PPPVAR_H
00052
00053 /*
00054  * Supported network protocols.  These values are used for
00055  * indexing sc_npmode.
00056  */
00057 #define NP_IP   0               /* Internet Protocol */
00058 #define NUM_NP  1               /* Number of NPs. */
00059
00060 /*
00061  * Structure describing each ppp unit.
00062  */
00063 struct ppp_softc {
00064         struct  ifnet sc_if;            /* network-visible interface */
00065         int     sc_unit;                /* XXX unit number */
00066         u_int   sc_flags;               /* control/status bits; see if_ppp.h */
00067         void    *sc_devp;               /* pointer to device-dep structure */
00068         void    (*sc_start) __P((struct ppp_softc *));  /* start output proc */
00069         void    (*sc_ctlp) __P((struct ppp_softc *)); /* rcvd control pkt */
00070         void    (*sc_relinq) __P((struct ppp_softc *)); /* relinquish ifunit */
00071         u_int16_t sc_mru;               /* max receive unit */
00072         int     sc_xfer;                /* used in transferring unit */
00073         struct  ifqueue sc_rawq;        /* received packets */
00074         struct  ifqueue sc_inq;         /* queue of input packets for daemon */
00075         struct  ifqueue sc_fastq;       /* interactive output packet q */
00076         struct  mbuf *sc_togo;          /* output packet ready to go */
00077         struct  mbuf *sc_npqueue;       /* output packets not to be sent yet */
00078         struct  mbuf **sc_npqtail;      /* ptr to last next ptr in npqueue */
00079         struct  pppstat sc_stats;       /* count of bytes/pkts sent/rcvd */
00080         caddr_t sc_bpf;                 /* hook for BPF */
00081         enum    NPmode sc_npmode[NUM_NP]; /* what to do with each NP */
00082         struct  compressor *sc_xcomp;   /* transmit compressor */
00083         void    *sc_xc_state;           /* transmit compressor state */
00084         struct  compressor *sc_rcomp;   /* receive decompressor */
00085         void    *sc_rc_state;           /* receive decompressor state */
00086         time_t  sc_last_sent;           /* time (secs) last NP pkt sent */
00087         time_t  sc_last_recv;           /* time (secs) last NP pkt rcvd */
00088 #ifdef PPP_FILTER
00089         struct  bpf_program sc_pass_filt;   /* filter for packets to pass */
00090         struct  bpf_program sc_active_filt; /* filter for "non-idle" packets */
00091 #endif /* PPP_FILTER */
00092 #ifdef  VJC
00093         struct  slcompress *sc_comp;    /* vjc control buffer */
00094 #endif
00095
00096         /* Device-dependent part for async lines. */
00097         ext_accm sc_asyncmap;           /* async control character map */
00098         u_int32_t sc_rasyncmap;         /* receive async control char map */
00099         struct  mbuf *sc_outm;          /* mbuf chain currently being output */
00100         struct  mbuf *sc_m;             /* pointer to input mbuf chain */
00101         struct  mbuf *sc_mc;            /* pointer to current input mbuf */
00102         char    *sc_mp;                 /* ptr to next char in input mbuf */
00103         u_int16_t sc_ilen;              /* length of input packet so far */
00104         u_int16_t sc_fcs;               /* FCS so far (input) */
00105         u_int16_t sc_outfcs;            /* FCS so far for output packet */
00106         u_char  sc_rawin[16];           /* chars as received */
00107         int     sc_rawin_count;         /* # in sc_rawin */
00108 };
00109
00110 #endif
Generated on Wed Jan 25 15:42:32 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/net/IF_SLVAR.H Source File

inc/net/IF_SLVAR.H

Go to the documentation of this file.
00001
00005 /*      $NetBSD: if_slvar.h,v 1.17 1997/03/27 20:36:17 thorpej Exp $    */
00006
00007 /*-
00008  * Copyright (c) 1991, 1993
00009  *      The Regents of the University of California.  All rights reserved.
00010  *
00011  * Redistribution and use in source and binary forms, with or without
00012  * modification, are permitted provided that the following conditions
00013  * are met:
00014  * 1. Redistributions of source code must retain the above copyright
00015  *    notice, this list of conditions and the following disclaimer.
00016  * 2. Redistributions in binary form must reproduce the above copyright
00017  *    notice, this list of conditions and the following disclaimer in the
00018  *    documentation and/or other materials provided with the distribution.
00019  * 3. All advertising materials mentioning features or use of this software
00020  *    must display the following acknowledgement:
00021  *      This product includes software developed by the University of
00022  *      California, Berkeley and its contributors.
00023  * 4. Neither the name of the University nor the names of its contributors
00024  *    may be used to endorse or promote products derived from this software
00025  *    without specific prior written permission.
00026  *
00027  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
00028  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00029  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00030  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
00031  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00032  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00033  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00034  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00035  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00036  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00037  * SUCH DAMAGE.
00038  *
00039  *      @(#)if_slvar.h  8.3 (Berkeley) 2/1/94
00040  */
00041 #ifndef __NET_IF_SLVAR_H
00042 #define __NET_IF_SLVAR_H
00043
00044 /*
00045  * Definitions for SLIP interface data structures
00046  *
00047  * (This exists so programs like slstats can get at the definition
00048  *  of sl_softc.)
00049  */
00050
00051 struct sl_softc {
00052         struct  ifnet sc_if;            /* network-visible interface */
00053         int     sc_unit;                /* XXX unit number */
00054         struct  ifqueue sc_fastq;       /* interactive output queue */
00055         struct  tty *sc_ttyp;           /* pointer to tty structure */
00056         u_char  *sc_mp;                 /* pointer to next available buf char */
00057         u_char  *sc_ep;                 /* pointer to last available buf char */
00058         u_char  *sc_buf;                /* input buffer */
00059         u_char  *sc_xxx;                /* XXX don't ask... */
00060         u_int   sc_flags;               /* see below */
00061         u_int   sc_escape;      /* =1 if last char input was FRAME_ESCAPE */
00062         long    sc_lasttime;            /* last time a char arrived */
00063         long    sc_abortcount;          /* number of abort esacpe chars */
00064         long    sc_starttime;           /* time of first abort in window */
00065         long    sc_oqlen;               /* previous output queue size */
00066         long    sc_otimeout;            /* number of times output's stalled */
00067 #ifdef NetBSD
00068         int     sc_oldbufsize;          /* previous output buffer size */
00069         int     sc_oldbufquot;          /* previous output buffer quoting */
00070 #endif
00071 #ifdef INET                             /* XXX */
00072         struct  slcompress sc_comp;     /* tcp compression data */
00073 #endif
00074         caddr_t sc_bpf;                 /* BPF data */
00075 };
00076
00077 /* internal flags */
00078 #define SC_ERROR        0x0001          /* had an input error */
00079
00080 /* visible flags */
00081 #define SC_COMPRESS     IFF_LINK0       /* compress TCP traffic */
00082 #define SC_NOICMP       IFF_LINK1       /* supress ICMP traffic */
00083 #define SC_AUTOCOMP     IFF_LINK2       /* auto-enable TCP compression */
00084
00085 #endif
Generated on Wed Jan 25 15:42:32 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/net/IF_STRIP.H Source File

inc/net/IF_STRIP.H

Go to the documentation of this file.
00001
00005 /*      $NetBSD: if_stripvar.h,v 1.4.8.1 1997/11/17 23:36:16 thorpej Exp $      */
00006
00007 /*
00008  * Definitions for SLIP interface data structures
00009  *
00010  * (This exists so programs like slstats can get at the definition
00011  *  of sl_softc.)
00012  */
00013
00014 #ifndef __NET_IF_STRIP_H
00015 #define __NET_IF_STRIP_H
00016
00017 struct strip_softc {
00018         struct  ifnet sc_if;            /* network-visible interface */
00019         int     sc_unit;                /* XXX unit number */
00020         struct  ifqueue sc_fastq;       /* interactive output queue */
00021         struct  tty *sc_ttyp;           /* pointer to tty structure */
00022         u_char  *sc_mp;                 /* pointer to next available buf char */
00023         u_char  *sc_ep;                 /* pointer to last available buf char */
00024         u_char  *sc_buf;                /* input buffer */
00025         u_char  *sc_rxbuf;              /* input destuffing buffer */
00026         u_char  *sc_txbuf;              /* output stuffing buffer */
00027         u_char  *sc_xxx;                /* XXX don't ask... */
00028         u_int   sc_flags;               /* see below */
00029         long    sc_oqlen;               /* previous output queue size */
00030         long    sc_otimeout;            /* number of times output's stalled */
00031 #ifdef __NetBSD__
00032         int     sc_oldbufsize;          /* previous output buffer size */
00033         int     sc_oldbufquot;          /* previous output buffer quoting */
00034 #endif
00035 #ifdef INET                             /* XXX */
00036         struct  slcompress sc_comp;     /* tcp compression data */
00037 #endif
00038
00039         int sc_state;                   /* Radio reset state-machine */
00040 #define ST_ALIVE        0x0             /*    answered  probe */
00041 #define ST_PROBE_SENT   0x1             /*    probe sent, answer pending */
00042 #define ST_DEAD         0x2             /*    no answer to probe; do reset */
00043
00044         long sc_statetimo;              /* When (secs) current state ends */
00045
00046         caddr_t sc_bpf;                 /* BPF data */
00047 };
00048
00049
00050 /* Internal flags */
00051 #define SC_ERROR        0x0001          /* Incurred error reading current pkt*/
00052
00053 #define SC_TIMEOUT      0x00000400      /* timeout is currently pending */
00054
00055 /* visible flags */
00056 #define SC_COMPRESS     IFF_LINK0       /* compress TCP traffic */
00057 #define SC_NOICMP       IFF_LINK1       /* supress ICMP traffic */
00058 #define SC_AUTOCOMP     IFF_LINK2       /* auto-enable TCP compression */
00059
00060 #endif
Generated on Wed Jan 25 15:42:32 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/net/IF_TUN.H Source File

inc/net/IF_TUN.H

Go to the documentation of this file.
00001
00005 /*      $NetBSD: if_tun.h,v 1.6 1996/06/25 22:15:18 pk Exp $    */
00006
00007 /*
00008  * Copyright (c) 1988, Julian Onions <jpo@cs.nott.ac.uk>
00009  * Nottingham University 1987.
00010  *
00011  * This source may be freely distributed, however I would be interested
00012  * in any changes that are made.
00013  *
00014  * This driver takes packets off the IP i/f and hands them up to a
00015  * user process to have it's wicked way with. This driver has it's
00016  * roots in a similar driver written by Phil Cockcroft (formerly) at
00017  * UCL. This driver is based much more on read/write/select mode of
00018  * operation though.
00019  *
00020  * : $Header: if_tnreg.h,v 1.1.2.1 1992/07/16 22:39:16 friedl Exp
00021  */
00022
00023 #ifndef __NET_IF_TUN_H
00024 #define __NET_IF_TUN_H
00025
00026 struct tun_softc {
00027         u_short tun_flags;              /* misc flags */
00028 #define TUN_OPEN        0x0001
00029 #define TUN_INITED      0x0002
00030 #define TUN_RCOLL       0x0004
00031 #define TUN_IASET       0x0008
00032 #define TUN_DSTADDR     0x0010
00033 #define TUN_RWAIT       0x0040
00034 #define TUN_ASYNC       0x0080
00035 #define TUN_NBIO        0x0100
00036 #define TUN_PREPADDR    0x0200
00037
00038 #define TUN_READY       (TUN_OPEN | TUN_INITED | TUN_IASET)
00039
00040         struct  ifnet tun_if;           /* the interface */
00041         int     tun_pgrp;               /* the process group - if any */
00042         struct  selinfo tun_rsel;       /* read select */
00043         struct  selinfo tun_wsel;       /* write select (not used) */
00044 #if NBPFILTER > 0
00045         caddr_t         tun_bpf;
00046 #endif
00047 };
00048
00049 /* Maximum packet size */
00050 #define TUNMTU          1500
00051
00052 /* ioctl's for get/set debug */
00053 #define TUNSDEBUG       _IOW('t', 90, int)
00054 #define TUNGDEBUG       _IOR('t', 89, int)
00055 #define TUNSIFMODE      _IOW('t', 88, int)
00056 #define TUNSLMODE       _IOW('t', 87, int)
00057
00058 #endif
Generated on Wed Jan 25 15:42:32 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/net/IF_TYPES.H Source File

inc/net/IF_TYPES.H

Go to the documentation of this file.
00001
00005 /*      $NetBSD: if_types.h,v 1.7 1995/02/27 09:10:24 glass Exp $       */
00006
00007 /*
00008  * Copyright (c) 1989, 1993, 1994
00009  *      The Regents of the University of California.  All rights reserved.
00010  *
00011  * Redistribution and use in source and binary forms, with or without
00012  * modification, are permitted provided that the following conditions
00013  * are met:
00014  * 1. Redistributions of source code must retain the above copyright
00015  *    notice, this list of conditions and the following disclaimer.
00016  * 2. Redistributions in binary form must reproduce the above copyright
00017  *    notice, this list of conditions and the following disclaimer in the
00018  *    documentation and/or other materials provided with the distribution.
00019  * 3. All advertising materials mentioning features or use of this software
00020  *    must display the following acknowledgement:
00021  *      This product includes software developed by the University of
00022  *      California, Berkeley and its contributors.
00023  * 4. Neither the name of the University nor the names of its contributors
00024  *    may be used to endorse or promote products derived from this software
00025  *    without specific prior written permission.
00026  *
00027  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
00028  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00029  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00030  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
00031  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00032  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00033  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00034  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00035  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00036  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00037  * SUCH DAMAGE.
00038  *
00039  *      @(#)if_types.h  8.2 (Berkeley) 4/20/94
00040  */
00041
00042 /*
00043  * Interface types for benefit of parsing media address headers.
00044  * This list is derived from the SNMP list of ifTypes, currently
00045  * documented in RFC1573.
00046  */
00047 #ifndef __NET_IF_TYPES_H
00048 #define __NET_IF_TYPES_H
00049
00050 #define IFT_OTHER       0x1             /* none of the following */
00051 #define IFT_1822        0x2             /* old-style arpanet imp */
00052 #define IFT_HDH1822     0x3             /* HDH arpanet imp */
00053 #define IFT_X25DDN      0x4             /* x25 to imp */
00054 #define IFT_X25         0x5             /* PDN X25 interface (RFC877) */
00055 #define IFT_ETHER       0x6             /* Ethernet CSMACD */
00056 #define IFT_ISO88023    0x7             /* CMSA CD */
00057 #define IFT_ISO88024    0x8             /* Token Bus */
00058 #define IFT_ISO88025    0x9             /* Token Ring */
00059 #define IFT_ISO88026    0xa             /* MAN */
00060 #define IFT_STARLAN     0xb
00061 #define IFT_P10         0xc             /* Proteon 10MBit ring */
00062 #define IFT_P80         0xd             /* Proteon 80MBit ring */
00063 #define IFT_HY          0xe             /* Hyperchannel */
00064 #define IFT_FDDI        0xf
00065 #define IFT_LAPB        0x10
00066 #define IFT_SDLC        0x11
00067 #define IFT_T1          0x12
00068 #define IFT_CEPT        0x13            /* E1 - european T1 */
00069 #define IFT_ISDNBASIC   0x14
00070 #define IFT_ISDNPRIMARY 0x15
00071 #define IFT_PTPSERIAL   0x16            /* Proprietary PTP serial */
00072 #define IFT_PPP         0x17            /* RFC 1331 */
00073 #define IFT_LOOP        0x18            /* loopback */
00074 #define IFT_EON         0x19            /* ISO over IP */
00075 #define IFT_XETHER      0x1a            /* obsolete 3MB experimental ethernet */
00076 #define IFT_NSIP        0x1b            /* XNS over IP */
00077 #define IFT_SLIP        0x1c            /* IP over generic TTY */
00078 #define IFT_ULTRA       0x1d            /* Ultra Technologies */
00079 #define IFT_DS3         0x1e            /* Generic T3 */
00080 #define IFT_SIP         0x1f            /* SMDS */
00081 #define IFT_FRELAY      0x20            /* Frame Relay DTE only */
00082 #define IFT_RS232       0x21
00083 #define IFT_PARA        0x22            /* parallel-port */
00084 #define IFT_ARCNET      0x23
00085 #define IFT_ARCNETPLUS  0x24
00086 #define IFT_ATM         0x25            /* ATM cells */
00087 #define IFT_MIOX25      0x26
00088 #define IFT_SONET       0x27            /* SONET or SDH */
00089 #define IFT_X25PLE      0x28
00090 #define IFT_ISO88022LLC 0x29
00091 #define IFT_LOCALTALK   0x2a
00092 #define IFT_SMDSDXI     0x2b
00093 #define IFT_FRELAYDCE   0x2c            /* Frame Relay DCE */
00094 #define IFT_V35         0x2d
00095 #define IFT_HSSI        0x2e
00096 #define IFT_HIPPI       0x2f
00097 #define IFT_MODEM       0x30            /* Generic Modem */
00098 #define IFT_AAL5        0x31            /* AAL5 over ATM */
00099 #define IFT_SONETPATH   0x32
00100 #define IFT_SONETVT     0x33
00101 #define IFT_SMDSICIP    0x34            /* SMDS InterCarrier Interface */
00102 #define IFT_PROPVIRTUAL 0x35            /* Proprietary Virtual/internal */
00103 #define IFT_PROPMUX     0x36            /* Proprietary Multiplexing */
00104
00105 #endif
Generated on Wed Jan 25 15:42:32 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/net/NETISR.H Source File

inc/net/NETISR.H

Go to the documentation of this file.
00001
00005 /*      $NetBSD: netisr.h,v 1.15 1997/04/02 21:23:29 christos Exp $     */
00006
00007 /*
00008  * Copyright (c) 1980, 1986, 1989, 1993
00009  *      The Regents of the University of California.  All rights reserved.
00010  *
00011  * Redistribution and use in source and binary forms, with or without
00012  * modification, are permitted provided that the following conditions
00013  * are met:
00014  * 1. Redistributions of source code must retain the above copyright
00015  *    notice, this list of conditions and the following disclaimer.
00016  * 2. Redistributions in binary form must reproduce the above copyright
00017  *    notice, this list of conditions and the following disclaimer in the
00018  *    documentation and/or other materials provided with the distribution.
00019  * 3. All advertising materials mentioning features or use of this software
00020  *    must display the following acknowledgement:
00021  *      This product includes software developed by the University of
00022  *      California, Berkeley and its contributors.
00023  * 4. Neither the name of the University nor the names of its contributors
00024  *    may be used to endorse or promote products derived from this software
00025  *    without specific prior written permission.
00026  *
00027  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
00028  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00029  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00030  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
00031  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00032  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00033  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00034  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00035  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00036  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00037  * SUCH DAMAGE.
00038  *
00039  *      @(#)netisr.h    8.1 (Berkeley) 6/10/93
00040  */
00041
00042 #ifndef __NET_NETISR_H
00043 #define __NET_NETISR_H
00044
00045 /*
00046  * The networking code runs off software interrupts.
00047  *
00048  * You can switch into the network by doing splsoftnet() and return by splx().
00049  * The software interrupt level for the network is higher than the software
00050  * level for the clock (so you can enter the network in routines called
00051  * at timeout time).
00052  *
00053  * The routine to request a network software interrupt, setsoftnet(),
00054  * is defined in the machine-specific include files.
00055  */
00056
00057 /*
00058  * Each ``pup-level-1'' input queue has a bit in a ``netisr'' status
00059  * word which is used to de-multiplex a single software
00060  * interrupt used for scheduling the network code to calls
00061  * on the lowest level routine of each protocol.
00062  */
00063 #define NETISR_IP       2               /* same as AF_INET */
00064 #define NETISR_IMP      3               /* same as AF_IMPLINK */
00065 #define NETISR_NS       6               /* same as AF_NS */
00066 #define NETISR_ISO      7               /* same as AF_ISO */
00067 #define NETISR_CCITT    10              /* same as AF_CCITT */
00068 #define NETISR_ATALK    16              /* same as AF_APPLETALK */
00069 #define NETISR_ARP      18              /* same as AF_LINK */
00070 #define NETISR_ISDN     26              /* same as AF_E164 */
00071 #define NETISR_NATM     27              /* same as AF_NATM */
00072 #define NETISR_PPP      28              /* for PPP processing */
00073
00074 #define schednetisr(anisr)      { netisr |= 1<<(anisr); setsoftnet(); }
00075
00076 extern int netisr;         /* scheduling bits for network */
00077
00078 #endif
Generated on Wed Jan 25 15:42:32 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/net/PFIL.H Source File

inc/net/PFIL.H

Go to the documentation of this file.
00001
00005 /*      $NetBSD: pfil.h,v 1.8 1997/10/10 05:40:26 mrg Exp $     */
00006
00007 /*
00008  * Copyright (c) 1996 Matthew R. Green
00009  * All rights reserved.
00010  *
00011  * Redistribution and use in source and binary forms, with or without
00012  * modification, are permitted provided that the following conditions
00013  * are met:
00014  * 1. Redistributions of source code must retain the above copyright
00015  *    notice, this list of conditions and the following disclaimer.
00016  * 2. Redistributions in binary form must reproduce the above copyright
00017  *    notice, this list of conditions and the following disclaimer in the
00018  *    documentation and/or other materials provided with the distribution.
00019  * 3. The name of the author may not be used to endorse or promote products
00020  *    derived from this software without specific prior written permission.
00021  *
00022  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
00023  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00024  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
00025  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
00026  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00027  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00028  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
00029  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00030  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00031  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00032  * SUCH DAMAGE.
00033  */
00034
00035 #ifndef __NET_PFIL_H
00036 #define __NET_PFIL_H
00037
00038 /* note: this file needs <net/if.h> and <sys/mbuf.h> */
00039
00040 #if NIPFILTER > 0
00041 #ifdef PFIL_HOOKS
00042 #undef PFIL_HOOKS
00043 #endif
00044 #define PFIL_HOOKS
00045 #endif /* NIPFILTER */
00046
00047 #endif
Generated on Wed Jan 25 15:42:32 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/net/PPP-COMP.H Source File

inc/net/PPP-COMP.H

Go to the documentation of this file.
00001
00005 /*      $NetBSD: ppp-comp.h,v 1.3 1997/03/12 20:26:55 christos Exp $    */
00006
00007 /*
00008  * ppp-comp.h - Definitions for doing PPP packet compression.
00009  *
00010  * Copyright (c) 1994 The Australian National University.
00011  * All rights reserved.
00012  *
00013  * Permission to use, copy, modify, and distribute this software and its
00014  * documentation is hereby granted, provided that the above copyright
00015  * notice appears in all copies.  This software is provided without any
00016  * warranty, express or implied. The Australian National University
00017  * makes no representations about the suitability of this software for
00018  * any purpose.
00019  *
00020  * IN NO EVENT SHALL THE AUSTRALIAN NATIONAL UNIVERSITY BE LIABLE TO ANY
00021  * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
00022  * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
00023  * THE AUSTRALIAN NATIONAL UNIVERSITY HAVE BEEN ADVISED OF THE POSSIBILITY
00024  * OF SUCH DAMAGE.
00025  *
00026  * THE AUSTRALIAN NATIONAL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
00027  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
00028  * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
00029  * ON AN "AS IS" BASIS, AND THE AUSTRALIAN NATIONAL UNIVERSITY HAS NO
00030  * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS,
00031  * OR MODIFICATIONS.
00032  *
00033  * Id: ppp-comp.h,v 1.10 1996/09/26 06:30:11 paulus Exp
00034  */
00035
00036 #ifndef __NET_PPP_COMP_H
00037 #define __NET_PPP_COMP_H
00038
00039 /*
00040  * The following symbols control whether we include code for
00041  * various compression methods.
00042  */
00043 #ifndef DO_BSD_COMPRESS
00044 #define DO_BSD_COMPRESS 1       /* by default, include BSD-Compress */
00045 #endif
00046
00047 #ifndef DO_DEFLATE
00048 #define DO_DEFLATE      1       /* by default, include Deflate */
00049 #endif
00050
00051 #define DO_PREDICTOR_1  0
00052 #define DO_PREDICTOR_2  0
00053
00054 /*
00055  * Structure giving methods for compression/decompression.
00056  */
00057 #ifdef PACKETPTR
00058 struct compressor {
00059        int     compress_proto; /* CCP compression protocol number */
00060
00061        /* Allocate space for a compressor (transmit side) */
00062        void    *(*comp_alloc) (u_char *options, int opt_len);
00063
00064        /* Free space used by a compressor */
00065        void    (*comp_free) (void *state);
00066
00067        /* Initialize a compressor */
00068        int     (*comp_init) (void *state, u_char *options, int opt_len,
00069                              int unit, int hdrlen, int debug);
00070        /* Reset a compressor */
00071        void    (*comp_reset) (void *state);
00072
00073        /* Compress a packet */
00074        int     (*compress) (void *state, PACKETPTR *mret,
00075                             PACKETPTR mp, int orig_len, int max_len);
00076
00077        /* Return compression statistics */
00078        void    (*comp_stat) (void *state, struct compstat *stats);
00079
00080        /* Allocate space for a decompressor (receive side) */
00081        void    *(*decomp_alloc) (u_char *options, int opt_len);
00082
00083        /* Free space used by a decompressor */
00084        void    (*decomp_free) (void *state);
00085
00086        /* Initialize a decompressor */
00087        int     (*decomp_init) (void *state, u_char *options, int opt_len,
00088                                int unit, int hdrlen, int mru, int debug);
00089        /* Reset a decompressor */
00090        void    (*decomp_reset) (void *state);
00091
00092        /* Decompress a packet. */
00093        int     (*decompress) (void *state, PACKETPTR mp, PACKETPTR *dmpp);
00094
00095        /* Update state for an incompressible packet received */
00096        void    (*incomp) (void *state, PACKETPTR mp);
00097
00098        /* Return decompression statistics */
00099        void    (*decomp_stat) (void *state, struct compstat *stats);
00100 };
00101 #endif /* PACKETPTR */
00102
00103 /*
00104  * Return values for decompress routine.
00105  * We need to make these distinctions so that we can disable certain
00106  * useful functionality, namely sending a CCP reset-request as a result
00107  * of an error detected after decompression.  This is to avoid infringing
00108  * a patent held by Motorola.
00109  * Don't you just lurve software patents.
00110  */
00111 #define DECOMP_OK               0       /* everything went OK */
00112 #define DECOMP_ERROR            1       /* error detected before decomp. */
00113 #define DECOMP_FATALERROR       2       /* error detected after decomp. */
00114
00115 /*
00116  * CCP codes.
00117  */
00118 #define CCP_CONFREQ     1
00119 #define CCP_CONFACK     2
00120 #define CCP_TERMREQ     5
00121 #define CCP_TERMACK     6
00122 #define CCP_RESETREQ    14
00123 #define CCP_RESETACK    15
00124
00125 /*
00126  * Max # bytes for a CCP option
00127  */
00128 #define CCP_MAX_OPTION_LENGTH   32
00129
00130 /*
00131  * Parts of a CCP packet.
00132  */
00133 #define CCP_CODE(dp)            ((dp)[0])
00134 #define CCP_ID(dp)              ((dp)[1])
00135 #define CCP_LENGTH(dp)          (((dp)[2] << 8) + (dp)[3])
00136 #define CCP_HDRLEN              4
00137
00138 #define CCP_OPT_CODE(dp)        ((dp)[0])
00139 #define CCP_OPT_LENGTH(dp)      ((dp)[1])
00140 #define CCP_OPT_MINLEN          2
00141
00142 /*
00143  * Definitions for BSD-Compress.
00144  */
00145 #define CI_BSD_COMPRESS         21      /* config. option for BSD-Compress */
00146 #define CILEN_BSD_COMPRESS      3       /* length of config. option */
00147
00148 /* Macros for handling the 3rd byte of the BSD-Compress config option. */
00149 #define BSD_NBITS(x)            ((x) & 0x1F)    /* number of bits requested */
00150 #define BSD_VERSION(x)          ((x) >> 5)      /* version of option format */
00151 #define BSD_CURRENT_VERSION     1               /* current version number */
00152 #define BSD_MAKE_OPT(v, n)      (((v) << 5) | (n))
00153
00154 #define BSD_MIN_BITS            9       /* smallest code size supported */
00155 #define BSD_MAX_BITS            15      /* largest code size supported */
00156
00157 /*
00158  * Definitions for Deflate.
00159  */
00160 #define CI_DEFLATE              24      /* config option for Deflate */
00161 #define CILEN_DEFLATE           4       /* length of its config option */
00162
00163 #define DEFLATE_MIN_SIZE        8
00164 #define DEFLATE_MAX_SIZE        15
00165 #define DEFLATE_METHOD_VAL      8
00166 #define DEFLATE_SIZE(x)         (((x) >> 4) + DEFLATE_MIN_SIZE)
00167 #define DEFLATE_METHOD(x)       ((x) & 0x0F)
00168 #define DEFLATE_MAKE_OPT(w)     ((((w) - DEFLATE_MIN_SIZE) << 4) \
00169                                  + DEFLATE_METHOD_VAL)
00170 #define DEFLATE_CHK_SEQUENCE    0
00171
00172 /*
00173  * Definitions for other, as yet unsupported, compression methods.
00174  */
00175 #define CI_PREDICTOR_1          1       /* config option for Predictor-1 */
00176 #define CILEN_PREDICTOR_1       2       /* length of its config option */
00177 #define CI_PREDICTOR_2          2       /* config option for Predictor-2 */
00178 #define CILEN_PREDICTOR_2       2       /* length of its config option */
00179
00180 #endif
Generated on Wed Jan 25 15:42:32 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/net/PPP_DEFS.H Source File

inc/net/PPP_DEFS.H

Go to the documentation of this file.
00001
00005 /*      $Id: ppp_defs.h,v 1.11 1997/04/30 05:46:24 paulus Exp $ */
00006
00007 /*
00008  * ppp_defs.h - PPP definitions.
00009  *
00010  * Copyright (c) 1994 The Australian National University.
00011  * All rights reserved.
00012  *
00013  * Permission to use, copy, modify, and distribute this software and its
00014  * documentation is hereby granted, provided that the above copyright
00015  * notice appears in all copies.  This software is provided without any
00016  * warranty, express or implied. The Australian National University
00017  * makes no representations about the suitability of this software for
00018  * any purpose.
00019  *
00020  * IN NO EVENT SHALL THE AUSTRALIAN NATIONAL UNIVERSITY BE LIABLE TO ANY
00021  * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
00022  * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
00023  * THE AUSTRALIAN NATIONAL UNIVERSITY HAVE BEEN ADVISED OF THE POSSIBILITY
00024  * OF SUCH DAMAGE.
00025  *
00026  * THE AUSTRALIAN NATIONAL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
00027  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
00028  * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
00029  * ON AN "AS IS" BASIS, AND THE AUSTRALIAN NATIONAL UNIVERSITY HAS NO
00030  * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS,
00031  * OR MODIFICATIONS.
00032  */
00033
00034 #ifndef __NET_PPP_DEFS_H
00035 #define __NET_PPP_DEFS_H
00036
00037 /*
00038  * The basic PPP frame.
00039  */
00040 #define PPP_HDRLEN      4       /* octets for standard ppp header */
00041 #define PPP_FCSLEN      2       /* octets for FCS */
00042
00043 /*
00044  * Packet sizes
00045  *
00046  * Note - lcp shouldn't be allowed to negotiate stuff outside these
00047  *        limits.  See lcp.h in the pppd directory.
00048  * (XXX - these constants should simply be shared by lcp.c instead
00049  *        of living in lcp.h)
00050  */
00051 #define PPP_MTU         1500    /* Default MTU (size of Info field) */
00052 #define PPP_MAXMTU      65535 - (PPP_HDRLEN + PPP_FCSLEN)
00053 #define PPP_MINMTU      64
00054 #define PPP_MRU         1500    /* default MRU = max length of info field */
00055 #define PPP_MAXMRU      65000   /* Largest MRU we allow */
00056 #define PPP_MINMRU      128
00057
00058 #define PPP_ADDRESS(p)  (((u_char *)(p))[0])
00059 #define PPP_CONTROL(p)  (((u_char *)(p))[1])
00060 #define PPP_PROTOCOL(p) ((((u_char *)(p))[2] << 8) + ((u_char *)(p))[3])
00061
00062 /*
00063  * Significant octet values.
00064  */
00065 #define PPP_ALLSTATIONS 0xff    /* All-Stations broadcast address */
00066 #define PPP_UI          0x03    /* Unnumbered Information */
00067 #define PPP_FLAG        0x7e    /* Flag Sequence */
00068 #define PPP_ESCAPE      0x7d    /* Asynchronous Control Escape */
00069 #define PPP_TRANS       0x20    /* Asynchronous transparency modifier */
00070
00071 /*
00072  * Protocol field values.
00073  */
00074 #define PPP_IP          0x0021  /* Raw IP */
00075 #define PPP_OSI         0x0023  /* OSI Network Layer */
00076 #define PPP_NS          0x0025  /* Xerox NS IDP */
00077 #define PPP_DECNET      0x0027  /* DECnet Phase IV */
00078 #define PPP_APPLE       0x0029  /* Appletalk */
00079 #define PPP_IPX         0x002b  /* Novell IPX */
00080 #define PPP_VJC         0x002d  /* Van Jacobson Compressed TCP/IP */
00081 #define PPP_VJNC        0x002f  /* Van Jacobson Uncompressed TCP/IP */
00082 #define PPP_VJC_COMP    PPP_VJC
00083 #define PPP_VJC_UNCOMP  PPP_VJNC
00084 #define PPP_BRPDU       0x0031  /* Bridging PDU */
00085 #define PPP_STII        0x0033  /* Stream Protocol (ST-II) */
00086 #define PPP_VINES       0x0035  /* Banyan Vines */
00087 #define PPP_IPV6        0x0057  /* Internet Protocol Version 6 */
00088 #define PPP_COMP        0x00fd  /* compressed packet */
00089
00090 #define PPP_HELLO       0x0201  /* 802.1d Hello Packets */
00091 #define PPP_LUXCOM      0x0231  /* Luxcom */
00092 #define PPP_SNS         0x0233  /* Sigma Network Systems */
00093
00094 #define PPP_IPCP        0x8021  /* IP Control Protocol */
00095 #define PPP_OSICP       0x8023  /* OSI Network Layer Control Protocol */
00096 #define PPP_NSCP        0x8025  /* Xerox NS IDP Control Protocol */
00097 #define PPP_DECNETCP    0x8027  /* DECnet Control Protocol */
00098 #define PPP_ATCP        0x8029  /* AppleTalk Control Protocol */
00099 #define PPP_IPXCP       0x802b  /* IPX Control Protocol */
00100 #define PPP_STIICP      0x8033  /* Strean Protocol Control Protocol */
00101 #define PPP_VINESCP     0x8035  /* Banyan Vines Control Protocol */
00102 #define PPP_CCP         0x80fd  /* Compression Control Protocol */
00103
00104 #define PPP_LCP         0xc021  /* Link Control Protocol */
00105 #define PPP_PAP         0xc023  /* Password Authentication Protocol */
00106 #define PPP_LQR         0xc025  /* Link Quality Report protocol */
00107 #define PPP_CHAP        0xc223  /* Cryptographic Handshake Auth. Protocol */
00108 #define PPP_CBCP        0xc029  /* Callback Control Protocol */
00109
00110 /*
00111  * Values for FCS calculations.
00112  */
00113 #define PPP_INITFCS     0xffff  /* Initial FCS value */
00114 #define PPP_GOODFCS     0xf0b8  /* Good final FCS value */
00115 #define PPP_FCS(fcs, c) (((fcs) >> 8) ^ fcstab[((fcs) ^ (c)) & 0xff])
00116
00117 /*
00118  * A 32-bit unsigned integral type.
00119  */
00120 #if !defined(__BIT_TYPES_DEFINED__) && !defined(_BITYPES) && !defined(__SYS_WTYPES_H)
00121   #ifdef UINT32_T
00122     typedef UINT32_T       u_int32_t;
00123   #else
00124     typedef unsigned long  u_int32_t;
00125   #endif
00126 #endif
00127
00128 /*
00129  * Extended asyncmap - allows any character to be escaped.
00130  */
00131 typedef u_int32_t  ext_accm[8];
00132
00133 /*
00134  * What to do with network protocol (NP) packets.
00135  */
00136 enum NPmode {
00137     NPMODE_PASS,                /* pass the packet through */
00138     NPMODE_DROP,                /* silently drop the packet */
00139     NPMODE_ERROR,               /* return an error */
00140     NPMODE_QUEUE                /* save it up for later. */
00141 };
00142
00143 /*
00144  * Statistics.
00145  */
00146 struct pppstat  {
00147     unsigned int ppp_ibytes;    /* bytes received */
00148     unsigned int ppp_ipackets;  /* packets received */
00149     unsigned int ppp_ierrors;   /* receive errors */
00150     unsigned int ppp_obytes;    /* bytes sent */
00151     unsigned int ppp_opackets;  /* packets sent */
00152     unsigned int ppp_oerrors;   /* transmit errors */
00153 };
00154
00155 struct vjstat {
00156     unsigned int vjs_packets;   /* outbound packets */
00157     unsigned int vjs_compressed; /* outbound compressed packets */
00158     unsigned int vjs_searches;  /* searches for connection state */
00159     unsigned int vjs_misses;    /* times couldn't find conn. state */
00160     unsigned int vjs_uncompressedin; /* inbound uncompressed packets */
00161     unsigned int vjs_compressedin; /* inbound compressed packets */
00162     unsigned int vjs_errorin;   /* inbound unknown type packets */
00163     unsigned int vjs_tossed;    /* inbound packets tossed because of error */
00164 };
00165
00166 struct ppp_stats {
00167     struct pppstat p;           /* basic PPP statistics */
00168     struct vjstat vj;           /* VJ header compression statistics */
00169 };
00170
00171 struct compstat {
00172     unsigned int unc_bytes;     /* total uncompressed bytes */
00173     unsigned int unc_packets;   /* total uncompressed packets */
00174     unsigned int comp_bytes;    /* compressed bytes */
00175     unsigned int comp_packets;  /* compressed packets */
00176     unsigned int inc_bytes;     /* incompressible bytes */
00177     unsigned int inc_packets;   /* incompressible packets */
00178     unsigned int ratio;         /* recent compression ratio << 8 */
00179 };
00180
00181 struct ppp_comp_stats {
00182     struct compstat c;          /* packet compression statistics */
00183     struct compstat d;          /* packet decompression statistics */
00184 };
00185
00186 /*
00187  * The following structure records the time in seconds since
00188  * the last NP packet was sent or received.
00189  */
00190 struct ppp_idle {
00191     time_t xmit_idle;           /* time since last NP packet sent */
00192     time_t recv_idle;           /* time since last NP packet received */
00193 };
00194
00195 #endif
Generated on Wed Jan 25 15:42:32 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/net/RADIX.H Source File

inc/net/RADIX.H

Go to the documentation of this file.
00001
00005 /*      $NetBSD: radix.h,v 1.9 1997/04/02 21:17:31 christos Exp $       */
00006
00007 /*
00008  * Copyright (c) 1988, 1989, 1993
00009  *      The Regents of the University of California.  All rights reserved.
00010  *
00011  * Redistribution and use in source and binary forms, with or without
00012  * modification, are permitted provided that the following conditions
00013  * are met:
00014  * 1. Redistributions of source code must retain the above copyright
00015  *    notice, this list of conditions and the following disclaimer.
00016  * 2. Redistributions in binary form must reproduce the above copyright
00017  *    notice, this list of conditions and the following disclaimer in the
00018  *    documentation and/or other materials provided with the distribution.
00019  * 3. All advertising materials mentioning features or use of this software
00020  *    must display the following acknowledgement:
00021  *      This product includes software developed by the University of
00022  *      California, Berkeley and its contributors.
00023  * 4. Neither the name of the University nor the names of its contributors
00024  *    may be used to endorse or promote products derived from this software
00025  *    without specific prior written permission.
00026  *
00027  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
00028  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00029  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00030  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
00031  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00032  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00033  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00034  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00035  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00036  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00037  * SUCH DAMAGE.
00038  *
00039  *      @(#)radix.h     8.2 (Berkeley) 10/31/94
00040  */
00041
00042 #ifndef _NET_RADIX_H_
00043 #define _NET_RADIX_H_
00044
00045 /*
00046  * Radix search tree node layout.
00047  */
00048
00049 struct radix_node {
00050         struct  radix_mask *rn_mklist;  /* list of masks contained in subtree */
00051         struct  radix_node *rn_p;       /* parent */
00052         short   rn_b;                   /* bit offset; -1-index(netmask) */
00053         char    rn_bmask;               /* node: mask for bit test*/
00054         u_char  rn_flags;               /* enumerated next */
00055 #define RNF_NORMAL      1               /* leaf contains normal route */
00056 #define RNF_ROOT        2               /* leaf is root leaf for tree */
00057 #define RNF_ACTIVE      4               /* This node is alive (for rtfree) */
00058         union {
00059                 struct {                        /* leaf only data: */
00060                         caddr_t rn_Key;         /* object of search */
00061                         caddr_t rn_Mask;        /* netmask, if present */
00062                         struct  radix_node *rn_Dupedkey;
00063                 } rn_leaf;
00064                 struct {                        /* node only data: */
00065                         int     rn_Off;         /* where to start compare */
00066                         struct  radix_node *rn_L;/* progeny */
00067                         struct  radix_node *rn_R;/* progeny */
00068                 } rn_node;
00069         } rn_u;
00070 #ifdef RN_DEBUG
00071         int rn_info;
00072         struct radix_node *rn_twin;
00073         struct radix_node *rn_ybro;
00074 #endif
00075 };
00076
00077 #define rn_dupedkey rn_u.rn_leaf.rn_Dupedkey
00078 #define rn_key rn_u.rn_leaf.rn_Key
00079 #define rn_mask rn_u.rn_leaf.rn_Mask
00080 #define rn_off rn_u.rn_node.rn_Off
00081 #define rn_l rn_u.rn_node.rn_L
00082 #define rn_r rn_u.rn_node.rn_R
00083
00084 /*
00085  * Annotations to tree concerning potential routes applying to subtrees.
00086  */
00087
00088 extern struct radix_mask {
00089         short   rm_b;                   /* bit offset; -1-index(netmask) */
00090         char    rm_unused;              /* cf. rn_bmask */
00091         u_char  rm_flags;               /* cf. rn_flags */
00092         struct  radix_mask *rm_mklist;  /* more masks to try */
00093         union   {
00094                 caddr_t rmu_mask;               /* the mask */
00095                 struct  radix_node *rmu_leaf;   /* for normal routes */
00096         }       rm_rmu;
00097         int     rm_refs;                /* # of references to this struct */
00098 } *rn_mkfreelist;
00099
00100 #define rm_mask rm_rmu.rmu_mask
00101 #define rm_leaf rm_rmu.rmu_leaf         /* extra field would make 32 bytes */
00102
00103 #define MKGet(m) {\
00104         if (rn_mkfreelist) {\
00105                 m = rn_mkfreelist; \
00106                 rn_mkfreelist = (m)->rm_mklist; \
00107         } else \
00108                 R_Malloc(m, struct radix_mask *, sizeof (*(m))); }\
00109
00110 #define MKFree(m) { (m)->rm_mklist = rn_mkfreelist; rn_mkfreelist = (m);}
00111
00112 struct radix_node_head {
00113         struct  radix_node *rnh_treetop;
00114         int     rnh_addrsize;           /* permit, but not require fixed keys */
00115         int     rnh_pktsize;            /* permit, but not require fixed keys */
00116         struct  radix_node *(*rnh_addaddr)      /* add based on sockaddr */
00117                 __P((void *v, void *mask,
00118                      struct radix_node_head *head, struct radix_node nodes[]));
00119         struct  radix_node *(*rnh_addpkt)       /* add based on packet hdr */
00120                 __P((void *v, void *mask,
00121                      struct radix_node_head *head, struct radix_node nodes[]));
00122         struct  radix_node *(*rnh_deladdr)      /* remove based on sockaddr */
00123                 __P((void *v, void *mask, struct radix_node_head *head));
00124         struct  radix_node *(*rnh_delpkt)       /* remove based on packet hdr */
00125                 __P((void *v, void *mask, struct radix_node_head *head));
00126         struct  radix_node *(*rnh_matchaddr)    /* locate based on sockaddr */
00127                 __P((void *v, struct radix_node_head *head));
00128         struct  radix_node *(*rnh_lookup)       /* locate based on sockaddr */
00129                 __P((void *v, void *mask, struct radix_node_head *head));
00130         struct  radix_node *(*rnh_matchpkt)     /* locate based on packet hdr */
00131                 __P((void *v, struct radix_node_head *head));
00132         int     (*rnh_walktree)                 /* traverse tree */
00133                 __P((struct radix_node_head *,
00134                      int (*)(struct radix_node *, void *), void *));
00135         struct  radix_node rnh_nodes[3];        /* empty tree for common case */
00136 };
00137
00138
00139 #define Bcmp(a,b,n)     memcmp (a,b,n)
00140 #define Bcopy(a,b,n)    memcpy (b,a,n)
00141 #define Bzero(p,n)      memset ((void*)(p),0,(int)(n));
00142 #define R_Malloc(p,t,n) (p = (t) malloc((unsigned int)(n)))
00143 #define Free(p)         free ((void*)p);
00144
00145 __BEGIN_DECLS
00146
00147 void rn_init     (void);
00148 int  rn_inithead (void **, int);
00149 int  rn_refines  (void *, void *);
00150 int  rn_walktree (struct radix_node_head *,
00151                   int (*)(struct radix_node *, void *),
00152                   void *);
00153
00154 struct radix_node *rn_addroute (void *, void *, struct radix_node_head *, struct radix_node [2]);
00155 struct radix_node *rn_insert (void *, struct radix_node_head *, int *, struct radix_node [2]);
00156 struct radix_node *rn_newpair (void *, int, struct radix_node[2]);
00157
00158 struct radix_node *rn_addmask (void *, int, int);
00159 struct radix_node *rn_delete (void *, void *, struct radix_node_head *);
00160 struct radix_node *rn_lookup (void *, void *, struct radix_node_head *);
00161 struct radix_node *rn_match (void *, struct radix_node_head *);
00162 struct radix_node *rn_search (void *, struct radix_node *);
00163 struct radix_node *rn_search_m (void *, struct radix_node *, void *);
00164
00165 __END_DECLS
00166
00167 #endif /* _NET_RADIX_H_ */
Generated on Wed Jan 25 15:42:33 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/net/RAW_CB.H Source File

inc/net/RAW_CB.H

Go to the documentation of this file.
00001
00005 /*      $NetBSD: raw_cb.h,v 1.11 1996/05/28 23:24:50 pk Exp $   */
00006
00007 /*
00008  * Copyright (c) 1980, 1986, 1993
00009  *      The Regents of the University of California.  All rights reserved.
00010  *
00011  * Redistribution and use in source and binary forms, with or without
00012  * modification, are permitted provided that the following conditions
00013  * are met:
00014  * 1. Redistributions of source code must retain the above copyright
00015  *    notice, this list of conditions and the following disclaimer.
00016  * 2. Redistributions in binary form must reproduce the above copyright
00017  *    notice, this list of conditions and the following disclaimer in the
00018  *    documentation and/or other materials provided with the distribution.
00019  * 3. All advertising materials mentioning features or use of this software
00020  *    must display the following acknowledgement:
00021  *      This product includes software developed by the University of
00022  *      California, Berkeley and its contributors.
00023  * 4. Neither the name of the University nor the names of its contributors
00024  *    may be used to endorse or promote products derived from this software
00025  *    without specific prior written permission.
00026  *
00027  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
00028  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00029  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00030  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
00031  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00032  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00033  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00034  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00035  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00036  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00037  * SUCH DAMAGE.
00038  *
00039  *      @(#)raw_cb.h    8.1 (Berkeley) 6/10/93
00040  */
00041
00042 #ifndef __NET_RAW_CB_H
00043 #define __NET_RAW_CB_H
00044
00045 /*
00046  * Raw protocol interface control block.  Used
00047  * to tie a socket to the generic raw interface.
00048  */
00049 struct rawcb {
00050         LIST_ENTRY(rawcb) rcb_list;     /* doubly linked list */
00051         struct  socket *rcb_socket;     /* back pointer to socket */
00052         struct  sockaddr *rcb_faddr;    /* destination address */
00053         struct  sockaddr *rcb_laddr;    /* socket's address */
00054         struct  sockproto rcb_proto;    /* protocol family, protocol */
00055 };
00056
00057 #define sotorawcb(so)   ((struct rawcb *)(so)->so_pcb)
00058
00059 /*
00060  * Nominal space allocated to a raw socket.
00061  */
00062 #define RAWSNDQ         8192
00063 #define RAWRCVQ         8192
00064
00065 #endif
Generated on Wed Jan 25 15:42:33 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/net/ROUTE.H Source File

inc/net/ROUTE.H

Go to the documentation of this file.
00001
00005 /*      $NetBSD: route.h,v 1.11 1997/04/02 21:17:29 christos Exp $      */
00006
00007 /*
00008  * Copyright (c) 1980, 1986, 1993
00009  *      The Regents of the University of California.  All rights reserved.
00010  *
00011  * Redistribution and use in source and binary forms, with or without
00012  * modification, are permitted provided that the following conditions
00013  * are met:
00014  * 1. Redistributions of source code must retain the above copyright
00015  *    notice, this list of conditions and the following disclaimer.
00016  * 2. Redistributions in binary form must reproduce the above copyright
00017  *    notice, this list of conditions and the following disclaimer in the
00018  *    documentation and/or other materials provided with the distribution.
00019  * 3. All advertising materials mentioning features or use of this software
00020  *    must display the following acknowledgement:
00021  *      This product includes software developed by the University of
00022  *      California, Berkeley and its contributors.
00023  * 4. Neither the name of the University nor the names of its contributors
00024  *    may be used to endorse or promote products derived from this software
00025  *    without specific prior written permission.
00026  *
00027  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
00028  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00029  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00030  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
00031  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00032  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00033  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00034  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00035  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00036  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00037  * SUCH DAMAGE.
00038  *
00039  *      @(#)route.h     8.5 (Berkeley) 2/8/95
00040  */
00041
00042 #ifndef __NET_ROUTE_H
00043 #define __NET_ROUTE_H
00044 /*
00045  * Kernel resident routing tables.
00046  *
00047  * The routing tables are initialized when interface addresses
00048  * are set by making entries for all directly connected interfaces.
00049  */
00050
00051 /*
00052  * A route consists of a destination address and a reference
00053  * to a routing entry.  These are often held by protocols
00054  * in their control blocks, e.g. inpcb.
00055  */
00056 struct route {
00057         struct  rtentry *ro_rt;
00058         struct  sockaddr ro_dst;
00059 };
00060
00061 /*
00062  * These numbers are used by reliable protocols for determining
00063  * retransmission behavior and are included in the routing structure.
00064  */
00065 struct rt_metrics {
00066         u_long  rmx_locks;      /* Kernel must leave these values alone */
00067         u_long  rmx_mtu;        /* MTU for this path */
00068         u_long  rmx_hopcount;   /* max hops expected */
00069         u_long  rmx_expire;     /* lifetime for route, e.g. redirect */
00070         u_long  rmx_recvpipe;   /* inbound delay-bandwith product */
00071         u_long  rmx_sendpipe;   /* outbound delay-bandwith product */
00072         u_long  rmx_ssthresh;   /* outbound gateway buffer limit */
00073         u_long  rmx_rtt;        /* estimated round trip time */
00074         u_long  rmx_rttvar;     /* estimated rtt variance */
00075         u_long  rmx_pksent;     /* packets sent using this route */
00076 };
00077
00078 /*
00079  * rmx_rtt and rmx_rttvar are stored as microseconds;
00080  * RTTTOPRHZ(rtt) converts to a value suitable for use
00081  * by a protocol slowtimo counter.
00082  */
00083 #define RTM_RTTUNIT     1000000 /* units for rtt, rttvar, as units per sec */
00084 #define RTTTOPRHZ(r)    ((r) / (RTM_RTTUNIT / PR_SLOWHZ))
00085
00086 /*
00087  * We distinguish between routes to hosts and routes to networks,
00088  * preferring the former if available.  For each route we infer
00089  * the interface to use from the gateway address supplied when
00090  * the route was entered.  Routes that forward packets through
00091  * gateways are marked so that the output routines know to address the
00092  * gateway rather than the ultimate destination.
00093  */
00094 #ifndef RNF_NORMAL
00095 #include <net/radix.h>
00096 #endif
00097
00098 struct rtentry {
00099         struct  radix_node rt_nodes[2]; /* tree glue, and other values */
00100 #define rt_key(r)       ((struct sockaddr *)((r)->rt_nodes->rn_key))
00101 #define rt_mask(r)      ((struct sockaddr *)((r)->rt_nodes->rn_mask))
00102         struct  sockaddr *rt_gateway;   /* value */
00103         short   rt_flags;               /* up/down?, host/net */
00104         short   rt_refcnt;              /* # held references */
00105         u_long  rt_use;                 /* raw # packets forwarded */
00106         struct  ifnet *rt_ifp;          /* the answer: interface to use */
00107         struct  ifaddr *rt_ifa;         /* the answer: interface to use */
00108         struct  sockaddr *rt_genmask;   /* for generation of cloned routes */
00109         caddr_t rt_llinfo;              /* pointer to link level info cache */
00110         struct  rt_metrics rt_rmx;      /* metrics used by rx'ing protocols */
00111         struct  rtentry *rt_gwroute;    /* implied entry for gatewayed routes */
00112 };
00113
00114 /*
00115  * Following structure necessary for 4.3 compatibility;
00116  * We should eventually move it to a compat file.
00117  */
00118 struct ortentry {
00119         u_int32_t rt_hash;              /* to speed lookups */
00120         struct  sockaddr rt_dst;        /* key */
00121         struct  sockaddr rt_gateway;    /* value */
00122         int16_t rt_flags;               /* up/down?, host/net */
00123         int16_t rt_refcnt;              /* # held references */
00124         u_int32_t rt_use;               /* raw # packets forwarded */
00125         struct  ifnet *rt_ifp;          /* the answer: interface to use */
00126 };
00127
00128 #define RTF_UP          0x1             /* route usable */
00129 #define RTF_GATEWAY     0x2             /* destination is a gateway */
00130 #define RTF_HOST        0x4             /* host entry (net otherwise) */
00131 #define RTF_REJECT      0x8             /* host or net unreachable */
00132 #define RTF_DYNAMIC     0x10            /* created dynamically (by redirect) */
00133 #define RTF_MODIFIED    0x20            /* modified dynamically (by redirect) */
00134 #define RTF_DONE        0x40            /* message confirmed */
00135 #define RTF_MASK        0x80            /* subnet mask present */
00136 #define RTF_CLONING     0x100           /* generate new routes on use */
00137 #define RTF_XRESOLVE    0x200           /* external daemon resolves name */
00138 #define RTF_LLINFO      0x400           /* generated by ARP or ESIS */
00139 #define RTF_STATIC      0x800           /* manually added */
00140 #define RTF_BLACKHOLE   0x1000          /* just discard pkts (during updates) */
00141 #define RTF_PROTO2      0x4000          /* protocol specific routing flag */
00142 #define RTF_PROTO1      0x8000          /* protocol specific routing flag */
00143
00144
00145 /*
00146  * Routing statistics.
00147  */
00148 struct  rtstat {
00149         short   rts_badredirect;        /* bogus redirect calls */
00150         short   rts_dynamic;            /* routes created by redirects */
00151         short   rts_newgateway;         /* routes modified by redirects */
00152         short   rts_unreach;            /* lookups which failed */
00153         short   rts_wildcard;           /* lookups satisfied by a wildcard */
00154 };
00155 /*
00156  * Structures for routing messages.
00157  */
00158 struct rt_msghdr {
00159         u_short rtm_msglen;     /* to skip over non-understood messages */
00160         u_char  rtm_version;    /* future binary compatibility */
00161         u_char  rtm_type;       /* message type */
00162         u_short rtm_index;      /* index for associated ifp */
00163         int     rtm_flags;      /* flags, incl. kern & message, e.g. DONE */
00164         int     rtm_addrs;      /* bitmask identifying sockaddrs in msg */
00165         int     rtm_pid;        /* identify sender */
00166         int     rtm_seq;        /* for sender to identify action */
00167         int     rtm_errno;      /* why failed */
00168         int     rtm_use;        /* from rtentry */
00169         u_long  rtm_inits;      /* which metrics we are initializing */
00170         struct  rt_metrics rtm_rmx; /* metrics themselves */
00171 };
00172
00173 #define RTM_VERSION     3       /* Up the ante and ignore older versions */
00174
00175 #define RTM_ADD         0x1     /* Add Route */
00176 #define RTM_DELETE      0x2     /* Delete Route */
00177 #define RTM_CHANGE      0x3     /* Change Metrics or flags */
00178 #define RTM_GET         0x4     /* Report Metrics */
00179 #define RTM_LOSING      0x5     /* Kernel Suspects Partitioning */
00180 #define RTM_REDIRECT    0x6     /* Told to use different route */
00181 #define RTM_MISS        0x7     /* Lookup failed on this address */
00182 #define RTM_LOCK        0x8     /* fix specified metrics */
00183 #define RTM_OLDADD      0x9     /* caused by SIOCADDRT */
00184 #define RTM_OLDDEL      0xa     /* caused by SIOCDELRT */
00185 #define RTM_RESOLVE     0xb     /* req to resolve dst to LL addr */
00186 #define RTM_NEWADDR     0xc     /* address being added to iface */
00187 #define RTM_DELADDR     0xd     /* address being removed from iface */
00188 #define RTM_IFINFO      0xe     /* iface going up/down etc. */
00189
00190 #define RTV_MTU         0x1     /* init or lock _mtu */
00191 #define RTV_HOPCOUNT    0x2     /* init or lock _hopcount */
00192 #define RTV_EXPIRE      0x4     /* init or lock _hopcount */
00193 #define RTV_RPIPE       0x8     /* init or lock _recvpipe */
00194 #define RTV_SPIPE       0x10    /* init or lock _sendpipe */
00195 #define RTV_SSTHRESH    0x20    /* init or lock _ssthresh */
00196 #define RTV_RTT         0x40    /* init or lock _rtt */
00197 #define RTV_RTTVAR      0x80    /* init or lock _rttvar */
00198
00199 /*
00200  * Bitmask values for rtm_addr.
00201  */
00202 #define RTA_DST         0x1     /* destination sockaddr present */
00203 #define RTA_GATEWAY     0x2     /* gateway sockaddr present */
00204 #define RTA_NETMASK     0x4     /* netmask sockaddr present */
00205 #define RTA_GENMASK     0x8     /* cloning mask sockaddr present */
00206 #define RTA_IFP         0x10    /* interface name sockaddr present */
00207 #define RTA_IFA         0x20    /* interface addr sockaddr present */
00208 #define RTA_AUTHOR      0x40    /* sockaddr for author of redirect */
00209 #define RTA_BRD         0x80    /* for NEWADDR, broadcast or p-p dest addr */
00210
00211 /*
00212  * Index offsets for sockaddr array for alternate internal encoding.
00213  */
00214 #define RTAX_DST        0       /* destination sockaddr present */
00215 #define RTAX_GATEWAY    1       /* gateway sockaddr present */
00216 #define RTAX_NETMASK    2       /* netmask sockaddr present */
00217 #define RTAX_GENMASK    3       /* cloning mask sockaddr present */
00218 #define RTAX_IFP        4       /* interface name sockaddr present */
00219 #define RTAX_IFA        5       /* interface addr sockaddr present */
00220 #define RTAX_AUTHOR     6       /* sockaddr for author of redirect */
00221 #define RTAX_BRD        7       /* for NEWADDR, broadcast or p-p dest addr */
00222 #define RTAX_MAX        8       /* size of array to allocate */
00223
00224 struct rt_addrinfo {
00225         int     rti_addrs;
00226         struct  sockaddr *rti_info[RTAX_MAX];
00227 };
00228
00229 struct route_cb {
00230         int     ip_count;
00231         int     ns_count;
00232         int     iso_count;
00233         int     any_count;
00234 };
00235
00236 #endif
Generated on Wed Jan 25 15:42:33 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/net/SLCOMPRE.H Source File

inc/net/SLCOMPRE.H

Go to the documentation of this file.
00001
00005 /*      $NetBSD: slcompress.h,v 1.11 1997/05/17 21:12:11 christos Exp $ */
00006 /*      Id: slcompress.h,v 1.4 1994/09/21 06:50:08 paulus Exp   */
00007
00008 /*
00009  * Copyright (c) 1989, 1993
00010  *      The Regents of the University of California.  All rights reserved.
00011  *
00012  * Redistribution and use in source and binary forms, with or without
00013  * modification, are permitted provided that the following conditions
00014  * are met:
00015  * 1. Redistributions of source code must retain the above copyright
00016  *    notice, this list of conditions and the following disclaimer.
00017  * 2. Redistributions in binary form must reproduce the above copyright
00018  *    notice, this list of conditions and the following disclaimer in the
00019  *    documentation and/or other materials provided with the distribution.
00020  * 3. All advertising materials mentioning features or use of this software
00021  *    must display the following acknowledgement:
00022  *      This product includes software developed by the University of
00023  *      California, Berkeley and its contributors.
00024  * 4. Neither the name of the University nor the names of its contributors
00025  *    may be used to endorse or promote products derived from this software
00026  *    without specific prior written permission.
00027  *
00028  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
00029  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00030  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00031  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
00032  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00033  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00034  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00035  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00036  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00037  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00038  * SUCH DAMAGE.
00039  *
00040  *      @(#)slcompress.h        8.1 (Berkeley) 6/10/93
00041  */
00042
00043 /*
00044  * Definitions for tcp compression routines.
00045  *
00046  * Van Jacobson (van@helios.ee.lbl.gov), Dec 31, 1989:
00047  *      - Initial distribution.
00048  */
00049
00050 #ifndef __NET_SLCOMPRESS_H
00051 #define __NET_SLCOMPRESS_H
00052
00053 #ifndef MLEN
00054 #define MLEN 128
00055 #endif
00056
00057 #define MAX_STATES 16           /* must be > 2 and < 256 */
00058 #define MAX_HDR    MLEN         /* XXX 4bsd-ism: should really be 128 */
00059
00060 /*
00061  * Compressed packet format:
00062  *
00063  * The first octet contains the packet type (top 3 bits), TCP
00064  * 'push' bit, and flags that indicate which of the 4 TCP sequence
00065  * numbers have changed (bottom 5 bits).  The next octet is a
00066  * conversation number that associates a saved IP/TCP header with
00067  * the compressed packet.  The next two octets are the TCP checksum
00068  * from the original datagram.  The next 0 to 15 octets are
00069  * sequence number changes, one change per bit set in the header
00070  * (there may be no changes and there are two special cases where
00071  * the receiver implicitly knows what changed -- see below).
00072  *
00073  * There are 5 numbers which can change (they are always inserted
00074  * in the following order): TCP urgent pointer, window,
00075  * acknowlegement, sequence number and IP ID.  (The urgent pointer
00076  * is different from the others in that its value is sent, not the
00077  * change in value.)  Since typical use of SLIP links is biased
00078  * toward small packets (see comments on MTU/MSS below), changes
00079  * use a variable length coding with one octet for numbers in the
00080  * range 1 - 255 and 3 octets (0, MSB, LSB) for numbers in the
00081  * range 256 - 65535 or 0.  (If the change in sequence number or
00082  * ack is more than 65535, an uncompressed packet is sent.)
00083  */
00084
00085 /*
00086  * Packet types (must not conflict with IP protocol version)
00087  *
00088  * The top nibble of the first octet is the packet type.  There are
00089  * three possible types: IP (not proto TCP or tcp with one of the
00090  * control flags set); uncompressed TCP (a normal IP/TCP packet but
00091  * with the 8-bit protocol field replaced by an 8-bit connection id --
00092  * this type of packet syncs the sender & receiver); and compressed
00093  * TCP (described above).
00094  *
00095  * LSB of 4-bit field is TCP "PUSH" bit (a worthless anachronism) and
00096  * is logically part of the 4-bit "changes" field that follows.  Top
00097  * three bits are actual packet type.  For backward compatibility
00098  * and in the interest of conserving bits, numbers are chosen so the
00099  * IP protocol version number (4) which normally appears in this nibble
00100  * means "IP packet".
00101  */
00102
00103 /* packet types */
00104 #define TYPE_IP               0x40
00105 #define TYPE_UNCOMPRESSED_TCP 0x70
00106 #define TYPE_COMPRESSED_TCP   0x80
00107 #define TYPE_ERROR            0x00
00108
00109 /* Bits in first octet of compressed packet */
00110 #define NEW_C   0x40    /* flag bits for what changed in a packet */
00111 #define NEW_I   0x20
00112 #define NEW_S   0x08
00113 #define NEW_A   0x04
00114 #define NEW_W   0x02
00115 #define NEW_U   0x01
00116
00117 /* reserved, special-case values of above */
00118 #define SPECIAL_I     (NEW_S|NEW_W|NEW_U)       /* echoed interactive traffic */
00119 #define SPECIAL_D     (NEW_S|NEW_A|NEW_W|NEW_U) /* unidirectional data */
00120 #define SPECIALS_MASK (NEW_S|NEW_A|NEW_W|NEW_U)
00121
00122 #define TCP_PUSH_BIT 0x10
00123
00124
00125 /*
00126  * "state" data for each active tcp conversation on the wire.  This is
00127  * basically a copy of the entire IP/TCP header from the last packet
00128  * we saw from the conversation together with a small identifier
00129  * the transmit & receive ends of the line use to locate saved header.
00130  */
00131 struct cstate {
00132         struct cstate *cs_next; /* next most recently used cstate (xmit only) */
00133         u_int16_t cs_hlen;      /* size of hdr (receive only) */
00134         u_char cs_id;           /* connection # associated with this state */
00135         u_char cs_filler;
00136         union {
00137           char csu_hdr[MAX_HDR];
00138           struct ip csu_ip;     /* ip/tcp hdr from most recent packet */
00139         } slcs_u;
00140 };
00141 #define cs_ip slcs_u.csu_ip
00142 #define cs_hdr slcs_u.csu_hdr
00143
00144 /*
00145  * all the state data for one serial line (we need one of these
00146  * per line).
00147  */
00148 struct slcompress {
00149         struct cstate *last_cs; /* most recently used tstate */
00150         u_char last_recv;       /* last rcvd conn. id */
00151         u_char last_xmit;       /* last sent conn. id */
00152         u_int16_t flags;
00153 #ifndef SL_NO_STATS
00154         int sls_packets;        /* outbound packets */
00155         int sls_compressed;     /* outbound compressed packets */
00156         int sls_searches;       /* searches for connection state */
00157         int sls_misses;         /* times couldn't find conn. state */
00158         int sls_uncompressedin; /* inbound uncompressed packets */
00159         int sls_compressedin;   /* inbound compressed packets */
00160         int sls_errorin;        /* inbound unknown type packets */
00161         int sls_tossed;         /* inbound packets tossed because of error */
00162 #endif
00163         struct cstate tstate[MAX_STATES];       /* xmit connection states */
00164         struct cstate rstate[MAX_STATES];       /* receive connection states */
00165 };
00166 /* flag values */
00167 #define SLF_TOSS 1              /* tossing rcvd frames because of input err */
00168
00169 void  sl_compress_init (struct slcompress *);
00170 void  sl_compress_setup (struct slcompress *, int);
00171 u_int sl_compress_tcp (struct mbuf *, struct ip *, struct slcompress *, int);
00172 int   sl_uncompress_tcp (u_char **, int, u_int, struct slcompress *);
00173 int   sl_uncompress_tcp_core (u_char *, int, int, u_int, struct slcompress *, u_char **, u_int *);
00174
00175 #endif
Generated on Wed Jan 25 15:42:33 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/net/SLIP.H Source File

inc/net/SLIP.H

Go to the documentation of this file.
00001
00005 /*      $NetBSD: slip.h,v 1.6 1994/06/29 06:36:53 cgd Exp $     */
00006
00007 /*-
00008  * Copyright (c) 1994
00009  *      The Regents of the University of California.  All rights reserved.
00010  *
00011  * Redistribution and use in source and binary forms, with or without
00012  * modification, are permitted provided that the following conditions
00013  * are met:
00014  * 1. Redistributions of source code must retain the above copyright
00015  *    notice, this list of conditions and the following disclaimer.
00016  * 2. Redistributions in binary form must reproduce the above copyright
00017  *    notice, this list of conditions and the following disclaimer in the
00018  *    documentation and/or other materials provided with the distribution.
00019  * 3. All advertising materials mentioning features or use of this software
00020  *    must display the following acknowledgement:
00021  *      This product includes software developed by the University of
00022  *      California, Berkeley and its contributors.
00023  * 4. Neither the name of the University nor the names of its contributors
00024  *    may be used to endorse or promote products derived from this software
00025  *    without specific prior written permission.
00026  *
00027  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
00028  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00029  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00030  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
00031  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00032  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00033  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00034  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00035  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00036  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00037  * SUCH DAMAGE.
00038  *
00039  *      @(#)slip.h      8.1 (Berkeley) 2/12/94
00040  */
00041
00042 #ifndef __NET_SLIP_H
00043 #define __NET_SLIP_H
00044
00045 /* Ioctls operating on SLIP ttys. */
00046 #define SLIOCGUNIT      _IOR('t', 88, int)      /* get slip unit number */
00047
00048 /*
00049  * Definitions of the pseudo-link-level header attached to slip
00050  * packets grabbed by the packet filter (bpf) traffic monitor.
00051  */
00052 #define SLIP_HDRLEN     16              /* BPF SLIP header length */
00053
00054 /* Offsets into BPF SLIP header. */
00055 #define SLX_DIR         0               /* direction; see below */
00056 #define SLX_CHDR        1               /* compressed header data */
00057 #define CHDR_LEN        15              /* length of compressed header data */
00058
00059 #define SLIPDIR_IN      0               /* incoming */
00060 #define SLIPDIR_OUT     1               /* outgoing */
00061
00062 #endif
Generated on Wed Jan 25 15:42:33 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/netinet/ICMP6.H Source File

inc/netinet/ICMP6.H

Go to the documentation of this file.
00001
00005 /*      $FreeBSD: src/sys/netinet/icmp6.h,v 1.8 2002/05/06 16:28:25 ume Exp $   */
00006 /*      $KAME: icmp6.h,v 1.46 2001/04/27 15:09:48 itojun Exp $  */
00007
00008 /*
00009  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
00010  * All rights reserved.
00011  *
00012  * Redistribution and use in source and binary forms, with or without
00013  * modification, are permitted provided that the following conditions
00014  * are met:
00015  * 1. Redistributions of source code must retain the above copyright
00016  *    notice, this list of conditions and the following disclaimer.
00017  * 2. Redistributions in binary form must reproduce the above copyright
00018  *    notice, this list of conditions and the following disclaimer in the
00019  *    documentation and/or other materials provided with the distribution.
00020  * 3. Neither the name of the project nor the names of its contributors
00021  *    may be used to endorse or promote products derived from this software
00022  *    without specific prior written permission.
00023  *
00024  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
00025  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00026  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00027  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
00028  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00029  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00030  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00031  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00032  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00033  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00034  * SUCH DAMAGE.
00035  */
00036
00037 /*
00038  * Copyright (c) 1982, 1986, 1993
00039  *      The Regents of the University of California.  All rights reserved.
00040  *
00041  * Redistribution and use in source and binary forms, with or without
00042  * modification, are permitted provided that the following conditions
00043  * are met:
00044  * 1. Redistributions of source code must retain the above copyright
00045  *    notice, this list of conditions and the following disclaimer.
00046  * 2. Redistributions in binary form must reproduce the above copyright
00047  *    notice, this list of conditions and the following disclaimer in the
00048  *    documentation and/or other materials provided with the distribution.
00049  * 3. All advertising materials mentioning features or use of this software
00050  *    must display the following acknowledgement:
00051  *      This product includes software developed by the University of
00052  *      California, Berkeley and its contributors.
00053  * 4. Neither the name of the University nor the names of its contributors
00054  *    may be used to endorse or promote products derived from this software
00055  *    without specific prior written permission.
00056  *
00057  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
00058  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00059  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00060  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
00061  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00062  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00063  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00064  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00065  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00066  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00067  * SUCH DAMAGE.
00068  *
00069  *      @(#)ip_icmp.h   8.1 (Berkeley) 6/10/93
00070  */
00071
00072 #ifndef _NETINET_ICMP6_H_
00073 #define _NETINET_ICMP6_H_
00074
00075 #ifndef __SYS_WTYPES_H
00076 #include <sys/wtypes.h>
00077 #endif
00078
00079 #define ICMPV6_PLD_MAXLEN       1232    /* IPV6_MMTU - sizeof(struct ip6_hdr)
00080                                            - sizeof(struct icmp6_hdr) */
00081 #include <sys/packon.h>
00082
00083 struct icmp6_hdr {
00084         u_int8_t        icmp6_type;     /* type field */
00085         u_int8_t        icmp6_code;     /* code field */
00086         u_int16_t       icmp6_cksum;    /* checksum field */
00087         union {
00088           u_int32_t     icmp6_un_data32[1]; /* type-specific field */
00089           u_int16_t     icmp6_un_data16[2]; /* type-specific field */
00090           u_int8_t      icmp6_un_data8[4];  /* type-specific field */
00091         } icmp6_dataun;
00092 };
00093
00094 #define icmp6_data32    icmp6_dataun.icmp6_un_data32
00095 #define icmp6_data16    icmp6_dataun.icmp6_un_data16
00096 #define icmp6_data8     icmp6_dataun.icmp6_un_data8
00097 #define icmp6_pptr      icmp6_data32[0]         /* parameter prob */
00098 #define icmp6_mtu       icmp6_data32[0]         /* packet too big */
00099 #define icmp6_id        icmp6_data16[0]         /* echo request/reply */
00100 #define icmp6_seq       icmp6_data16[1]         /* echo request/reply */
00101 #define icmp6_maxdelay  icmp6_data16[0]         /* mcast group membership */
00102
00103 #define ICMP6_DST_UNREACH               1       /* dest unreachable, codes: */
00104 #define ICMP6_PACKET_TOO_BIG            2       /* packet too big */
00105 #define ICMP6_TIME_EXCEEDED             3       /* time exceeded, code: */
00106 #define ICMP6_PARAM_PROB                4       /* ip6 header bad */
00107
00108 #define ICMP6_ECHO_REQUEST              128     /* echo service */
00109 #define ICMP6_ECHO_REPLY                129     /* echo reply */
00110 #define ICMP6_MEMBERSHIP_QUERY          130     /* group membership query */
00111 #define MLD_LISTENER_QUERY              130     /* multicast listener query */
00112 #define ICMP6_MEMBERSHIP_REPORT         131     /* group membership report */
00113 #define MLD_LISTENER_REPORT             131     /* multicast listener report */
00114 #define ICMP6_MEMBERSHIP_REDUCTION      132     /* group membership termination */
00115 #define MLD_LISTENER_DONE               132     /* multicast listener done */
00116
00117 #ifndef _KERNEL
00118 /* the followings are for backward compatibility to old KAME apps. */
00119 #define MLD6_LISTENER_QUERY     MLD_LISTENER_QUERY
00120 #define MLD6_LISTENER_REPORT    MLD_LISTENER_REPORT
00121 #define MLD6_LISTENER_DONE      MLD_LISTENER_DONE
00122 #endif
00123
00124 #define ND_ROUTER_SOLICIT               133     /* router solicitation */
00125 #define ND_ROUTER_ADVERT                134     /* router advertisment */
00126 #define ND_NEIGHBOR_SOLICIT             135     /* neighbor solicitation */
00127 #define ND_NEIGHBOR_ADVERT              136     /* neighbor advertisment */
00128 #define ND_REDIRECT                     137     /* redirect */
00129
00130 #define ICMP6_ROUTER_RENUMBERING        138     /* router renumbering */
00131
00132 #define ICMP6_WRUREQUEST                139     /* who are you request */
00133 #define ICMP6_WRUREPLY                  140     /* who are you reply */
00134 #define ICMP6_FQDN_QUERY                139     /* FQDN query */
00135 #define ICMP6_FQDN_REPLY                140     /* FQDN reply */
00136 #define ICMP6_NI_QUERY                  139     /* node information request */
00137 #define ICMP6_NI_REPLY                  140     /* node information reply */
00138
00139 /* The definitions below are experimental. TBA */
00140 #define MLD_MTRACE_RESP                 200     /* mtrace resp (to sender) */
00141 #define MLD_MTRACE                      201     /* mtrace messages */
00142
00143 #define ICMP6_HADISCOV_REQUEST          202     /* XXX To be defined */
00144 #define ICMP6_HADISCOV_REPLY            203     /* XXX To be defined */
00145
00146 #ifndef _KERNEL
00147 #define MLD6_MTRACE_RESP        MLD_MTRACE_RESP
00148 #define MLD6_MTRACE             MLD_MTRACE
00149 #endif
00150
00151 #define ICMP6_MAXTYPE                   203
00152
00153 #define ICMP6_DST_UNREACH_NOROUTE       0       /* no route to destination */
00154 #define ICMP6_DST_UNREACH_ADMIN         1       /* administratively prohibited */
00155 #define ICMP6_DST_UNREACH_NOTNEIGHBOR   2       /* not a neighbor(obsolete) */
00156 #define ICMP6_DST_UNREACH_BEYONDSCOPE   2       /* beyond scope of source address */
00157 #define ICMP6_DST_UNREACH_ADDR          3       /* address unreachable */
00158 #define ICMP6_DST_UNREACH_NOPORT        4       /* port unreachable */
00159
00160 #define ICMP6_TIME_EXCEED_TRANSIT       0       /* ttl==0 in transit */
00161 #define ICMP6_TIME_EXCEED_REASSEMBLY    1       /* ttl==0 in reass */
00162
00163 #define ICMP6_PARAMPROB_HEADER          0       /* erroneous header field */
00164 #define ICMP6_PARAMPROB_NEXTHEADER      1       /* unrecognized next header */
00165 #define ICMP6_PARAMPROB_OPTION          2       /* unrecognized option */
00166
00167 #define ICMP6_INFOMSG_MASK              0x80    /* all informational messages */
00168
00169 #define ICMP6_NI_SUBJ_IPV6      0       /* Query Subject is an IPv6 address */
00170 #define ICMP6_NI_SUBJ_FQDN      1       /* Query Subject is a Domain name */
00171 #define ICMP6_NI_SUBJ_IPV4      2       /* Query Subject is an IPv4 address */
00172
00173 #define ICMP6_NI_SUCCESS        0       /* node information successful reply */
00174 #define ICMP6_NI_REFUSED        1       /* node information request is refused */
00175 #define ICMP6_NI_UNKNOWN        2       /* unknown Qtype */
00176
00177 #define ICMP6_ROUTER_RENUMBERING_COMMAND  0     /* rr command */
00178 #define ICMP6_ROUTER_RENUMBERING_RESULT   1     /* rr result */
00179 #define ICMP6_ROUTER_RENUMBERING_SEQNUM_RESET   255     /* rr seq num reset */
00180
00181 /* Used in kernel only */
00182 #define ND_REDIRECT_ONLINK      0       /* redirect to an on-link node */
00183 #define ND_REDIRECT_ROUTER      1       /* redirect to a better router */
00184
00185 /*
00186  * Multicast Listener Discovery
00187  */
00188 struct mld_hdr {
00189        struct icmp6_hdr  mld_icmp6_hdr;
00190        struct in6_addr   mld_addr; /* multicast address */
00191       };
00192
00193 /* definitions to provide backward compatibility to old KAME applications */
00194 #ifndef _KERNEL
00195 #define mld6_hdr        mld_hdr
00196 #define mld6_type       mld_type
00197 #define mld6_code       mld_code
00198 #define mld6_cksum      mld_cksum
00199 #define mld6_maxdelay   mld_maxdelay
00200 #define mld6_reserved   mld_reserved
00201 #define mld6_addr       mld_addr
00202 #endif
00203
00204 /* shortcut macro definitions */
00205 #define mld_type        mld_icmp6_hdr.icmp6_type
00206 #define mld_code        mld_icmp6_hdr.icmp6_code
00207 #define mld_cksum       mld_icmp6_hdr.icmp6_cksum
00208 #define mld_maxdelay    mld_icmp6_hdr.icmp6_data16[0]
00209 #define mld_reserved    mld_icmp6_hdr.icmp6_data16[1]
00210
00211 /*
00212  * Neighbor Discovery
00213  */
00214
00215 struct nd_router_solicit {      /* router solicitation */
00216        struct icmp6_hdr        nd_rs_hdr;
00217        /* could be followed by options */
00218      };
00219
00220 #define nd_rs_type      nd_rs_hdr.icmp6_type
00221 #define nd_rs_code      nd_rs_hdr.icmp6_code
00222 #define nd_rs_cksum     nd_rs_hdr.icmp6_cksum
00223 #define nd_rs_reserved  nd_rs_hdr.icmp6_data32[0]
00224
00225 struct nd_router_advert {       /* router advertisement */
00226        struct icmp6_hdr nd_ra_hdr;
00227        u_int32_t        nd_ra_reachable;        /* reachable time */
00228        u_int32_t        nd_ra_retransmit;       /* retransmit timer */
00229        /* could be followed by options */
00230      };
00231
00232 #define nd_ra_type              nd_ra_hdr.icmp6_type
00233 #define nd_ra_code              nd_ra_hdr.icmp6_code
00234 #define nd_ra_cksum             nd_ra_hdr.icmp6_cksum
00235 #define nd_ra_curhoplimit       nd_ra_hdr.icmp6_data8[0]
00236 #define nd_ra_flags_reserved    nd_ra_hdr.icmp6_data8[1]
00237 #define ND_RA_FLAG_MANAGED      0x80
00238 #define ND_RA_FLAG_OTHER        0x40
00239 #define ND_RA_FLAG_HA           0x20
00240
00241 /*
00242  * Router preference values based on draft-draves-ipngwg-router-selection-01.
00243  * These are non-standard definitions.
00244  */
00245 #define ND_RA_FLAG_RTPREF_MASK  0x18 /* 00011000 */
00246
00247 #define ND_RA_FLAG_RTPREF_HIGH  0x08 /* 00001000 */
00248 #define ND_RA_FLAG_RTPREF_MEDIUM        0x00 /* 00000000 */
00249 #define ND_RA_FLAG_RTPREF_LOW   0x18 /* 00011000 */
00250 #define ND_RA_FLAG_RTPREF_RSV   0x10 /* 00010000 */
00251
00252 #define nd_ra_router_lifetime   nd_ra_hdr.icmp6_data16[1]
00253
00254 struct nd_neighbor_solicit {    /* neighbor solicitation */
00255        struct icmp6_hdr  nd_ns_hdr;
00256        struct in6_addr   nd_ns_target;   /*target address */
00257        /* could be followed by options */
00258      };
00259
00260 #define nd_ns_type              nd_ns_hdr.icmp6_type
00261 #define nd_ns_code              nd_ns_hdr.icmp6_code
00262 #define nd_ns_cksum             nd_ns_hdr.icmp6_cksum
00263 #define nd_ns_reserved          nd_ns_hdr.icmp6_data32[0]
00264
00265 struct nd_neighbor_advert {     /* neighbor advertisement */
00266        struct icmp6_hdr  nd_na_hdr;
00267        struct in6_addr   nd_na_target;   /* target address */
00268        /* could be followed by options */
00269      };
00270
00271 #define nd_na_type              nd_na_hdr.icmp6_type
00272 #define nd_na_code              nd_na_hdr.icmp6_code
00273 #define nd_na_cksum             nd_na_hdr.icmp6_cksum
00274 #define nd_na_flags_reserved    nd_na_hdr.icmp6_data32[0]
00275 #if BYTE_ORDER == BIG_ENDIAN
00276 #define ND_NA_FLAG_ROUTER               0x80000000
00277 #define ND_NA_FLAG_SOLICITED            0x40000000
00278 #define ND_NA_FLAG_OVERRIDE             0x20000000
00279 #else
00280 #if BYTE_ORDER == LITTLE_ENDIAN
00281 #define ND_NA_FLAG_ROUTER               0x80
00282 #define ND_NA_FLAG_SOLICITED            0x40
00283 #define ND_NA_FLAG_OVERRIDE             0x20
00284 #endif
00285 #endif
00286
00287 struct nd_redirect {            /* redirect */
00288        struct icmp6_hdr nd_rd_hdr;
00289        struct in6_addr  nd_rd_target;   /* target address */
00290        struct in6_addr  nd_rd_dst;      /* destination address */
00291        /* could be followed by options */
00292      };
00293
00294 #define nd_rd_type      nd_rd_hdr.icmp6_type
00295 #define nd_rd_code      nd_rd_hdr.icmp6_code
00296 #define nd_rd_cksum     nd_rd_hdr.icmp6_cksum
00297 #define nd_rd_reserved  nd_rd_hdr.icmp6_data32[0]
00298
00299 struct nd_opt_hdr {             /* Neighbor discovery option header */
00300        u_int8_t  nd_opt_type;
00301        u_int8_t  nd_opt_len;
00302        /* followed by option specific data*/
00303      };
00304
00305 #define ND_OPT_SOURCE_LINKADDR          1
00306 #define ND_OPT_TARGET_LINKADDR          2
00307 #define ND_OPT_PREFIX_INFORMATION       3
00308 #define ND_OPT_REDIRECTED_HEADER        4
00309 #define ND_OPT_MTU                      5
00310
00311 #define ND_OPT_ROUTE_INFO               200     /* draft-ietf-ipngwg-router-preference, not officially assigned yet */
00312
00313 struct nd_opt_prefix_info {     /* prefix information */
00314        u_int8_t        nd_opt_pi_type;
00315        u_int8_t        nd_opt_pi_len;
00316        u_int8_t        nd_opt_pi_prefix_len;
00317        u_int8_t        nd_opt_pi_flags_reserved;
00318        u_int32_t       nd_opt_pi_valid_time;
00319        u_int32_t       nd_opt_pi_preferred_time;
00320        u_int32_t       nd_opt_pi_reserved2;
00321        struct in6_addr nd_opt_pi_prefix;
00322      };
00323
00324 #define ND_OPT_PI_FLAG_ONLINK           0x80
00325 #define ND_OPT_PI_FLAG_AUTO             0x40
00326
00327 struct nd_opt_rd_hdr {          /* redirected header */
00328        u_int8_t        nd_opt_rh_type;
00329        u_int8_t        nd_opt_rh_len;
00330        u_int16_t       nd_opt_rh_reserved1;
00331        u_int32_t       nd_opt_rh_reserved2;
00332        /* followed by IP header and data */
00333      };
00334
00335 struct nd_opt_mtu {             /* MTU option */
00336        u_int8_t        nd_opt_mtu_type;
00337        u_int8_t        nd_opt_mtu_len;
00338        u_int16_t       nd_opt_mtu_reserved;
00339        u_int32_t       nd_opt_mtu_mtu;
00340      };
00341
00342 struct nd_opt_route_info {      /* route info */
00343        u_int8_t        nd_opt_rti_type;
00344        u_int8_t        nd_opt_rti_len;
00345        u_int8_t        nd_opt_rti_prefixlen;
00346        u_int8_t        nd_opt_rti_flags;
00347        u_int32_t       nd_opt_rti_lifetime;
00348        /* prefix follows */
00349      };
00350
00351 /*
00352  * icmp6 namelookup
00353  */
00354
00355 struct icmp6_namelookup {
00356        struct icmp6_hdr icmp6_nl_hdr;
00357        u_int8_t         icmp6_nl_nonce[8];
00358        int32_t          icmp6_nl_ttl;
00359 #if 0
00360        u_int8_t         icmp6_nl_len;
00361        u_int8_t         icmp6_nl_name[3];
00362 #endif
00363        /* could be followed by options */
00364      };
00365
00366 /*
00367  * icmp6 node information
00368  */
00369 struct icmp6_nodeinfo {
00370        struct icmp6_hdr icmp6_ni_hdr;
00371        u_int8_t icmp6_ni_nonce[8];
00372        /* could be followed by reply data */
00373      };
00374
00375 #define ni_type         icmp6_ni_hdr.icmp6_type
00376 #define ni_code         icmp6_ni_hdr.icmp6_code
00377 #define ni_cksum        icmp6_ni_hdr.icmp6_cksum
00378 #define ni_qtype        icmp6_ni_hdr.icmp6_data16[0]
00379 #define ni_flags        icmp6_ni_hdr.icmp6_data16[1]
00380
00381 #define NI_QTYPE_NOOP           0 /* NOOP  */
00382 #define NI_QTYPE_SUPTYPES       1 /* Supported Qtypes */
00383 #define NI_QTYPE_FQDN           2 /* FQDN (draft 04) */
00384 #define NI_QTYPE_DNSNAME        2 /* DNS Name */
00385 #define NI_QTYPE_NODEADDR       3 /* Node Addresses */
00386 #define NI_QTYPE_IPV4ADDR       4 /* IPv4 Addresses */
00387
00388 #if BYTE_ORDER == BIG_ENDIAN
00389 #define NI_SUPTYPE_FLAG_COMPRESS        0x1
00390 #define NI_FQDN_FLAG_VALIDTTL           0x1
00391 #elif BYTE_ORDER == LITTLE_ENDIAN
00392 #define NI_SUPTYPE_FLAG_COMPRESS        0x0100
00393 #define NI_FQDN_FLAG_VALIDTTL           0x0100
00394 #endif
00395
00396 #ifdef NAME_LOOKUPS_04
00397 #if BYTE_ORDER == BIG_ENDIAN
00398 #define NI_NODEADDR_FLAG_LINKLOCAL      0x1
00399 #define NI_NODEADDR_FLAG_SITELOCAL      0x2
00400 #define NI_NODEADDR_FLAG_GLOBAL         0x4
00401 #define NI_NODEADDR_FLAG_ALL            0x8
00402 #define NI_NODEADDR_FLAG_TRUNCATE       0x10
00403 #define NI_NODEADDR_FLAG_ANYCAST        0x20 /* just experimental. not in spec */
00404 #elif BYTE_ORDER == LITTLE_ENDIAN
00405 #define NI_NODEADDR_FLAG_LINKLOCAL      0x0100
00406 #define NI_NODEADDR_FLAG_SITELOCAL      0x0200
00407 #define NI_NODEADDR_FLAG_GLOBAL         0x0400
00408 #define NI_NODEADDR_FLAG_ALL            0x0800
00409 #define NI_NODEADDR_FLAG_TRUNCATE       0x1000
00410 #define NI_NODEADDR_FLAG_ANYCAST        0x2000 /* just experimental. not in spec */
00411 #endif
00412 #else  /* draft-ietf-ipngwg-icmp-name-lookups-05 (and later?) */
00413 #if BYTE_ORDER == BIG_ENDIAN
00414 #define NI_NODEADDR_FLAG_TRUNCATE       0x1
00415 #define NI_NODEADDR_FLAG_ALL            0x2
00416 #define NI_NODEADDR_FLAG_COMPAT         0x4
00417 #define NI_NODEADDR_FLAG_LINKLOCAL      0x8
00418 #define NI_NODEADDR_FLAG_SITELOCAL      0x10
00419 #define NI_NODEADDR_FLAG_GLOBAL         0x20
00420 #define NI_NODEADDR_FLAG_ANYCAST        0x40 /* just experimental. not in spec */
00421 #elif BYTE_ORDER == LITTLE_ENDIAN
00422 #define NI_NODEADDR_FLAG_TRUNCATE       0x0100
00423 #define NI_NODEADDR_FLAG_ALL            0x0200
00424 #define NI_NODEADDR_FLAG_COMPAT         0x0400
00425 #define NI_NODEADDR_FLAG_LINKLOCAL      0x0800
00426 #define NI_NODEADDR_FLAG_SITELOCAL      0x1000
00427 #define NI_NODEADDR_FLAG_GLOBAL         0x2000
00428 #define NI_NODEADDR_FLAG_ANYCAST        0x4000 /* just experimental. not in spec */
00429 #endif
00430 #endif
00431
00432 struct ni_reply_fqdn {
00433        u_int32_t ni_fqdn_ttl;      /* TTL */
00434        u_int8_t  ni_fqdn_namelen;  /* length in octets of the FQDN */
00435        u_int8_t  ni_fqdn_name[3];  /* XXX: alignment */
00436      };
00437
00438 /*
00439  * Router Renumbering. as router-renum-08.txt
00440  */
00441 struct icmp6_router_renum {     /* router renumbering header */
00442        struct icmp6_hdr        rr_hdr;
00443        u_int8_t        rr_segnum;
00444        u_int8_t        rr_flags;
00445        u_int16_t       rr_maxdelay;
00446        u_int32_t       rr_reserved;
00447      };
00448
00449 #define ICMP6_RR_FLAGS_TEST             0x80
00450 #define ICMP6_RR_FLAGS_REQRESULT        0x40
00451 #define ICMP6_RR_FLAGS_FORCEAPPLY       0x20
00452 #define ICMP6_RR_FLAGS_SPECSITE         0x10
00453 #define ICMP6_RR_FLAGS_PREVDONE         0x08
00454
00455 #define rr_type         rr_hdr.icmp6_type
00456 #define rr_code         rr_hdr.icmp6_code
00457 #define rr_cksum        rr_hdr.icmp6_cksum
00458 #define rr_seqnum       rr_hdr.icmp6_data32[0]
00459
00460 struct rr_pco_match {           /* match prefix part */
00461        u_int8_t        rpm_code;
00462        u_int8_t        rpm_len;
00463        u_int8_t        rpm_ordinal;
00464        u_int8_t        rpm_matchlen;
00465        u_int8_t        rpm_minlen;
00466        u_int8_t        rpm_maxlen;
00467        u_int16_t       rpm_reserved;
00468        struct  in6_addr        rpm_prefix;
00469      };
00470
00471 #define RPM_PCO_ADD             1
00472 #define RPM_PCO_CHANGE          2
00473 #define RPM_PCO_SETGLOBAL       3
00474 #define RPM_PCO_MAX             4
00475
00476 struct rr_pco_use {             /* use prefix part */
00477        u_int8_t        rpu_uselen;
00478        u_int8_t        rpu_keeplen;
00479        u_int8_t        rpu_ramask;
00480        u_int8_t        rpu_raflags;
00481        u_int32_t       rpu_vltime;
00482        u_int32_t       rpu_pltime;
00483        u_int32_t       rpu_flags;
00484        struct  in6_addr rpu_prefix;
00485      };
00486
00487 #define ICMP6_RR_PCOUSE_RAFLAGS_ONLINK  0x80
00488 #define ICMP6_RR_PCOUSE_RAFLAGS_AUTO    0x40
00489
00490 #if BYTE_ORDER == BIG_ENDIAN
00491 #define ICMP6_RR_PCOUSE_FLAGS_DECRVLTIME     0x80000000
00492 #define ICMP6_RR_PCOUSE_FLAGS_DECRPLTIME     0x40000000
00493 #elif BYTE_ORDER == LITTLE_ENDIAN
00494 #define ICMP6_RR_PCOUSE_FLAGS_DECRVLTIME     0x80
00495 #define ICMP6_RR_PCOUSE_FLAGS_DECRPLTIME     0x40
00496 #endif
00497
00498 struct rr_result {              /* router renumbering result message */
00499        u_int16_t       rrr_flags;
00500        u_int8_t        rrr_ordinal;
00501        u_int8_t        rrr_matchedlen;
00502        u_int32_t       rrr_ifid;
00503        struct  in6_addr rrr_prefix;
00504      };
00505
00506 #include <sys/packoff.h>
00507
00508 #if BYTE_ORDER == BIG_ENDIAN
00509 #define ICMP6_RR_RESULT_FLAGS_OOB               0x0002
00510 #define ICMP6_RR_RESULT_FLAGS_FORBIDDEN         0x0001
00511 #elif BYTE_ORDER == LITTLE_ENDIAN
00512 #define ICMP6_RR_RESULT_FLAGS_OOB               0x0200
00513 #define ICMP6_RR_RESULT_FLAGS_FORBIDDEN         0x0100
00514 #endif
00515
00516 /*
00517  * icmp6 filter structures.
00518  */
00519
00520 struct icmp6_filter {
00521        u_int32_t icmp6_filt[8];
00522      };
00523
00524 #define ICMP6_FILTER_SETPASSALL(filterp) \
00525         memset(filterp, 0xff, sizeof(struct icmp6_filter))
00526 #define ICMP6_FILTER_SETBLOCKALL(filterp) \
00527         memset(filterp, 0x00, sizeof(struct icmp6_filter))
00528
00529 #define ICMP6_FILTER_SETPASS(type, filterp) \
00530         (((filterp)->icmp6_filt[(type) >> 5]) |= (1 << ((type) & 31)))
00531 #define ICMP6_FILTER_SETBLOCK(type, filterp) \
00532         (((filterp)->icmp6_filt[(type) >> 5]) &= ~(1 << ((type) & 31)))
00533 #define ICMP6_FILTER_WILLPASS(type, filterp) \
00534         ((((filterp)->icmp6_filt[(type) >> 5]) & (1 << ((type) & 31))) != 0)
00535 #define ICMP6_FILTER_WILLBLOCK(type, filterp) \
00536         ((((filterp)->icmp6_filt[(type) >> 5]) & (1 << ((type) & 31))) == 0)
00537
00538 /*
00539  * Variables related to this implementation
00540  * of the internet control message protocol version 6.
00541  */
00542 struct icmp6errstat {
00543        u_quad_t icp6errs_dst_unreach_noroute;
00544        u_quad_t icp6errs_dst_unreach_admin;
00545        u_quad_t icp6errs_dst_unreach_beyondscope;
00546        u_quad_t icp6errs_dst_unreach_addr;
00547        u_quad_t icp6errs_dst_unreach_noport;
00548        u_quad_t icp6errs_packet_too_big;
00549        u_quad_t icp6errs_time_exceed_transit;
00550        u_quad_t icp6errs_time_exceed_reassembly;
00551        u_quad_t icp6errs_paramprob_header;
00552        u_quad_t icp6errs_paramprob_nextheader;
00553        u_quad_t icp6errs_paramprob_option;
00554        u_quad_t icp6errs_redirect; /* we regard redirect as an error here */
00555        u_quad_t icp6errs_unknown;
00556      };
00557
00558 struct icmp6stat {
00559        /* statistics related to icmp6 packets generated */
00560        u_quad_t icp6s_error;           /* # of calls to icmp6_error */
00561        u_quad_t icp6s_canterror;       /* no error 'cuz old was icmp */
00562        u_quad_t icp6s_toofreq;         /* no error 'cuz rate limitation */
00563        u_quad_t icp6s_outhist[256];
00564
00565        /* statistics related to input message processed */
00566        u_quad_t icp6s_badcode;         /* icmp6_code out of range */
00567        u_quad_t icp6s_tooshort;        /* packet < sizeof(struct icmp6_hdr) */
00568        u_quad_t icp6s_checksum;        /* bad checksum */
00569        u_quad_t icp6s_badlen;          /* calculated bound mismatch */
00570        /*
00571         * number of responses: this member is inherited from netinet code, but
00572         * for netinet6 code, it is already available in icp6s_outhist[].
00573         */
00574        u_quad_t icp6s_reflect;
00575        u_quad_t icp6s_inhist[256];
00576        u_quad_t icp6s_nd_toomanyopt;   /* too many ND options */
00577        struct icmp6errstat icp6s_outerrhist;
00578 #define icp6s_odst_unreach_noroute \
00579         icp6s_outerrhist.icp6errs_dst_unreach_noroute
00580 #define icp6s_odst_unreach_admin icp6s_outerrhist.icp6errs_dst_unreach_admin
00581 #define icp6s_odst_unreach_beyondscope \
00582         icp6s_outerrhist.icp6errs_dst_unreach_beyondscope
00583 #define icp6s_odst_unreach_addr icp6s_outerrhist.icp6errs_dst_unreach_addr
00584 #define icp6s_odst_unreach_noport icp6s_outerrhist.icp6errs_dst_unreach_noport
00585 #define icp6s_opacket_too_big icp6s_outerrhist.icp6errs_packet_too_big
00586 #define icp6s_otime_exceed_transit \
00587         icp6s_outerrhist.icp6errs_time_exceed_transit
00588 #define icp6s_otime_exceed_reassembly \
00589         icp6s_outerrhist.icp6errs_time_exceed_reassembly
00590 #define icp6s_oparamprob_header icp6s_outerrhist.icp6errs_paramprob_header
00591 #define icp6s_oparamprob_nextheader \
00592         icp6s_outerrhist.icp6errs_paramprob_nextheader
00593 #define icp6s_oparamprob_option icp6s_outerrhist.icp6errs_paramprob_option
00594 #define icp6s_oredirect icp6s_outerrhist.icp6errs_redirect
00595 #define icp6s_ounknown icp6s_outerrhist.icp6errs_unknown
00596        u_quad_t icp6s_pmtuchg;         /* path MTU changes */
00597        u_quad_t icp6s_nd_badopt;       /* bad ND options */
00598        u_quad_t icp6s_badns;           /* bad neighbor solicitation */
00599        u_quad_t icp6s_badna;           /* bad neighbor advertisement */
00600        u_quad_t icp6s_badrs;           /* bad router advertisement */
00601        u_quad_t icp6s_badra;           /* bad router advertisement */
00602        u_quad_t icp6s_badredirect;     /* bad redirect message */
00603      };
00604
00605 /*
00606  * Names for ICMP sysctl objects
00607  */
00608 #define ICMPV6CTL_STATS         1
00609 #define ICMPV6CTL_REDIRACCEPT   2       /* accept/process redirects */
00610 #define ICMPV6CTL_REDIRTIMEOUT  3       /* redirect cache time */
00611 #define ICMPV6CTL_ND6_PRUNE     6
00612 #define ICMPV6CTL_ND6_DELAY     8
00613 #define ICMPV6CTL_ND6_UMAXTRIES 9
00614 #define ICMPV6CTL_ND6_MMAXTRIES         10
00615 #define ICMPV6CTL_ND6_USELOOPBACK       11
00616 /*#define ICMPV6CTL_ND6_PROXYALL        12      obsoleted, do not reuse here */
00617 #define ICMPV6CTL_NODEINFO      13
00618 #define ICMPV6CTL_ERRPPSLIMIT   14      /* ICMPv6 error pps limitation */
00619 #define ICMPV6CTL_ND6_MAXNUDHINT        15
00620 #define ICMPV6CTL_MTUDISC_HIWAT 16
00621 #define ICMPV6CTL_MTUDISC_LOWAT 17
00622 #define ICMPV6CTL_ND6_DEBUG     18
00623 #define ICMPV6CTL_ND6_DRLIST    19
00624 #define ICMPV6CTL_ND6_PRLIST    20
00625 #define ICMPV6CTL_MAXID         21
00626
00627 #define ICMPV6CTL_NAMES { \
00628         { 0, 0 }, \
00629         { 0, 0 }, \
00630         { "rediraccept", CTLTYPE_INT }, \
00631         { "redirtimeout", CTLTYPE_INT }, \
00632         { 0, 0 }, \
00633         { 0, 0 }, \
00634         { "nd6_prune", CTLTYPE_INT }, \
00635         { 0, 0 }, \
00636         { "nd6_delay", CTLTYPE_INT }, \
00637         { "nd6_umaxtries", CTLTYPE_INT }, \
00638         { "nd6_mmaxtries", CTLTYPE_INT }, \
00639         { "nd6_useloopback", CTLTYPE_INT }, \
00640         { 0, 0 }, \
00641         { "nodeinfo", CTLTYPE_INT }, \
00642         { "errppslimit", CTLTYPE_INT }, \
00643         { "nd6_maxnudhint", CTLTYPE_INT }, \
00644         { "mtudisc_hiwat", CTLTYPE_INT }, \
00645         { "mtudisc_lowat", CTLTYPE_INT }, \
00646         { "nd6_debug", CTLTYPE_INT }, \
00647         { 0, 0 }, \
00648         { 0, 0 }, \
00649 }
00650
00651 #define RTF_PROBEMTU    RTF_PROTO1
00652
00653 #ifdef _KERNEL
00654 # ifdef __STDC__
00655 struct  rtentry;
00656 struct  rttimer;
00657 struct  in6_multi;
00658 # endif
00659 void    icmp6_init(void);
00660 void    icmp6_paramerror(struct mbuf *, int);
00661 void    icmp6_error(struct mbuf *, int, int, int);
00662 int     icmp6_input(struct mbuf **, int *, int);
00663 void    icmp6_fasttimo(void);
00664 void    icmp6_reflect(struct mbuf *, size_t);
00665 void    icmp6_prepare(struct mbuf *);
00666 void    icmp6_redirect_input(struct mbuf *, int);
00667 void    icmp6_redirect_output(struct mbuf *, struct rtentry *);
00668
00669 struct  ip6ctlparam;
00670 void    icmp6_mtudisc_update(struct ip6ctlparam *, int);
00671
00672 /* XXX: is this the right place for these macros? */
00673 #define icmp6_ifstat_inc(ifp, tag) \
00674 do {                                                            \
00675         if ((ifp) && (ifp)->if_index <= if_index                        \
00676          && (ifp)->if_index < icmp6_ifstatmax                   \
00677          && icmp6_ifstat && icmp6_ifstat[(ifp)->if_index]) {    \
00678                 icmp6_ifstat[(ifp)->if_index]->tag++;           \
00679         }                                                       \
00680 } while (0)
00681
00682 #define icmp6_ifoutstat_inc(ifp, type, code) \
00683 do { \
00684                 icmp6_ifstat_inc(ifp, ifs6_out_msg); \
00685                 if (type < ICMP6_INFOMSG_MASK) \
00686                         icmp6_ifstat_inc(ifp, ifs6_out_error); \
00687                 switch(type) { \
00688                  case ICMP6_DST_UNREACH: \
00689                          icmp6_ifstat_inc(ifp, ifs6_out_dstunreach); \
00690                          if (code == ICMP6_DST_UNREACH_ADMIN) \
00691                                  icmp6_ifstat_inc(ifp, ifs6_out_adminprohib); \
00692                          break; \
00693                  case ICMP6_PACKET_TOO_BIG: \
00694                          icmp6_ifstat_inc(ifp, ifs6_out_pkttoobig); \
00695                          break; \
00696                  case ICMP6_TIME_EXCEEDED: \
00697                          icmp6_ifstat_inc(ifp, ifs6_out_timeexceed); \
00698                          break; \
00699                  case ICMP6_PARAM_PROB: \
00700                          icmp6_ifstat_inc(ifp, ifs6_out_paramprob); \
00701                          break; \
00702                  case ICMP6_ECHO_REQUEST: \
00703                          icmp6_ifstat_inc(ifp, ifs6_out_echo); \
00704                          break; \
00705                  case ICMP6_ECHO_REPLY: \
00706                          icmp6_ifstat_inc(ifp, ifs6_out_echoreply); \
00707                          break; \
00708                  case MLD_LISTENER_QUERY: \
00709                          icmp6_ifstat_inc(ifp, ifs6_out_mldquery); \
00710                          break; \
00711                  case MLD_LISTENER_REPORT: \
00712                          icmp6_ifstat_inc(ifp, ifs6_out_mldreport); \
00713                          break; \
00714                  case MLD_LISTENER_DONE: \
00715                          icmp6_ifstat_inc(ifp, ifs6_out_mlddone); \
00716                          break; \
00717                  case ND_ROUTER_SOLICIT: \
00718                          icmp6_ifstat_inc(ifp, ifs6_out_routersolicit); \
00719                          break; \
00720                  case ND_ROUTER_ADVERT: \
00721                          icmp6_ifstat_inc(ifp, ifs6_out_routeradvert); \
00722                          break; \
00723                  case ND_NEIGHBOR_SOLICIT: \
00724                          icmp6_ifstat_inc(ifp, ifs6_out_neighborsolicit); \
00725                          break; \
00726                  case ND_NEIGHBOR_ADVERT: \
00727                          icmp6_ifstat_inc(ifp, ifs6_out_neighboradvert); \
00728                          break; \
00729                  case ND_REDIRECT: \
00730                          icmp6_ifstat_inc(ifp, ifs6_out_redirect); \
00731                          break; \
00732                 } \
00733 } while (0)
00734
00735 extern int      icmp6_rediraccept;      /* accept/process redirects */
00736 extern int      icmp6_redirtimeout;     /* cache time for redirect routes */
00737 #endif /* _KERNEL */
00738
00739 #endif /* not _NETINET_ICMP6_H_ */
Generated on Wed Jan 25 15:42:33 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/netinet/ICMP_VAR.H Source File

inc/netinet/ICMP_VAR.H

Go to the documentation of this file.
00001
00005 /*
00006  * Copyright (c) 1982, 1986, 1993
00007  *      The Regents of the University of California.  All rights reserved.
00008  *
00009  * Redistribution and use in source and binary forms, with or without
00010  * modification, are permitted provided that the following conditions
00011  * are met:
00012  * 1. Redistributions of source code must retain the above copyright
00013  *    notice, this list of conditions and the following disclaimer.
00014  * 2. Redistributions in binary form must reproduce the above copyright
00015  *    notice, this list of conditions and the following disclaimer in the
00016  *    documentation and/or other materials provided with the distribution.
00017  * 3. All advertising materials mentioning features or use of this software
00018  *    must display the following acknowledgement:
00019  *      This product includes software developed by the University of
00020  *      California, Berkeley and its contributors.
00021  * 4. Neither the name of the University nor the names of its contributors
00022  *    may be used to endorse or promote products derived from this software
00023  *    without specific prior written permission.
00024  *
00025  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
00026  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00027  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00028  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
00029  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00030  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00031  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00032  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00033  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00034  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00035  * SUCH DAMAGE.
00036  *
00037  *      @(#)icmp_var.h  8.1 (Berkeley) 6/10/93
00038  * $Id: icmp_var.h,v 1.4 1995/02/16 00:27:40 wollman Exp $
00039  */
00040
00041 #ifndef __NETINET_ICMP_VAR_H
00042 #define __NETINET_ICMP_VAR_H
00043
00044 #ifndef ICMP_MAXTYPE
00045 #define ICMP_MAXTYPE  18
00046 #endif
00047
00048 /*
00049  * Variables related to this implementation
00050  * of the internet control message protocol.
00051  */
00052 struct  icmpstat {
00053 /* statistics related to icmp packets generated */
00054         u_long  icps_error;             /* # of calls to icmp_error */
00055         u_long  icps_oldshort;          /* no error 'cuz old ip too short */
00056         u_long  icps_oldicmp;           /* no error 'cuz old was icmp */
00057         u_long  icps_outhist[ICMP_MAXTYPE + 1];
00058 /* statistics related to input messages processed */
00059         u_long  icps_badcode;           /* icmp_code out of range */
00060         u_long  icps_tooshort;          /* packet < ICMP_MINLEN */
00061         u_long  icps_checksum;          /* bad checksum */
00062         u_long  icps_badlen;            /* calculated bound mismatch */
00063         u_long  icps_reflect;           /* number of responses */
00064         u_long  icps_inhist[ICMP_MAXTYPE + 1];
00065         u_long  icps_bmcastecho;        /* b/mcast echo requests dropped */
00066         u_long  icps_bmcasttstamp;      /* b/mcast tstamp requests dropped */
00067         u_long  icps_badaddr;           /* bad return address */
00068         u_long  icps_noroute;           /* no route back */
00069 };
00070
00071 /*
00072  * Names for ICMP sysctl objects
00073  */
00074 #define ICMPCTL_MASKREPL        1       /* allow replies to netmask requests */
00075 #define ICMPCTL_STATS           2       /* statistics (read-only) */
00076 #define ICMPCTL_ICMPLIM         3
00077 #define ICMPCTL_MAXID           4
00078
00079 #define ICMPCTL_NAMES { \
00080         { 0, 0 }, \
00081         { "maskrepl", CTLTYPE_INT }, \
00082         { "stats", CTLTYPE_STRUCT }, \
00083         { "icmplim", CTLTYPE_INT }, \
00084 }
00085
00086 #endif
Generated on Wed Jan 25 15:42:33 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/netinet/IF_ETHER.H Source File

inc/netinet/IF_ETHER.H

Go to the documentation of this file.
00001
00005 /* Modified for emx by hv 1994
00006  *
00007  * Copyright (c) 1982, 1986 Regents of the University of California.
00008  * All rights reserved.
00009  *
00010  * Redistribution and use in source and binary forms, with or without
00011  * modification, are permitted provided that the following conditions
00012  * are met:
00013  * 1. Redistributions of source code must retain the above copyright
00014  *    notice, this list of conditions and the following disclaimer.
00015  * 2. Redistributions in binary form must reproduce the above copyright
00016  *    notice, this list of conditions and the following disclaimer in the
00017  *    documentation and/or other materials provided with the distribution.
00018  * 3. All advertising materials mentioning features or use of this software
00019  *    must display the following acknowledgement:
00020  *      This product includes software developed by the University of
00021  *      California, Berkeley and its contributors.
00022  * 4. Neither the name of the University nor the names of its contributors
00023  *    may be used to endorse or promote products derived from this software
00024  *    without specific prior written permission.
00025  *
00026  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
00027  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00028  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00029  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
00030  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00031  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00032  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00033  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00034  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00035  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00036  * SUCH DAMAGE.
00037  *
00038  *      from: @(#)if_ether.h    7.5 (Berkeley) 6/28/90
00039  *      $Id: if_ether.h,v 1.8 1994/02/02 05:58:54 hpeyerl Exp $
00040  */
00041
00042 #ifndef __NETINET_IF_ETHER_H
00043 #define __NETINET_IF_ETHER_H
00044
00045 #include <sys/packon.h>
00046
00047 /*
00048  * Ethernet address - 6 octets
00049  * this is only used by the ethers(3) functions.
00050  */
00051 struct ether_addr {
00052        u_char ether_addr_octet[6];
00053      };
00054
00055 /*
00056  * Structure of a 10Mb/s Ethernet header.
00057  */
00058 struct ether_header {
00059        u_char  ether_dhost[6];
00060        u_char  ether_shost[6];
00061        u_short ether_type;
00062      };
00063
00064 #define ETHERTYPE_PUP           0x0200  /* PUP protocol */
00065 /* the IBM header corrects the following to 0x608 for OS/2 but I believe
00066  * this is just a dirty hack
00067  */
00068 #define ETHERTYPE_ARP           0x0806  /* address resolution protocol */
00069 #define ETHERTYPE_IP            0x0800  /* IP protocol */
00070 #define ETHERTYPE_REVARP        0x8035  /* reverse addr resolution protocol */
00071
00072 /*
00073  * The ETHERTYPE_NTRAILER packet types starting at ETHERTYPE_TRAIL have
00074  * (type-ETHERTYPE_TRAIL)*512 bytes of data followed
00075  * by an ETHER type (as given above) and then the (variable-length) header.
00076  */
00077 #define ETHERTYPE_TRAIL         0x1000          /* Trailer packet */
00078 #define ETHERTYPE_NTRAILER      16
00079
00080 #define ETHERMTU                1500
00081 #define ETHERMIN                (60-14)
00082
00083 /*
00084  * Macro to map an IP multicast address to an Ethernet multicast address.
00085  * The high-order 25 bits of the Ethernet address are statically assigned,
00086  * and the low-order 23 bits are taken from the low end of the IP address.
00087  */
00088 #define ETHER_MAP_IP_MULTICAST(ipaddr, enaddr) \
00089         /* struct in_addr *ipaddr; */ \
00090         /* u_char enaddr[6];       */ \
00091         { \
00092           (enaddr)[0] = 0x01; \
00093           (enaddr)[1] = 0x00; \
00094           (enaddr)[2] = 0x5e; \
00095           (enaddr)[3] = ((u_char *)ipaddr)[1] & 0x7f; \
00096           (enaddr)[4] = ((u_char *)ipaddr)[2]; \
00097           (enaddr)[5] = ((u_char *)ipaddr)[3]; \
00098         }
00099
00100
00101 /*
00102  * Ethernet Address Resolution Protocol.
00103  *
00104  * See RFC 826 for protocol description.  Structure below is adapted
00105  * to resolving internet addresses.  Field names used correspond to
00106  * RFC 826.
00107  */
00108 struct ether_arp {
00109        struct  arphdr ea_hdr;  /* fixed-size header */
00110        u_char  arp_sha[6];     /* sender hardware address */
00111        u_char  arp_spa[4];     /* sender protocol address */
00112        u_char  arp_tha[6];     /* target hardware address */
00113        u_char  arp_tpa[4];     /* target protocol address */
00114      };
00115 #define arp_hrd ea_hdr.ar_hrd
00116 #define arp_pro ea_hdr.ar_pro
00117 #define arp_hln ea_hdr.ar_hln
00118 #define arp_pln ea_hdr.ar_pln
00119 #define arp_op  ea_hdr.ar_op
00120
00121
00122 /*
00123  * Structure shared between the ethernet driver modules and
00124  * the address resolution code.  For example, each ec_softc or il_softc
00125  * begins with this structure.
00126  */
00127 struct arpcom {
00128        struct  ifnet ac_if;               /* network-visible interface */
00129        u_char  ac_enaddr[6];              /* ethernet hardware address */
00130        struct in_addr ac_ipaddr;          /* copy of ip address- XXX */
00131        struct ether_multi *ac_multiaddrs; /* list of ether multicast addrs */
00132        int ac_multicnt;                   /* length of ac_multiaddrs list */
00133 };
00134
00135 /*
00136  * Internet to ethernet address resolution table.
00137  */
00138
00139 struct arptab {
00140        struct  in_addr at_iaddr;       /* internet address */
00141        u_char  at_enaddr[6];           /* ethernet address */
00142        u_char  at_timer;               /* minutes since last reference */
00143        u_char  at_flags;               /* flags */
00144        struct  mbuf *at_hold;          /* last packet until resolved/timeout */
00145 /* only os2 */
00146        u_short at_rcf;
00147        u_short at_rseg[8];
00148        u_long at_millisec;
00149        int at_interface;
00150 };
00151
00152
00153 extern u_char  etherbroadcastaddr[6];
00154 extern u_char  ether_ipmulticast_min[6];
00155 extern u_char  ether_ipmulticast_max[6];
00156
00157 /*
00158  * Ethernet multicast address structure.  There is one of these for each
00159  * multicast address or range of multicast addresses that we are supposed
00160  * to listen to on a particular interface.  They are kept in a linked list,
00161  * rooted in the interface's arpcom structure.  (This really has nothing to
00162  * do with ARP, or with the Internet address family, but this appears to be
00163  * the minimally-disrupting place to put it.)
00164  */
00165 struct ether_multi {
00166        u_char  enm_addrlo[6];          /* low  or only address of range */
00167        u_char  enm_addrhi[6];          /* high or only address of range */
00168        struct  arpcom *enm_ac;         /* back pointer to arpcom */
00169        u_int   enm_refcount;           /* no. claims to this addr/range */
00170        struct  ether_multi *enm_next;  /* ptr to next ether_multi */
00171      };
00172
00173 /*
00174  * Structure used by macros below to remember position when stepping through
00175  * all of the ether_multi records.
00176  */
00177 struct ether_multistep {
00178        struct ether_multi  *e_enm;
00179      };
00180
00181 #include <sys/packoff.h>
00182
00183 /*
00184  * Macro for looking up the ether_multi record for a given range of Ethernet
00185  * multicast addresses connected to a given arpcom structure.  If no matching
00186  * record is found, "enm" returns NULL.
00187  */
00188 #define ETHER_LOOKUP_MULTI(addrlo, addrhi, ac, enm) \
00189         /* u_char addrlo[6]; */ \
00190         /* u_char addrhi[6]; */ \
00191         /* struct arpcom *ac; */ \
00192         /* struct ether_multi *enm; */ \
00193 { \
00194         for ((enm) = (ac)->ac_multiaddrs; \
00195             (enm) != NULL && \
00196             (bcmp((enm)->enm_addrlo, (addrlo), 6) != 0 || \
00197              bcmp((enm)->enm_addrhi, (addrhi), 6) != 0); \
00198                 (enm) = (enm)->enm_next); \
00199 }
00200
00201 /*
00202  * Macro to step through all of the ether_multi records, one at a time.
00203  * The current position is remembered in "step", which the caller must
00204  * provide.  ETHER_FIRST_MULTI(), below, must be called to initialize "step"
00205  * and get the first record.  Both macros return a NULL "enm" when there
00206  * are no remaining records.
00207  */
00208 #define ETHER_NEXT_MULTI(step, enm) \
00209         /* struct ether_multistep step; */  \
00210         /* struct ether_multi *enm; */  \
00211 { \
00212         if (((enm) = (step).e_enm) != NULL) \
00213                 (step).e_enm = (enm)->enm_next; \
00214 }
00215
00216 #define ETHER_FIRST_MULTI(step, ac, enm) \
00217         /* struct ether_multistep step; */ \
00218         /* struct arpcom *ac; */ \
00219         /* struct ether_multi *enm; */ \
00220 { \
00221         (step).e_enm = (ac)->ac_multiaddrs; \
00222         ETHER_NEXT_MULTI((step), (enm)); \
00223 }
00224
00225 #endif
Generated on Wed Jan 25 15:42:32 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/netinet/IF_FDDI.H Source File

inc/netinet/IF_FDDI.H

Go to the documentation of this file.
00001
00005 /*
00006  * Copyright (c) 1982, 1986, 1993
00007  *      The Regents of the University of California.  All rights reserved.
00008  * Copyright (c) 1995 Matt Thomas (thomas@lkg.dec.com)
00009  * All rights reserved.
00010  *
00011  * Redistribution and use in source and binary forms, with or without
00012  * modification, are permitted provided that the following conditions
00013  * are met:
00014  * 1. Redistributions of source code must retain the above copyright
00015  *    notice, this list of conditions and the following disclaimer.
00016  * 2. Redistributions in binary form must reproduce the above copyright
00017  *    notice, this list of conditions and the following disclaimer in the
00018  *    documentation and/or other materials provided with the distribution.
00019  * 3. All advertising materials mentioning features or use of this software
00020  *    must display the following acknowledgement:
00021  *      This product includes software developed by the University of
00022  *      California, Berkeley and its contributors.
00023  * 4. Neither the name of the University nor the names of its contributors
00024  *    may be used to endorse or promote products derived from this software
00025  *    without specific prior written permission.
00026  *
00027  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
00028  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00029  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00030  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
00031  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00032  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00033  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00034  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00035  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00036  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00037  * SUCH DAMAGE.
00038  *
00039  *      @(#)if_fddi.h   8.1 (Berkeley) 6/10/93
00040  * $Id: if_fddi.h,v 1.3.4.1 1997/02/08 15:13:45 joerg Exp $
00041  */
00042
00043 #ifndef __NETINET_IF_FDDI_H
00044 #define __NETINET_IF_FDDI_H
00045
00046 #include <sys/packon.h>
00047
00048 /*
00049  * Structure of an 100Mb/s FDDI header.
00050  */
00051 struct  fddi_header {
00052         u_char  fddi_fc;
00053         u_char  fddi_dhost[6];
00054         u_char  fddi_shost[6];
00055 };
00056
00057 #include <sys/packoff.h>
00058
00059 #define FDDIIPMTU               4352
00060 #define FDDIMTU                 4470
00061 #define FDDIMIN                 3
00062
00063 #define FDDIFC_C                0x80    /* 0b10000000 */
00064 #define FDDIFC_L                0x40    /* 0b01000000 */
00065 #define FDDIFC_F                0x30    /* 0b00110000 */
00066 #define FDDIFC_Z                0x0F    /* 0b00001111 */
00067
00068 #define FDDIFC_LLC_ASYNC        0x50
00069 #define FDDIFC_LLC_PRIO0        0
00070 #define FDDIFC_LLC_PRIO1        1
00071 #define FDDIFC_LLC_PRIO2        2
00072 #define FDDIFC_LLC_PRIO3        3
00073 #define FDDIFC_LLC_PRIO4        4
00074 #define FDDIFC_LLC_PRIO5        5
00075 #define FDDIFC_LLC_PRIO6        6
00076 #define FDDIFC_LLC_PRIO7        7
00077 #define FDDIFC_LLC_SYNC         0xd0
00078 #define FDDIFC_SMT              0x40
00079
00080 #endif
Generated on Wed Jan 25 15:42:32 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/netinet/IGMP.H Source File

inc/netinet/IGMP.H

Go to the documentation of this file.
00001
00005 /*
00006  * Copyright (c) 1988 Stephen Deering.
00007  * Copyright (c) 1992, 1993
00008  *      The Regents of the University of California.  All rights reserved.
00009  *
00010  * This code is derived from software contributed to Berkeley by
00011  * Stephen Deering of Stanford University.
00012  *
00013  * Redistribution and use in source and binary forms, with or without
00014  * modification, are permitted provided that the following conditions
00015  * are met:
00016  * 1. Redistributions of source code must retain the above copyright
00017  *    notice, this list of conditions and the following disclaimer.
00018  * 2. Redistributions in binary form must reproduce the above copyright
00019  *    notice, this list of conditions and the following disclaimer in the
00020  *    documentation and/or other materials provided with the distribution.
00021  * 3. All advertising materials mentioning features or use of this software
00022  *    must display the following acknowledgement:
00023  *      This product includes software developed by the University of
00024  *      California, Berkeley and its contributors.
00025  * 4. Neither the name of the University nor the names of its contributors
00026  *    may be used to endorse or promote products derived from this software
00027  *    without specific prior written permission.
00028  *
00029  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
00030  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00031  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00032  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
00033  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00034  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00035  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00036  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00037  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00038  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00039  * SUCH DAMAGE.
00040  *
00041  *      @(#)igmp.h      8.1 (Berkeley) 6/10/93
00042  *      $Id: igmp.h,v 1.7 1996/03/14 16:59:17 fenner Exp $
00043  */
00044
00045 #ifndef __NETINET_IGMP_H
00046 #define __NETINET_IGMP_H
00047
00048 /*
00049  * Internet Group Management Protocol (IGMP) definitions.
00050  *
00051  * Written by Steve Deering, Stanford, May 1988.
00052  *
00053  * MULTICAST Revision: 3.5.1.2
00054  */
00055
00056 /*
00057  * IGMP packet format.
00058  */
00059
00060 #include <sys/packon.h>
00061
00062 struct igmp {
00063         u_char          igmp_type;      /* version & type of IGMP message  */
00064         u_char          igmp_code;      /* subtype for routing msgs        */
00065         u_short         igmp_cksum;     /* IP-style checksum               */
00066         struct in_addr  igmp_group;     /* group address being reported    */
00067 };                                      /*  (zero for queries)             */
00068
00069 #include <sys/packoff.h>
00070
00071 #define IGMP_MINLEN                  8
00072
00073 /*
00074  * Message types, including version number.
00075  */
00076 #define IGMP_MEMBERSHIP_QUERY           0x11    /* membership query         */
00077 #define IGMP_V1_MEMBERSHIP_REPORT       0x12    /* Ver. 1 membership report */
00078 #define IGMP_V2_MEMBERSHIP_REPORT       0x16    /* Ver. 2 membership report */
00079 #define IGMP_V2_LEAVE_GROUP             0x17    /* Leave-group message      */
00080
00081 #define IGMP_DVMRP                      0x13    /* DVMRP routing message    */
00082 #define IGMP_PIM                        0x14    /* PIM routing message      */
00083
00084 #define IGMP_MTRACE_RESP                0x1e  /* traceroute resp.(to sender)*/
00085 #define IGMP_MTRACE                     0x1f  /* mcast traceroute messages  */
00086
00087 #define IGMP_MAX_HOST_REPORT_DELAY   10    /* max delay for response to     */
00088                                            /*  query (in seconds) according */
00089                                            /*  to RFC1112                   */
00090
00091
00092 #define IGMP_TIMER_SCALE     10         /* denotes that the igmp code field */
00093                                         /* specifies time in 10th of seconds*/
00094
00095 /*
00096  * The following four defininitions are for backwards compatibility.
00097  * They should be removed as soon as all applications are updated to
00098  * use the new constant names.
00099  */
00100 #define IGMP_HOST_MEMBERSHIP_QUERY      IGMP_MEMBERSHIP_QUERY
00101 #define IGMP_HOST_MEMBERSHIP_REPORT     IGMP_V1_MEMBERSHIP_REPORT
00102 #define IGMP_HOST_NEW_MEMBERSHIP_REPORT IGMP_V2_MEMBERSHIP_REPORT
00103 #define IGMP_HOST_LEAVE_MESSAGE         IGMP_V2_LEAVE_GROUP
00104
00105 #endif
Generated on Wed Jan 25 15:42:33 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/netinet/IGMP_VAR.H Source File

inc/netinet/IGMP_VAR.H

Go to the documentation of this file.
00001
00005 /*
00006  * Copyright (c) 1988 Stephen Deering.
00007  * Copyright (c) 1992, 1993
00008  *      The Regents of the University of California.  All rights reserved.
00009  *
00010  * This code is derived from software contributed to Berkeley by
00011  * Stephen Deering of Stanford University.
00012  *
00013  * Redistribution and use in source and binary forms, with or without
00014  * modification, are permitted provided that the following conditions
00015  * are met:
00016  * 1. Redistributions of source code must retain the above copyright
00017  *    notice, this list of conditions and the following disclaimer.
00018  * 2. Redistributions in binary form must reproduce the above copyright
00019  *    notice, this list of conditions and the following disclaimer in the
00020  *    documentation and/or other materials provided with the distribution.
00021  * 3. All advertising materials mentioning features or use of this software
00022  *    must display the following acknowledgement:
00023  *      This product includes software developed by the University of
00024  *      California, Berkeley and its contributors.
00025  * 4. Neither the name of the University nor the names of its contributors
00026  *    may be used to endorse or promote products derived from this software
00027  *    without specific prior written permission.
00028  *
00029  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
00030  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00031  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00032  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
00033  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00034  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00035  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00036  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00037  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00038  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00039  * SUCH DAMAGE.
00040  *
00041  *      @(#)igmp_var.h  8.1 (Berkeley) 7/19/93
00042  * $Id: igmp_var.h,v 1.9 1996/03/14 16:59:18 fenner Exp $
00043  */
00044
00045 #ifndef __NETINET_IGMP_VAR_H
00046 #define __NETINET_IGMP_VAR_H
00047
00048 /*
00049  * Internet Group Management Protocol (IGMP),
00050  * implementation-specific definitions.
00051  *
00052  * Written by Steve Deering, Stanford, May 1988.
00053  *
00054  * MULTICAST Revision: 3.5.1.3
00055  */
00056
00057 struct igmpstat {
00058         u_int   igps_rcv_total;         /* total IGMP messages received */
00059         u_int   igps_rcv_tooshort;      /* received with too few bytes */
00060         u_int   igps_rcv_badsum;        /* received with bad checksum */
00061         u_int   igps_rcv_queries;       /* received membership queries */
00062         u_int   igps_rcv_badqueries;    /* received invalid queries */
00063         u_int   igps_rcv_reports;       /* received membership reports */
00064         u_int   igps_rcv_badreports;    /* received invalid reports */
00065         u_int   igps_rcv_ourreports;    /* received reports for our groups */
00066         u_int   igps_snd_reports;       /* sent membership reports */
00067 };
00068
00069 /*
00070  * Names for IGMP sysctl objects
00071  */
00072 #define IGMPCTL_STATS           1       /* statistics (read-only) */
00073 #define IGMPCTL_MAXID           2
00074
00075 #define IGMPCTL_NAMES { \
00076         { 0, 0 }, \
00077         { "stats", CTLTYPE_STRUCT }, \
00078 }
00079
00080 #endif
00081
00082
Generated on Wed Jan 25 15:42:33 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/netinet/IN.H Source File

inc/netinet/IN.H

Go to the documentation of this file.
00001
00005 /*
00006  * Copyright (c) 1982, 1986, 1990, 1993
00007  *      The Regents of the University of California.  All rights reserved.
00008  *
00009  * Redistribution and use in source and binary forms, with or without
00010  * modification, are permitted provided that the following conditions
00011  * are met:
00012  * 1. Redistributions of source code must retain the above copyright
00013  *    notice, this list of conditions and the following disclaimer.
00014  * 2. Redistributions in binary form must reproduce the above copyright
00015  *    notice, this list of conditions and the following disclaimer in the
00016  *    documentation and/or other materials provided with the distribution.
00017  * 3. All advertising materials mentioning features or use of this software
00018  *    must display the following acknowledgement:
00019  *      This product includes software developed by the University of
00020  *      California, Berkeley and its contributors.
00021  * 4. Neither the name of the University nor the names of its contributors
00022  *    may be used to endorse or promote products derived from this software
00023  *    without specific prior written permission.
00024  *
00025  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
00026  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00027  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00028  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
00029  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00030  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00031  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00032  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00033  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00034  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00035  * SUCH DAMAGE.
00036  *
00037  *      @(#)in.h        8.3 (Berkeley) 1/3/94
00038  * $Id: in.h,v 1.22.2.1 1996/11/11 23:40:37 phk Exp $
00039  */
00040
00041 #ifndef __NETINET_IN_H
00042 #define __NETINET_IN_H
00043
00044 #ifndef __SYS_SOCKET_H
00045 #include <sys/socket.h>
00046 #endif
00047
00048 /*
00049  * Constants and structures defined by the internet system,
00050  * Per RFC 790, September 1981, and numerous additions.
00051  */
00052
00053 /*
00054  * Protocols
00055  */
00056 #define IPPROTO_IP              0               /* dummy for IP */
00057 #define IPPROTO_ICMP            1               /* control message protocol */
00058 #define IPPROTO_IGMP            2               /* group mgmt protocol */
00059 #define IPPROTO_GGP             3               /* gateway^2 (deprecated) */
00060 #define IPPROTO_IPIP            4               /* IP encapsulation in IP */
00061 #define IPPROTO_TCP             6               /* tcp */
00062 #define IPPROTO_EGP             8               /* exterior gateway protocol */
00063 #define IPPROTO_IGRP            9               /* interior gw routing protocol */
00064 #define IPPROTO_PUP             12              /* pup */
00065 #define IPPROTO_UDP             17              /* user datagram protocol */
00066 #define IPPROTO_IDP             22              /* xns idp */
00067 #define IPPROTO_TP              29              /* tp-4 w/ class negotiation */
00068 #define IPPROTO_XTP             36              /* eXpress Transfer Protocol */
00069 #define IPPROTO_RSVP            46              /* resource reservation */
00070 #define IPPROTO_ESP             50
00071 #define IPPROTO_AH              51              /* authenticate header */
00072 #define IPPROTO_ICMPV6          58              /* ICMP v6 */
00073 #define IPPROTO_NONE            59
00074 #define IPPROTO_EON             80              /* ISO cnlp */
00075 #define IPPROTO_ENCAP           98              /* encapsulation header */
00076 #define IPPROTO_PIM             103
00077 #define IPPROTO_VRRP            112
00078 #define IPPROTO_SCTP            132
00079
00080 #define IPPROTO_DIVERT          254             /* divert pseudo-protocol */
00081 #define IPPROTO_RAW             255             /* raw IP packet */
00082 #define IPPROTO_MAX             256
00083
00084
00085 /*
00086  * Local port number conventions:
00087  *
00088  * When a user does a bind(2) or connect(2) with a port number of zero,
00089  * a non-conflicting local port address is chosen.
00090  * The default range is IPPORT_RESERVED through
00091  * IPPORT_USERRESERVED, although that is settable by sysctl.
00092  *
00093  * A user may set the IPPROTO_IP option IP_PORTRANGE to change this
00094  * default assignment range.
00095  *
00096  * The value IP_PORTRANGE_DEFAULT causes the default behavior.
00097  *
00098  * The value IP_PORTRANGE_HIGH changes the range of candidate port numbers
00099  * into the "high" range.  These are reserved for client outbound connections
00100  * which do not want to be filtered by any firewalls.
00101  *
00102  * The value IP_PORTRANGE_LOW changes the range to the "low" are
00103  * that is (by convention) restricted to privileged processes.  This
00104  * convention is based on "vouchsafe" principles only.  It is only secure
00105  * if you trust the remote host to restrict these ports.
00106  *
00107  * The default range of ports and the high range can be changed by
00108  * sysctl(3).  (net.inet.ip.port{hi,low}{first,last}_auto)
00109  *
00110  * Changing those values has bad security implications if you are
00111  * using a a stateless firewall that is allowing packets outside of that
00112  * range in order to allow transparent outgoing connections.
00113  *
00114  * Such a firewall configuration will generally depend on the use of these
00115  * default values.  If you change them, you may find your Security
00116  * Administrator looking for you with a heavy object.
00117  */
00118
00119 /*
00120  * Ports < IPPORT_RESERVED are reserved for
00121  * privileged processes (e.g. root).         (IP_PORTRANGE_LOW)
00122  * Ports > IPPORT_USERRESERVED are reserved
00123  * for servers, not necessarily privileged.  (IP_PORTRANGE_DEFAULT)
00124  */
00125 #define IPPORT_RESERVED         1024
00126 #define IPPORT_USERRESERVED     5000
00127
00128 /*
00129  * Default local port range to use by setting IP_PORTRANGE_HIGH
00130  */
00131 #define IPPORT_HIFIRSTAUTO      40000
00132 #define IPPORT_HILASTAUTO       44999
00133
00134 /*
00135  * Scanning for a free reserved port return a value below IPPORT_RESERVED,
00136  * but higher than IPPORT_RESERVEDSTART.  Traditionally the start value was
00137  * 512, but that conflicts with some well-known-services that firewalls may
00138  * have a fit if we use.
00139  */
00140 #define IPPORT_RESERVEDSTART    600
00141
00142
00143 /*
00144  * Internet address (a structure for historical reasons)
00145  */
00146 struct in_addr {
00147        u_long s_addr;
00148      };
00149 /*
00150  *  For IPv6 from RFC2133
00151  */
00152 struct in6_addr {
00153        u_int8_t  s6_addr[16];
00154      };
00155
00156 /*
00157  * Definitions of bits in internet address integers.
00158  * On subnets, the decomposition of addresses to host and net parts
00159  * is done according to subnet mask, not the masks here.
00160  */
00161 #define IN_CLASSA(i)            (((long)(i) & 0x80000000) == 0)
00162 #define IN_CLASSA_NET           0xff000000
00163 #define IN_CLASSA_NSHIFT        24
00164 #define IN_CLASSA_HOST          0x00ffffff
00165 #define IN_CLASSA_MAX           128
00166
00167 #define IN_CLASSB(i)            (((long)(i) & 0xC0000000) == 0x80000000)
00168 #define IN_CLASSB_NET           0xffff0000
00169 #define IN_CLASSB_NSHIFT        16
00170 #define IN_CLASSB_HOST          0x0000ffff
00171 #define IN_CLASSB_MAX           65536
00172
00173 #define IN_CLASSC(i)            (((long)(i) & 0xE0000000) == 0xC0000000)
00174 #define IN_CLASSC_NET           0xffffff00
00175 #define IN_CLASSC_NSHIFT        8
00176 #define IN_CLASSC_HOST          0x000000ff
00177
00178 #define IN_CLASSD(i)            (((long)(i) & 0xF0000000) == 0xE0000000)
00179 #define IN_CLASSD_NET           0xf0000000      /* These ones aren't really */
00180 #define IN_CLASSD_NSHIFT        28              /* net and host fields, but */
00181 #define IN_CLASSD_HOST          0x0fffffff      /* routing needn't know.    */
00182 #define IN_MULTICAST(i)         IN_CLASSD(i)
00183
00184 #define IN_EXPERIMENTAL(i)      (((long)(i) & 0xF0000000) == 0xF0000000)
00185 #define IN_BADCLASS(i)          (((long)(i) & 0xF0000000) == 0xF0000000)
00186
00187 #define INADDR_ANY              (u_long)0x00000000
00188 #define INADDR_BROADCAST        (u_long)0xFFFFFFFF      /* must be masked */
00189 #define INADDR_LOOPBACK         (u_long)0x7F000001      /* 127.0.0.1 */
00190 #define INADDR_NONE             0xFFFFFFFF              /* -1 return */
00191
00192 #define INADDR_UNSPEC_GROUP     (u_long)0xE0000000      /* 224.0.0.0 */
00193 #define INADDR_ALLHOSTS_GROUP   (u_long)0xE0000001      /* 224.0.0.1 */
00194 #define INADDR_ALLRTRS_GROUP    (u_long)0xE0000002      /* 224.0.0.2 */
00195 #define INADDR_MAX_LOCAL_GROUP  (u_long)0xE00000FF      /* 224.0.0.255 */
00196
00197 #define IN_LOOPBACKNET          127                     /* official! */
00198
00199 W32_DATA const struct in6_addr in6addr_any;             /* :: */
00200 W32_DATA const struct in6_addr in6addr_loopback;        /* ::1 */
00201
00202 #define IN6ADDR_ANY_INIT      { { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } } }
00203 #define IN6ADDR_LOOPBACK_INIT { { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 } } }
00204
00205 #define INET_ADDRSTRLEN       16
00206 #define INET6_ADDRSTRLEN      46
00207
00208
00209 /*
00210  * Socket address, internet style.
00211  */
00212 struct sockaddr_in {
00213        u_short        sin_family;
00214        u_short        sin_port;
00215        struct in_addr sin_addr;
00216        char           sin_zero[8];
00217      };
00218
00219 struct sockaddr_in6 {
00220        u_int16_t       sin6_family;
00221        u_int16_t       sin6_port;
00222        u_int32_t       sin6_flowinfo;
00223        struct in6_addr sin6_addr;
00224        u_int32_t       sin6_scope_id; /* IPv6 scope-id */
00225      };
00226
00227 /*
00228  * Stolen from winsock2.h (hope this is portable)
00229  * Portable IPv6/IPv4 version of sockaddr.
00230  * Uses padding to force 8 byte alignment
00231  * and maximum size of 128 bytes
00232  */
00233 struct sockaddr_storage {
00234        u_short  ss_family;
00235        u_short  ss_len;        /* !! added for BSD progs, gv Nov-2003 */
00236        char   __ss_pad1[6];              /* pad to 8 */
00237        long   __ss_align1, __ssalign2;   /* force alignment */
00238        char   __ss_pad2[110];            /* pad to 128 */
00239      };
00240
00241
00242 /* IPv6 multicast request. */
00243 struct ipv6_mreq {
00244        /* IPv6 multicast address of group */
00245        struct in6_addr ipv6mr_multiaddr;
00246
00247        /* local interface */
00248        unsigned long ipv6mr_interface;
00249      };
00250
00251 /*
00252  * Structure used to describe IP options.
00253  * Used to store options internally, to pass them to a process,
00254  * or to restore options retrieved earlier.
00255  * The ip_dst is used for the first-hop gateway when using a source route
00256  * (this gets put into the header proper).
00257  */
00258 struct ip_opts {
00259        struct in_addr ip_dst;     /* first hop, 0 w/o src rt */
00260        char   IP_opts[40];        /* actually variable in size */
00261      };
00262
00263 /*
00264  * Options for use with [gs]etsockopt at the IP level.
00265  * First word of comment is data type; bool is stored in int.
00266  */
00267 #define IP_OPTIONS              1    /* buf/ip_opts; set/get IP options */
00268 #define IP_HDRINCL              2    /* int; header is included with data */
00269 #define IP_TOS                  3    /* int; IP type of service and preced. */
00270 #define IP_TTL                  4    /* int; IP time to live */
00271 #define IP_RECVOPTS             5    /* bool; receive all IP opts w/dgram */
00272 #define IP_RECVRETOPTS          6    /* bool; receive IP opts for response */
00273 #define IP_RECVDSTADDR          7    /* bool; receive IP dst addr w/dgram */
00274 #define IP_RETOPTS              8    /* ip_opts; set/get IP options */
00275 #define IP_MULTICAST_IF         9    /* u_char; set/get IP multicast i/f  */
00276 #define IP_MULTICAST_TTL        10   /* u_char; set/get IP multicast ttl */
00277 #define IP_MULTICAST_LOOP       11   /* u_char; set/get IP multicast loopback */
00278 #define IP_ADD_MEMBERSHIP       12   /* ip_mreq; add an IP group membership */
00279 #define IP_DROP_MEMBERSHIP      13   /* ip_mreq; drop an IP group membership */
00280 #define IP_MULTICAST_VIF        14   /* set/get IP mcast virt. iface */
00281 #define IP_RSVP_ON              15   /* enable RSVP in kernel */
00282 #define IP_RSVP_OFF             16   /* disable RSVP in kernel */
00283 #define IP_RSVP_VIF_ON          17   /* set RSVP per-vif socket */
00284 #define IP_RSVP_VIF_OFF         18   /* unset RSVP per-vif socket */
00285 #define IP_PORTRANGE            19   /* int; range to choose for unspec port */
00286 #define IP_RECVIF               20   /* bool; receive reception if w/dgram */
00287
00288 #define IP_FW_ADD               50   /* add a firewall rule to chain */
00289 #define IP_FW_DEL               51   /* delete a firewall rule from chain */
00290 #define IP_FW_FLUSH             52   /* flush firewall rule chain */
00291 #define IP_FW_ZERO              53   /* clear single/all firewall counter(s) */
00292 #define IP_FW_GET               54   /* get entire firewall rule chain */
00293 #define IP_NAT                  55   /* set/get NAT opts */
00294
00295 /*
00296  * Defaults and limits for options
00297  */
00298 #define IP_DEFAULT_MULTICAST_TTL  1     /* normally limit m'casts to 1 hop  */
00299 #define IP_DEFAULT_MULTICAST_LOOP 1     /* normally hear sends if a member  */
00300 #define IP_MAX_MEMBERSHIPS      20      /* per socket */
00301
00302 /*
00303  * Argument structure for IP_ADD_MEMBERSHIP and IP_DROP_MEMBERSHIP.
00304  */
00305 struct ip_mreq {
00306         struct  in_addr imr_multiaddr;  /* IP multicast address of group */
00307         struct  in_addr imr_interface;  /* local IP address of interface */
00308 };
00309
00310 /*
00311  * Argument for IP_PORTRANGE:
00312  * - which range to search when port is unspecified at bind() or connect()
00313  */
00314 #define IP_PORTRANGE_DEFAULT    0       /* default range */
00315 #define IP_PORTRANGE_HIGH       1       /* "high" - request firewall bypass */
00316 #define IP_PORTRANGE_LOW        2       /* "low" - vouchsafe security */
00317
00318 /*
00319  * Definitions for inet sysctl operations.
00320  *
00321  * Third level is protocol number.
00322  * Fourth level is desired variable within that protocol.
00323  */
00324 #define IPPROTO_MAXID   (IPPROTO_IDP + 1)       /* don't list to IPPROTO_MAX */
00325
00326 #define CTL_IPPROTO_NAMES { \
00327         { "ip", CTLTYPE_NODE }, \
00328         { "icmp", CTLTYPE_NODE }, \
00329         { "igmp", CTLTYPE_NODE }, \
00330         { "ggp", CTLTYPE_NODE }, \
00331         { 0, 0 }, \
00332         { 0, 0 }, \
00333         { "tcp", CTLTYPE_NODE }, \
00334         { 0, 0 }, \
00335         { "egp", CTLTYPE_NODE }, \
00336         { 0, 0 }, \
00337         { 0, 0 }, \
00338         { 0, 0 }, \
00339         { "pup", CTLTYPE_NODE }, \
00340         { 0, 0 }, \
00341         { 0, 0 }, \
00342         { 0, 0 }, \
00343         { 0, 0 }, \
00344         { "udp", CTLTYPE_NODE }, \
00345         { 0, 0 }, \
00346         { 0, 0 }, \
00347         { 0, 0 }, \
00348         { 0, 0 }, \
00349         { "idp", CTLTYPE_NODE }, \
00350 }
00351
00352 /*
00353  * Names for IP sysctl objects
00354  */
00355 #define IPCTL_FORWARDING        1       /* act as router */
00356 #define IPCTL_SENDREDIRECTS     2       /* may send redirects when forwarding */
00357 #define IPCTL_DEFTTL            3       /* default TTL */
00358 #define IPCTL_DEFMTU            4       /* default MTU */
00359 #define IPCTL_RTEXPIRE          5       /* cloned route expiration time */
00360 #define IPCTL_RTMINEXPIRE       6       /* min value for expiration time */
00361 #define IPCTL_RTMAXCACHE        7       /* trigger level for dynamic expire */
00362 #define IPCTL_SOURCEROUTE       8       /* may perform source routes */
00363 #define IPCTL_DIRECTEDBROADCAST 9       /* may re-broadcast received packets */
00364 #define IPCTL_INTRQMAXLEN       10      /* max length of netisr queue */
00365 #define IPCTL_INTRQDROPS        11      /* number of netisr q drops */
00366 #define IPCTL_MAXID             12
00367
00368 #define IPCTL_NAMES { \
00369         { 0, 0 }, \
00370         { "forwarding", CTLTYPE_INT }, \
00371         { "redirect", CTLTYPE_INT }, \
00372         { "ttl", CTLTYPE_INT }, \
00373         { "mtu", CTLTYPE_INT }, \
00374         { "rtexpire", CTLTYPE_INT }, \
00375         { "rtminexpire", CTLTYPE_INT }, \
00376         { "rtmaxcache", CTLTYPE_INT }, \
00377         { "sourceroute", CTLTYPE_INT }, \
00378         { "directed-broadcast", CTLTYPE_INT }, \
00379         { "intr-queue-maxlen", CTLTYPE_INT }, \
00380         { "intr-queue-drops", CTLTYPE_INT }, \
00381 }
00382
00383
00384 /*
00385  * IPv6 address macros
00386  */
00387 #define IN6_IS_ADDR_UNSPECIFIED(a)        \
00388            (((u_int32_t*)(a))[0] == 0   \
00389          && ((u_int32_t*)(a))[1] == 0   \
00390          && ((u_int32_t*)(a))[2] == 0   \
00391          && ((u_int32_t*)(a))[3] == 0)
00392
00393 #define IN6_IS_ADDR_LOOPBACK(a)           \
00394            (((u_int32_t*)(a))[0] == 0   \
00395          && ((u_int32_t*)(a))[1] == 0   \
00396          && ((u_int32_t*)(a))[2] == 0   \
00397          && ((u_int32_t*)(a))[3] == htonl (1))
00398
00399 #define IN6_IS_ADDR_MULTICAST(a) (((u_int8_t*) (a))[0] == 0xff)
00400
00401 #define IN6_IS_ADDR_LINKLOCAL(a) \
00402         ((((u_int32_t*)(a))[0] & htonl(0xffc00000)) == htonl(0xfe800000))
00403
00404 #define IN6_IS_ADDR_SITELOCAL(a) \
00405         ((((u_int32_t*)(a))[0] & htonl(0xffc00000)) == htonl(0xfec00000))
00406
00407 #define IN6_IS_ADDR_V4MAPPED(a)         \
00408            ((((u_int32_t*)(a))[0] == 0) \
00409          && (((u_int32_t*)(a))[1] == 0) \
00410          && (((u_int32_t*)(a))[2] == htonl(0xffff)))
00411
00412 #define IN6_IS_ADDR_V4COMPAT(a)         \
00413            ((((u_int32_t*)(a))[0] == 0) \
00414          && (((u_int32_t*)(a))[1] == 0) \
00415          && (((u_int32_t*)(a))[2] == 0) \
00416          && (ntohl(((u_int32_t*)(a))[3]) > 1))
00417
00418 #define IN6_ARE_ADDR_EQUAL(a,b) \
00419            ((((u_int32_t*)(a))[0] == ((u_int32_t*)(b))[0])  \
00420          && (((u_int32_t*)(a))[1] == ((u_int32_t*)(b))[1])  \
00421          && (((u_int32_t*)(a))[2] == ((u_int32_t*)(b))[2])  \
00422          && (((u_int32_t*)(a))[3] == ((u_int32_t*)(b))[3]))
00423
00424 #define IN6_IS_ADDR_MC_NODELOCAL(a) \
00425         (IN6_IS_ADDR_MULTICAST(a) && ((((u_int8_t*)(a))[1] & 0xf) == 0x1))
00426
00427 #define IN6_IS_ADDR_MC_LINKLOCAL(a) \
00428         (IN6_IS_ADDR_MULTICAST(a) && ((((u_int8_t*)(a))[1] & 0xf) == 0x2))
00429
00430 #define IN6_IS_ADDR_MC_SITELOCAL(a) \
00431         (IN6_IS_ADDR_MULTICAST(a) && ((((u_int8_t*)(a))[1] & 0xf) == 0x5))
00432
00433 #define IN6_IS_ADDR_MC_ORGLOCAL(a)  \
00434         (IN6_IS_ADDR_MULTICAST(a) && ((((u_int8_t*)(a))[1] & 0xf) == 0x8))
00435
00436 #define IN6_IS_ADDR_MC_GLOBAL(a)    \
00437         (IN6_IS_ADDR_MULTICAST(a) && ((((u_int8_t*)(a))[1] & 0xf) == 0xe))
00438
00439 #endif /* __NETINET_IN_H */
00440
Generated on Wed Jan 25 15:42:33 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/netinet/IN_PCB.H Source File

inc/netinet/IN_PCB.H

Go to the documentation of this file.
00001
00005 /*
00006  * Copyright (c) 1982, 1986, 1990, 1993
00007  *      The Regents of the University of California.  All rights reserved.
00008  *
00009  * Redistribution and use in source and binary forms, with or without
00010  * modification, are permitted provided that the following conditions
00011  * are met:
00012  * 1. Redistributions of source code must retain the above copyright
00013  *    notice, this list of conditions and the following disclaimer.
00014  * 2. Redistributions in binary form must reproduce the above copyright
00015  *    notice, this list of conditions and the following disclaimer in the
00016  *    documentation and/or other materials provided with the distribution.
00017  * 3. All advertising materials mentioning features or use of this software
00018  *    must display the following acknowledgement:
00019  *      This product includes software developed by the University of
00020  *      California, Berkeley and its contributors.
00021  * 4. Neither the name of the University nor the names of its contributors
00022  *    may be used to endorse or promote products derived from this software
00023  *    without specific prior written permission.
00024  *
00025  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
00026  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00027  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00028  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
00029  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00030  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00031  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00032  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00033  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00034  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00035  * SUCH DAMAGE.
00036  *
00037  *      @(#)in_pcb.h    8.1 (Berkeley) 6/10/93
00038  * $Id: in_pcb.h,v 1.14.2.2 1997/03/03 09:24:37 davidg Exp $
00039  */
00040
00041 #ifndef __NETINET_IN_PCB_H
00042 #define __NETINET_IN_PCB_H
00043
00044 #include <sys/queue.h>
00045
00046 /*
00047  * Common structure pcb for internet protocol implementation.
00048  * Here are stored pointers to local and foreign host table
00049  * entries, local and foreign socket numbers, and pointers
00050  * up (to a socket structure) and down (to a protocol-specific)
00051  * control block.
00052  */
00053 LIST_HEAD(inpcbhead, inpcb);
00054
00055 struct inpcb {
00056         LIST_ENTRY(inpcb) inp_list;    /* list for all PCBs of this proto */
00057         LIST_ENTRY(inpcb) inp_hash;    /* hash list */
00058         struct  inpcbinfo *inp_pcbinfo;
00059         struct  in_addr inp_faddr;      /* foreign host table entry */
00060         u_short inp_fport;              /* foreign port */
00061         struct  in_addr inp_laddr;      /* local host table entry */
00062         u_short inp_lport;              /* local port */
00063         struct  socket *inp_socket;     /* back pointer to socket */
00064         caddr_t inp_ppcb;               /* pointer to per-protocol pcb */
00065         struct  route inp_route;        /* placeholder for routing entry */
00066         int     inp_flags;              /* generic IP/datagram flags */
00067         struct  ip inp_ip;              /* header prototype; should have more */
00068         struct  mbuf *inp_options;      /* IP options */
00069         struct  ip_moptions *inp_moptions; /* IP multicast options */
00070 };
00071
00072 struct inpcbinfo {
00073         struct inpcbhead *listhead;
00074         struct inpcbhead *hashbase;
00075         unsigned long hashmask;
00076         unsigned short lastport;
00077         unsigned short lastlow;
00078         unsigned short lasthi;
00079 };
00080
00081 #define INP_PCBHASH(faddr, lport, fport, mask) \
00082         (((faddr) ^ ((faddr) >> 16) ^ (lport) ^ (fport)) & (mask))
00083
00084 /* flags in inp_flags: */
00085 #define INP_RECVOPTS            0x01    /* receive incoming IP options */
00086 #define INP_RECVRETOPTS         0x02    /* receive IP options for reply */
00087 #define INP_RECVDSTADDR         0x04    /* receive IP dst address */
00088 #define INP_HDRINCL             0x08    /* user supplies entire IP header */
00089 #define INP_HIGHPORT            0x10    /* user wants "high" port binding */
00090 #define INP_LOWPORT             0x20    /* user wants "low" port binding */
00091 #define INP_ANONPORT            0x40    /* port chosen for user */
00092 #define INP_RECVIF              0x80    /* receive incoming interface */
00093 #define INP_CONTROLOPTS         (INP_RECVOPTS|INP_RECVRETOPTS|INP_RECVDSTADDR|\
00094                                         INP_RECVIF)
00095
00096 #define INPLOOKUP_WILDCARD      1
00097
00098 #define sotoinpcb(so)   ((struct inpcb *)(so)->so_pcb)
00099
00100 #endif
Generated on Wed Jan 25 15:42:33 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/netinet/IN_SYSTM.H Source File

inc/netinet/IN_SYSTM.H

Go to the documentation of this file.
00001
00005 /*
00006  * Copyright (c) 1982, 1986, 1993
00007  *      The Regents of the University of California.  All rights reserved.
00008  *
00009  * Redistribution and use in source and binary forms, with or without
00010  * modification, are permitted provided that the following conditions
00011  * are met:
00012  * 1. Redistributions of source code must retain the above copyright
00013  *    notice, this list of conditions and the following disclaimer.
00014  * 2. Redistributions in binary form must reproduce the above copyright
00015  *    notice, this list of conditions and the following disclaimer in the
00016  *    documentation and/or other materials provided with the distribution.
00017  * 3. All advertising materials mentioning features or use of this software
00018  *    must display the following acknowledgement:
00019  *      This product includes software developed by the University of
00020  *      California, Berkeley and its contributors.
00021  * 4. Neither the name of the University nor the names of its contributors
00022  *    may be used to endorse or promote products derived from this software
00023  *    without specific prior written permission.
00024  *
00025  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
00026  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00027  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00028  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
00029  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00030  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00031  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00032  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00033  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00034  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00035  * SUCH DAMAGE.
00036  *
00037  *      @(#)in_systm.h  8.1 (Berkeley) 6/10/93
00038  * $Id: in_systm.h,v 1.3 1994/08/21 05:27:29 paul Exp $
00039  */
00040
00041 #ifndef __NETINET_IN_SYSTM_H
00042 #define __NETINET_IN_SYSTM_H
00043
00044 /*
00045  * Miscellaneous internetwork
00046  * definitions for kernel.
00047  */
00048
00049 /*
00050  * Network types.
00051  *
00052  * Internally the system keeps counters in the headers with the bytes
00053  * swapped so that VAX instructions will work on them.  It reverses
00054  * the bytes before transmission at each protocol level.  The n_ types
00055  * represent the types with the bytes in ``high-ender'' order.
00056  */
00057 typedef u_short n_short;                /* short as received from the net */
00058 typedef u_long  n_long;                 /* long as received from the net */
00059
00060 typedef u_long  n_time;                 /* ms since 00:00 GMT, byte rev */
00061
00062 #endif
Generated on Wed Jan 25 15:42:33 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/netinet/IN_VAR.H Source File

inc/netinet/IN_VAR.H

Go to the documentation of this file.
00001
00005 /*
00006  * Copyright (c) 1985, 1986, 1993
00007  *      The Regents of the University of California.  All rights reserved.
00008  *
00009  * Redistribution and use in source and binary forms, with or without
00010  * modification, are permitted provided that the following conditions
00011  * are met:
00012  * 1. Redistributions of source code must retain the above copyright
00013  *    notice, this list of conditions and the following disclaimer.
00014  * 2. Redistributions in binary form must reproduce the above copyright
00015  *    notice, this list of conditions and the following disclaimer in the
00016  *    documentation and/or other materials provided with the distribution.
00017  * 3. All advertising materials mentioning features or use of this software
00018  *    must display the following acknowledgement:
00019  *      This product includes software developed by the University of
00020  *      California, Berkeley and its contributors.
00021  * 4. Neither the name of the University nor the names of its contributors
00022  *    may be used to endorse or promote products derived from this software
00023  *    without specific prior written permission.
00024  *
00025  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
00026  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00027  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00028  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
00029  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00030  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00031  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00032  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00033  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00034  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00035  * SUCH DAMAGE.
00036  *
00037  *      @(#)in_var.h    8.2 (Berkeley) 1/9/95
00038  *      $Id: in_var.h,v 1.17 1996/03/14 16:59:19 fenner Exp $
00039  */
00040
00041 #ifndef __NETINET_IN_VAR_H
00042 #define __NETINET_IN_VAR_H
00043
00044 #include <sys/queue.h>
00045
00046 /*
00047  * Interface address, Internet version.  One of these structures
00048  * is allocated for each interface with an Internet address.
00049  * The ifaddr structure contains the protocol-independent part
00050  * of the structure and is assumed to be first.
00051  */
00052 struct in_ifaddr {
00053         struct  ifaddr ia_ifa;          /* protocol-independent info */
00054 #define ia_ifp          ia_ifa.ifa_ifp
00055 #define ia_flags        ia_ifa.ifa_flags
00056                                         /* ia_{,sub}net{,mask} in host order */
00057         u_long  ia_net;                 /* network number of interface */
00058         u_long  ia_netmask;             /* mask of net part */
00059         u_long  ia_subnet;              /* subnet number, including net */
00060         u_long  ia_subnetmask;          /* mask of subnet part */
00061         struct  in_addr ia_netbroadcast; /* to recognize net broadcasts */
00062         struct  in_ifaddr *ia_next;     /* next in list of internet addresses */
00063         struct  sockaddr_in ia_addr;    /* reserve space for interface name */
00064         struct  sockaddr_in ia_dstaddr; /* reserve space for broadcast addr */
00065 #define ia_broadaddr    ia_dstaddr
00066         struct  sockaddr_in ia_sockmask; /* reserve space for general netmask */
00067         LIST_HEAD(in_multihead, in_multi) ia_multiaddrs;
00068                                         /* list of multicast addresses */
00069 };
00070
00071 struct  in_aliasreq {
00072         char    ifra_name[IFNAMSIZ];            /* if name, e.g. "en0" */
00073         struct  sockaddr_in ifra_addr;
00074         struct  sockaddr_in ifra_broadaddr;
00075 #define ifra_dstaddr ifra_broadaddr
00076         struct  sockaddr_in ifra_mask;
00077 };
00078 /*
00079  * Given a pointer to an in_ifaddr (ifaddr),
00080  * return a pointer to the addr as a sockaddr_in.
00081  */
00082 #define IA_SIN(ia)    (&(((struct in_ifaddr *)(ia))->ia_addr))
00083 #define IA_DSTSIN(ia) (&(((struct in_ifaddr *)(ia))->ia_dstaddr))
00084
00085 #define IN_LNAOF(in, ifa) \
00086         ((ntohl((in).s_addr) & ~((struct in_ifaddr *)(ifa)->ia_subnetmask))
00087
00088
00089 /*
00090  * This information should be part of the ifnet structure but we don't wish
00091  * to change that - as it might break a number of things
00092  */
00093
00094 struct router_info {
00095         struct ifnet *rti_ifp;
00096         int    rti_type; /* type of router which is querier on this interface */
00097         int    rti_time; /* # of slow timeouts since last old query */
00098         struct router_info *rti_next;
00099 };
00100
00101 /*
00102  * Internet multicast address structure.  There is one of these for each IP
00103  * multicast group to which this host belongs on a given network interface.
00104  * They are kept in a linked list, rooted in the interface's in_ifaddr
00105  * structure.
00106  */
00107 struct in_multi {
00108         LIST_ENTRY(in_multi) inm_entry; /* list glue */
00109         struct  in_addr inm_addr;       /* IP multicast address */
00110         struct  ifnet *inm_ifp;         /* back pointer to ifnet */
00111         struct  in_ifaddr *inm_ia;      /* back pointer to in_ifaddr */
00112         u_int   inm_refcount;           /* no. membership claims by sockets */
00113         u_int   inm_timer;              /* IGMP membership report timer */
00114         u_int   inm_state;              /*  state of the membership */
00115         struct  router_info *inm_rti;   /* router info*/
00116 };
00117
00118 #endif
Generated on Wed Jan 25 15:42:33 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/netinet/IP.H Source File

inc/netinet/IP.H

Go to the documentation of this file.
00001
00005 /*
00006  * Copyright (c) 1982, 1986, 1993
00007  *      The Regents of the University of California.  All rights reserved.
00008  *
00009  * Redistribution and use in source and binary forms, with or without
00010  * modification, are permitted provided that the following conditions
00011  * are met:
00012  * 1. Redistributions of source code must retain the above copyright
00013  *    notice, this list of conditions and the following disclaimer.
00014  * 2. Redistributions in binary form must reproduce the above copyright
00015  *    notice, this list of conditions and the following disclaimer in the
00016  *    documentation and/or other materials provided with the distribution.
00017  * 3. All advertising materials mentioning features or use of this software
00018  *    must display the following acknowledgement:
00019  *      This product includes software developed by the University of
00020  *      California, Berkeley and its contributors.
00021  * 4. Neither the name of the University nor the names of its contributors
00022  *    may be used to endorse or promote products derived from this software
00023  *    without specific prior written permission.
00024  *
00025  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
00026  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00027  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00028  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
00029  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00030  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00031  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00032  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00033  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00034  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00035  * SUCH DAMAGE.
00036  *
00037  *      @(#)ip.h        8.2 (Berkeley) 6/1/94
00038  *      $Id: ip.h,v 1.10 1996/10/23 18:35:49 wollman Exp $
00039  */
00040
00041 #ifndef __NETINET_IP_H
00042 #define __NETINET_IP_H
00043
00044 #ifndef __NETINET_IN_SYSTM_H
00045 #include <netinet/in_systm.h>
00046 #endif
00047
00048 #if defined(__TURBOC__) || defined(__BORLANDC__)
00049 #pragma warn -bbf-   /* "Bitfields must be signed or unsigned int" warning */
00050 #endif
00051
00052 /*
00053  * Definitions for internet protocol version 4.
00054  * Per RFC 791, September 1981.
00055  */
00056 #define IPVERSION       4
00057
00058 #include <sys/packon.h>
00059
00060 /*
00061  * Structure of an internet header, naked of options.
00062  *
00063  * We declare ip_len and ip_off to be short, rather than u_short
00064  * pragmatically since otherwise unsigned comparisons can result
00065  * against negative integers quite easily, and fail in subtle ways.
00066  */
00067 struct ip {
00068 #ifdef _IP_VHL
00069         u_char  ip_vhl;                 /* version << 4 | header length >> 2 */
00070 #else
00071         u_char  ip_hl:4;                /* header length */
00072         u_char  ip_v:4;                 /* version */
00073 #endif
00074         u_char  ip_tos;                 /* type of service */
00075         u_short ip_len;                 /* total length */
00076         u_short ip_id;                  /* identification */
00077         u_short ip_off;                 /* fragment offset field */
00078 #define IP_DF 0x4000                    /* dont fragment flag */
00079 #define IP_MF 0x2000                    /* more fragments flag */
00080 #define IP_OFFMASK 0x1FFF               /* mask for fragmenting bits */
00081         u_char  ip_ttl;                 /* time to live */
00082         u_char  ip_p;                   /* protocol */
00083         u_short ip_sum;                 /* checksum */
00084         struct  in_addr ip_src,ip_dst;  /* source and dest address */
00085 };
00086
00087 #ifdef _IP_VHL
00088 #define IP_MAKE_VHL(v,hl)   ((v) << 4 | (hl))
00089 #define IP_VHL_HL(vhl)      ((vhl) & 0x0f)
00090 #define IP_VHL_V(vhl)       ((vhl) >> 4)
00091 #define IP_VHL_BORING       0x45
00092 #endif
00093
00094 #define IP_MAXPACKET        65535       /* maximum packet size */
00095
00096 /*
00097  * Definitions for IP type of service (ip_tos)
00098  */
00099 #define IPTOS_LOWDELAY          0x10
00100 #define IPTOS_THROUGHPUT        0x08
00101 #define IPTOS_RELIABILITY       0x04
00102 #define IPTOS_MINCOST           0x02
00103
00104 /*
00105  * Definitions for IP precedence (also in ip_tos) (hopefully unused)
00106  */
00107 #define IPTOS_PREC_NETCONTROL           0xe0
00108 #define IPTOS_PREC_INTERNETCONTROL      0xc0
00109 #define IPTOS_PREC_CRITIC_ECP           0xa0
00110 #define IPTOS_PREC_FLASHOVERRIDE        0x80
00111 #define IPTOS_PREC_FLASH                0x60
00112 #define IPTOS_PREC_IMMEDIATE            0x40
00113 #define IPTOS_PREC_PRIORITY             0x20
00114 #define IPTOS_PREC_ROUTINE              0x00
00115
00116 /*
00117  * Definitions for options.
00118  */
00119 #define IPOPT_COPIED(o)         ((o)&0x80)
00120 #define IPOPT_CLASS(o)          ((o)&0x60)
00121 #define IPOPT_NUMBER(o)         ((o)&0x1f)
00122
00123 #define IPOPT_CONTROL           0x00
00124 #define IPOPT_RESERVED1         0x20
00125 #define IPOPT_DEBMEAS           0x40
00126 #define IPOPT_RESERVED2         0x60
00127
00128 #define IPOPT_EOL               0               /* end of option list */
00129 #define IPOPT_NOP               1               /* no operation */
00130
00131 #define IPOPT_RR                7               /* record packet route */
00132 #define IPOPT_TS                68              /* timestamp */
00133 #define IPOPT_SECURITY          130             /* provide s,c,h,tcc */
00134 #define IPOPT_LSRR              131             /* loose source route */
00135 #define IPOPT_SATID             136             /* satnet id */
00136 #define IPOPT_SSRR              137             /* strict source route */
00137 #define IPOPT_RA                148             /* router alert */
00138
00139 /*
00140  * Offsets to fields in options other than EOL and NOP.
00141  */
00142 #define IPOPT_OPTVAL            0               /* option ID */
00143 #define IPOPT_OLEN              1               /* option length */
00144 #define IPOPT_OFFSET            2               /* offset within option */
00145 #define IPOPT_MINOFF            4               /* min value of above */
00146
00147 /*
00148  * Time stamp option structure.
00149  */
00150 struct  ip_timestamp {
00151         u_char  ipt_code;               /* IPOPT_TS */
00152         u_char  ipt_len;                /* size of structure (variable) */
00153         u_char  ipt_ptr;                /* index of current entry */
00154         u_char  ipt_flg:4;              /* flags, see below */
00155         u_char  ipt_oflw:4;             /* overflow counter */
00156         union ipt_timestamp {
00157                 n_long  ipt_time[1];
00158                 struct  ipt_ta {
00159                         struct in_addr ipt_addr;
00160                         n_long ipt_time;
00161                 } ipt_ta[1];
00162         } ipt_timestamp;
00163 };
00164
00165 #include <sys/packoff.h>
00166
00167 /* flag bits for ipt_flg */
00168 #define IPOPT_TS_TSONLY         0               /* timestamps only */
00169 #define IPOPT_TS_TSANDADDR      1               /* timestamps and addresses */
00170 #define IPOPT_TS_PRESPEC        3               /* specified modules only */
00171
00172 /* bits for security (not byte swapped) */
00173 #define IPOPT_SECUR_UNCLASS     0x0000
00174 #define IPOPT_SECUR_CONFID      0xf135
00175 #define IPOPT_SECUR_EFTO        0x789a
00176 #define IPOPT_SECUR_MMMM        0xbc4d
00177 #define IPOPT_SECUR_RESTR       0xaf13
00178 #define IPOPT_SECUR_SECRET      0xd788
00179 #define IPOPT_SECUR_TOPSECRET   0x6bc5
00180
00181 /*
00182  * Internet implementation parameters.
00183  */
00184 #define MAXTTL          255             /* maximum time to live (seconds) */
00185 #define IPDEFTTL        64              /* default ttl, from RFC 1340 */
00186 #define IPFRAGTTL       60              /* time to live for frags, slowhz */
00187 #define IPTTLDEC        1               /* subtracted when forwarding */
00188
00189 #define IP_MSS          576             /* default maximum segment size */
00190
00191 #if defined(__TURBOC__) || defined(__BORLANDC__)
00192 #pragma warn -bbf.
00193 #endif
00194
00195 #endif
Generated on Wed Jan 25 15:42:33 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/netinet/IP6.H Source File

inc/netinet/IP6.H

Go to the documentation of this file.
00001
00005 /*      $FreeBSD: src/sys/netinet/ip6.h,v 1.5 2001/06/11 12:39:00 ume Exp $     */
00006 /*      $KAME: ip6.h,v 1.18 2001/03/29 05:34:30 itojun Exp $    */
00007
00008 /*
00009  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
00010  * All rights reserved.
00011  *
00012  * Redistribution and use in source and binary forms, with or without
00013  * modification, are permitted provided that the following conditions
00014  * are met:
00015  * 1. Redistributions of source code must retain the above copyright
00016  *    notice, this list of conditions and the following disclaimer.
00017  * 2. Redistributions in binary form must reproduce the above copyright
00018  *    notice, this list of conditions and the following disclaimer in the
00019  *    documentation and/or other materials provided with the distribution.
00020  * 3. Neither the name of the project nor the names of its contributors
00021  *    may be used to endorse or promote products derived from this software
00022  *    without specific prior written permission.
00023  *
00024  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
00025  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00026  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00027  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
00028  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00029  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00030  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00031  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00032  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00033  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00034  * SUCH DAMAGE.
00035  */
00036
00037 /*
00038  * Copyright (c) 1982, 1986, 1993
00039  *      The Regents of the University of California.  All rights reserved.
00040  *
00041  * Redistribution and use in source and binary forms, with or without
00042  * modification, are permitted provided that the following conditions
00043  * are met:
00044  * 1. Redistributions of source code must retain the above copyright
00045  *    notice, this list of conditions and the following disclaimer.
00046  * 2. Redistributions in binary form must reproduce the above copyright
00047  *    notice, this list of conditions and the following disclaimer in the
00048  *    documentation and/or other materials provided with the distribution.
00049  * 3. All advertising materials mentioning features or use of this software
00050  *    must display the following acknowledgement:
00051  *      This product includes software developed by the University of
00052  *      California, Berkeley and its contributors.
00053  * 4. Neither the name of the University nor the names of its contributors
00054  *    may be used to endorse or promote products derived from this software
00055  *    without specific prior written permission.
00056  *
00057  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
00058  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00059  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00060  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
00061  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00062  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00063  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00064  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00065  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00066  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00067  * SUCH DAMAGE.
00068  *
00069  *      @(#)ip.h        8.1 (Berkeley) 6/10/93
00070  */
00071
00072 #ifndef _NETINET_IP6_H_
00073 #define _NETINET_IP6_H_
00074
00075 /*
00076  * Definition for internet protocol version 6.
00077  * RFC 2460
00078  */
00079
00080 #ifndef __SYS_WTYPES_H
00081 #include <sys/wtypes.h>
00082 #endif
00083
00084 #include <sys/packon.h>
00085
00086 struct ip6_hdr {
00087        union {
00088          struct ip6_hdrctl {
00089            u_int32_t ip6_un1_flow; /* 20 bits of flow-ID */
00090            u_int16_t ip6_un1_plen; /* payload length */
00091            u_int8_t  ip6_un1_nxt;  /* next header */
00092            u_int8_t  ip6_un1_hlim; /* hop limit */
00093          } ip6_un1;
00094          u_int8_t    ip6_un2_vfc;  /* 4 bits version, top 4 bits class */
00095        } ip6_ctlun;
00096        struct in6_addr ip6_src;    /* source address */
00097        struct in6_addr ip6_dst;    /* destination address */
00098      };
00099
00100 #define ip6_vfc         ip6_ctlun.ip6_un2_vfc
00101 #define ip6_flow        ip6_ctlun.ip6_un1.ip6_un1_flow
00102 #define ip6_plen        ip6_ctlun.ip6_un1.ip6_un1_plen
00103 #define ip6_nxt         ip6_ctlun.ip6_un1.ip6_un1_nxt
00104 #define ip6_hlim        ip6_ctlun.ip6_un1.ip6_un1_hlim
00105 #define ip6_hops        ip6_ctlun.ip6_un1.ip6_un1_hlim
00106
00107 #define IPV6_VERSION            0x60
00108 #define IPV6_VERSION_MASK       0xf0
00109
00110 #if BYTE_ORDER == BIG_ENDIAN
00111 #define IPV6_FLOWINFO_MASK      0x0fffffff      /* flow info (28 bits) */
00112 #define IPV6_FLOWLABEL_MASK     0x000fffff      /* flow label (20 bits) */
00113 #else
00114 #if BYTE_ORDER == LITTLE_ENDIAN
00115 #define IPV6_FLOWINFO_MASK      0xffffff0f      /* flow info (28 bits) */
00116 #define IPV6_FLOWLABEL_MASK     0xffff0f00      /* flow label (20 bits) */
00117 #endif /* LITTLE_ENDIAN */
00118 #endif
00119
00120 #if 1
00121 /* ECN bits proposed by Sally Floyd */
00122 #define IP6TOS_CE               0x01    /* congestion experienced */
00123 #define IP6TOS_ECT              0x02    /* ECN-capable transport */
00124 #endif
00125
00126 /*
00127  * Extension Headers
00128  */
00129
00130 struct ip6_ext {
00131        u_int8_t ip6e_nxt;
00132        u_int8_t ip6e_len;
00133      };
00134
00135 /* Hop-by-Hop options header */
00136 /* XXX should we pad it to force alignment on an 8-byte boundary? */
00137 struct ip6_hbh {
00138        u_int8_t ip6h_nxt;      /* next header */
00139        u_int8_t ip6h_len;      /* length in units of 8 octets */
00140        /* followed by options */
00141      };
00142
00143 /* Destination options header */
00144 /* XXX should we pad it to force alignment on an 8-byte boundary? */
00145 struct ip6_dest {
00146        u_int8_t ip6d_nxt;      /* next header */
00147        u_int8_t ip6d_len;      /* length in units of 8 octets */
00148        /* followed by options */
00149      };
00150
00151 /* Option types and related macros */
00152 #define IP6OPT_PAD1             0x00    /* 00 0 00000 */
00153 #define IP6OPT_PADN             0x01    /* 00 0 00001 */
00154 #define IP6OPT_JUMBO            0xC2    /* 11 0 00010 = 194 */
00155 #define IP6OPT_NSAP_ADDR        0xC3    /* 11 0 00011 */
00156 #define IP6OPT_TUNNEL_LIMIT     0x04    /* 00 0 00100 */
00157 #define IP6OPT_RTALERT          0x05    /* 00 0 00101 (KAME definition) */
00158
00159 #define IP6OPT_RTALERT_LEN      4
00160 #define IP6OPT_RTALERT_MLD      0       /* Datagram contains an MLD message */
00161 #define IP6OPT_RTALERT_RSVP     1       /* Datagram contains an RSVP message */
00162 #define IP6OPT_RTALERT_ACTNET   2       /* contains an Active Networks msg */
00163 #define IP6OPT_MINLEN           2
00164
00165 #define IP6OPT_BINDING_UPDATE   0xc6    /* 11 0 00110 */
00166 #define IP6OPT_BINDING_ACK      0x07    /* 00 0 00111 */
00167 #define IP6OPT_BINDING_REQ      0x08    /* 00 0 01000 */
00168 #define IP6OPT_HOME_ADDRESS     0xc9    /* 11 0 01001 */
00169 #define IP6OPT_EID              0x8a    /* 10 0 01010 */
00170
00171 #define IP6OPT_TYPE(o)          ((o) & 0xC0)
00172 #define IP6OPT_TYPE_SKIP        0x00
00173 #define IP6OPT_TYPE_DISCARD     0x40
00174 #define IP6OPT_TYPE_FORCEICMP   0x80
00175 #define IP6OPT_TYPE_ICMP        0xC0
00176
00177 #define IP6OPT_MUTABLE          0x20
00178
00179 #define IP6OPT_JUMBO_LEN        6
00180
00181 /* Routing header */
00182 struct ip6_rthdr {
00183        u_int8_t  ip6r_nxt;     /* next header */
00184        u_int8_t  ip6r_len;     /* length in units of 8 octets */
00185        u_int8_t  ip6r_type;    /* routing type */
00186        u_int8_t  ip6r_segleft; /* segments left */
00187        /* followed by routing type specific data */
00188      };
00189
00190 /* Type 0 Routing header */
00191 struct ip6_rthdr0 {
00192        u_int8_t  ip6r0_nxt;            /* next header */
00193        u_int8_t  ip6r0_len;            /* length in units of 8 octets */
00194        u_int8_t  ip6r0_type;           /* always zero */
00195        u_int8_t  ip6r0_segleft;        /* segments left */
00196        u_int8_t  ip6r0_reserved;       /* reserved field */
00197        u_int8_t  ip6r0_slmap[3];       /* strict/loose bit map */
00198        struct in6_addr  ip6r0_addr[1]; /* up to 23 addresses */
00199      };
00200
00201 /* Fragment header */
00202 struct ip6_frag {
00203        u_int8_t  ip6f_nxt;             /* next header */
00204        u_int8_t  ip6f_reserved;        /* reserved field */
00205        u_int16_t ip6f_offlg;           /* offset, reserved, and flag */
00206        u_int32_t ip6f_ident;           /* identification */
00207      };
00208
00209 #include <sys/packoff.h>
00210
00211 #if BYTE_ORDER == BIG_ENDIAN
00212 #define IP6F_OFF_MASK           0xfff8  /* mask out offset from _offlg */
00213 #define IP6F_RESERVED_MASK      0x0006  /* reserved bits in ip6f_offlg */
00214 #define IP6F_MORE_FRAG          0x0001  /* more-fragments flag */
00215 #else /* BYTE_ORDER == LITTLE_ENDIAN */
00216 #define IP6F_OFF_MASK           0xf8ff  /* mask out offset from _offlg */
00217 #define IP6F_RESERVED_MASK      0x0600  /* reserved bits in ip6f_offlg */
00218 #define IP6F_MORE_FRAG          0x0100  /* more-fragments flag */
00219 #endif /* BYTE_ORDER == LITTLE_ENDIAN */
00220
00221 /*
00222  * Internet implementation parameters.
00223  */
00224 #define IPV6_MAXHLIM    255     /* maximun hoplimit */
00225 #define IPV6_DEFHLIM    64      /* default hlim */
00226 #define IPV6_FRAGTTL    120     /* ttl for fragment packets, in slowtimo tick */
00227 #define IPV6_HLIMDEC    1       /* subtracted when forwaeding */
00228
00229 #define IPV6_MMTU       1280    /* minimal MTU and reassembly. 1024 + 256 */
00230 #define IPV6_MAXPACKET  65535   /* ip6 max packet size without Jumbo payload*/
00231
00232 #ifdef _KERNEL
00233 /*
00234  * IP6_EXTHDR_CHECK ensures that region between the IP6 header and the
00235  * target header (including IPv6 itself, extension headers and
00236  * TCP/UDP/ICMP6 headers) are continuous. KAME requires drivers
00237  * to store incoming data into one internal mbuf or one or more external
00238  * mbufs(never into two or more internal mbufs). Thus, the third case is
00239  * supposed to never be matched but is prepared just in case.
00240  */
00241
00242 #define IP6_EXTHDR_CHECK(m, off, hlen, ret)                             \
00243 do {                                                                    \
00244     if ((m)->m_next != NULL) {                                          \
00245         if (((m)->m_flags & M_LOOP) &&                                  \
00246             ((m)->m_len < (off) + (hlen)) &&                            \
00247             (((m) = m_pullup((m), (off) + (hlen))) == NULL)) {          \
00248                 ip6stat.ip6s_exthdrtoolong++;                           \
00249                 return ret;                                             \
00250         } else if ((m)->m_flags & M_EXT) {                              \
00251                 if ((m)->m_len < (off) + (hlen)) {                      \
00252                         ip6stat.ip6s_exthdrtoolong++;                   \
00253                         m_freem(m);                                     \
00254                         return ret;                                     \
00255                 }                                                       \
00256         } else {                                                        \
00257                 if ((m)->m_len < (off) + (hlen)) {                      \
00258                         ip6stat.ip6s_exthdrtoolong++;                   \
00259                         m_freem(m);                                     \
00260                         return ret;                                     \
00261                 }                                                       \
00262         }                                                               \
00263     } else {                                                            \
00264         if ((m)->m_len < (off) + (hlen)) {                              \
00265                 ip6stat.ip6s_tooshort++;                                \
00266                 in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_truncated);   \
00267                 m_freem(m);                                             \
00268                 return ret;                                             \
00269         }                                                               \
00270     }                                                                   \
00271 } while (0)
00272
00273 /*
00274  * IP6_EXTHDR_GET ensures that intermediate protocol header (from "off" to
00275  * "len") is located in single mbuf, on contiguous memory region.
00276  * The pointer to the region will be returned to pointer variable "val",
00277  * with type "typ".
00278  * IP6_EXTHDR_GET0 does the same, except that it aligns the structure at the
00279  * very top of mbuf.  GET0 is likely to make memory copy than GET.
00280  *
00281  * XXX we're now testing this, needs m_pulldown()
00282  */
00283 #define IP6_EXTHDR_GET(val, typ, m, off, len) \
00284 do {                                                                    \
00285         struct mbuf *t;                                                 \
00286         int tmp;                                                        \
00287         if ((m)->m_len >= (off) + (len))                                \
00288                 (val) = (typ)(mtod((m), caddr_t) + (off));              \
00289         else {                                                          \
00290                 t = m_pulldown((m), (off), (len), &tmp);                \
00291                 if (t) {                                                \
00292                         if (t->m_len < tmp + (len))                     \
00293                                 panic("m_pulldown malfunction");        \
00294                         (val) = (typ)(mtod(t, caddr_t) + tmp);          \
00295                 } else {                                                \
00296                         (val) = (typ)NULL;                              \
00297                         (m) = NULL;                                     \
00298                 }                                                       \
00299         }                                                               \
00300 } while (0)
00301
00302 #define IP6_EXTHDR_GET0(val, typ, m, off, len) \
00303 do {                                                                    \
00304         struct mbuf *t;                                                 \
00305         if ((off) == 0)                                                 \
00306                 (val) = (typ)mtod(m, caddr_t);                          \
00307         else {                                                          \
00308                 t = m_pulldown((m), (off), (len), NULL);                \
00309                 if (t) {                                                \
00310                         if (t->m_len < (len))                           \
00311                                 panic("m_pulldown malfunction");        \
00312                         (val) = (typ)mtod(t, caddr_t);                  \
00313                 } else {                                                \
00314                         (val) = (typ)NULL;                              \
00315                         (m) = NULL;                                     \
00316                 }                                                       \
00317         }                                                               \
00318 } while (0)
00319 #endif /*_KERNEL*/
00320
00321 #endif /* not _NETINET_IP6_H_ */
Generated on Wed Jan 25 15:42:33 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/netinet/IP_FW.H Source File

inc/netinet/IP_FW.H

Go to the documentation of this file.
00001
00005 /*
00006  * Copyright (c) 1993 Daniel Boulet
00007  * Copyright (c) 1994 Ugen J.S.Antsilevich
00008  *
00009  * Redistribution and use in source forms, with and without modification,
00010  * are permitted provided that this entire comment appears intact.
00011  *
00012  * Redistribution in binary form may occur without any restrictions.
00013  * Obviously, it would be nice if you gave credit where credit is due
00014  * but requiring it would be too onerous.
00015  *
00016  * This software is provided ``AS IS'' without any warranties of any kind.
00017  *
00018  *      $Id: ip_fw.h,v 1.23.2.1 1997/01/29 13:15:43 adam Exp $
00019  */
00020
00021 /*
00022  * Format of an IP firewall descriptor
00023  *
00024  * fw_src, fw_dst, fw_smsk, fw_dmsk are always stored in network byte order.
00025  * fw_flg and fw_n*p are stored in host byte order (of course).
00026  * Port numbers are stored in HOST byte order.
00027  */
00028
00029 #ifndef __NETINET_IP_FW_H
00030 #define __NETINET_IP_FW_H
00031
00032 struct ip_fw {
00033     u_long fw_pcnt,fw_bcnt;             /* Packet and byte counters */
00034     struct in_addr fw_src, fw_dst;      /* Source and destination IP addr */
00035     struct in_addr fw_smsk, fw_dmsk;    /* Mask for src and dest IP addr */
00036     union {
00037         struct in_addr fu_via_ip;       /* Specified by IP address */
00038         struct {                        /* Specified by interface name */
00039 #define FW_IFNLEN       6               /* To keep structure on 2^x boundary */
00040                 char  fu_via_name[FW_IFNLEN];
00041                 short fu_via_unit;
00042         } fu_via_if;
00043     } fu_via_un;
00044 #define fw_via_ip       fu_via_un.fu_via_ip
00045 #define fw_via_name     fu_via_un.fu_via_if.fu_via_name
00046 #define fw_via_unit     fu_via_un.fu_via_if.fu_via_unit
00047     u_short fw_number;
00048     u_short fw_flg;                     /* Flags word */
00049     u_short fw_nsp, fw_ndp;             /* N'of src ports and # of dst ports */
00050                                         /* in ports array (dst ports follow */
00051                                         /* src ports; max of 10 ports in all; */
00052                                         /* count of 0 means match all ports) */
00053 #define IP_FW_MAX_PORTS 10              /* A reasonable maximum */
00054     u_short  fw_pts[IP_FW_MAX_PORTS];   /* Array of port numbers to match */
00055     u_char   fw_ipopt,fw_ipnopt;        /* IP options set/unset */
00056     u_char   fw_tcpf,fw_tcpnf;          /* TCP flags set/unset */
00057 #define IP_FW_ICMPTYPES_DIM (256 / (sizeof(unsigned) * 8))
00058     unsigned fw_icmptypes[IP_FW_ICMPTYPES_DIM]; /* ICMP types bitmap */
00059     long     timestamp;                 /* timestamp (tv_sec) of last match */
00060     u_short  fw_divert_port;            /* Divert port (options IPDIVERT) */
00061     u_char   fw_prot;                   /* IP protocol */
00062 };
00063
00064 struct ip_fw_chain {
00065        LIST_ENTRY(ip_fw_chain) chain;
00066        struct ip_fw    *rule;
00067 };
00068
00069 /*
00070  * Values for "flags" field .
00071  */
00072 #define IP_FW_F_INVSRC  0x0001  /* Invert sense of src check          */
00073 #define IP_FW_F_INVDST  0x0002  /* Invert sense of dst check          */
00074 #define IP_FW_F_IN      0x0004  /* Inbound                            */
00075 #define IP_FW_F_OUT     0x0008  /* Outbound                           */
00076
00077 #define IP_FW_F_COMMAND 0x0030  /* Mask for type of chain entry:      */
00078 #define IP_FW_F_ACCEPT  0x0010  /* This is an accept rule             */
00079 #define IP_FW_F_COUNT   0x0020  /* This is a count rule               */
00080 #define IP_FW_F_DIVERT  0x0030  /* This is a divert rule              */
00081 #define IP_FW_F_DENY    0x0000  /* This is a deny rule                */
00082
00083 #define IP_FW_F_PRN     0x0040  /* Print if this rule matches         */
00084 #define IP_FW_F_ICMPRPL 0x0080  /* Send back icmp unreachable packet  */
00085
00086 #define IP_FW_F_SRNG    0x0100  /* The first two src ports are a min  *
00087                                  * and max range (stored in host byte *
00088                                  * order).                            */
00089
00090 #define IP_FW_F_DRNG    0x0200  /* The first two dst ports are a min  *
00091                                  * and max range (stored in host byte *
00092                                  * order).                            */
00093
00094 #define IP_FW_F_IFNAME  0x0400  /* Use interface name/unit (not IP)   */
00095
00096 #define IP_FW_F_FRAG    0x0800  /* Fragment                           */
00097
00098 #define IP_FW_F_ICMPBIT 0x1000  /* ICMP type bitmap is valid          */
00099
00100 #define IP_FW_F_IFUWILD 0x2000  /* Match all interface units          */
00101
00102 #define IP_FW_F_MASK    0x3FFF  /* All possible flag bits mask        */
00103
00104 /*
00105  * Definitions for IP option names.
00106  */
00107 #define IP_FW_IPOPT_LSRR        0x01
00108 #define IP_FW_IPOPT_SSRR        0x02
00109 #define IP_FW_IPOPT_RR          0x04
00110 #define IP_FW_IPOPT_TS          0x08
00111
00112 /*
00113  * Definitions for TCP flags.
00114  */
00115 #define IP_FW_TCPF_FIN          TH_FIN
00116 #define IP_FW_TCPF_SYN          TH_SYN
00117 #define IP_FW_TCPF_RST          TH_RST
00118 #define IP_FW_TCPF_PSH          TH_PUSH
00119 #define IP_FW_TCPF_ACK          TH_ACK
00120 #define IP_FW_TCPF_URG          TH_URG
00121 #define IP_FW_TCPF_ESTAB        0x40
00122
00123 #endif
Generated on Wed Jan 25 15:42:33 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/netinet/IP_ICMP.H Source File

inc/netinet/IP_ICMP.H

Go to the documentation of this file.
00001
00005 /*
00006  * Copyright (c) 1982, 1986, 1993
00007  *      The Regents of the University of California.  All rights reserved.
00008  *
00009  * Redistribution and use in source and binary forms, with or without
00010  * modification, are permitted provided that the following conditions
00011  * are met:
00012  * 1. Redistributions of source code must retain the above copyright
00013  *    notice, this list of conditions and the following disclaimer.
00014  * 2. Redistributions in binary form must reproduce the above copyright
00015  *    notice, this list of conditions and the following disclaimer in the
00016  *    documentation and/or other materials provided with the distribution.
00017  * 3. All advertising materials mentioning features or use of this software
00018  *    must display the following acknowledgement:
00019  *      This product includes software developed by the University of
00020  *      California, Berkeley and its contributors.
00021  * 4. Neither the name of the University nor the names of its contributors
00022  *    may be used to endorse or promote products derived from this software
00023  *    without specific prior written permission.
00024  *
00025  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
00026  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00027  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00028  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
00029  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00030  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00031  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00032  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00033  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00034  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00035  * SUCH DAMAGE.
00036  *
00037  *      @(#)ip_icmp.h   8.1 (Berkeley) 6/10/93
00038  * $Id: ip_icmp.h,v 1.9 1996/08/20 23:11:30 fenner Exp $
00039  */
00040
00041 #ifndef __NETINET_IP_ICMP_H
00042 #define __NETINET_IP_ICMP_H
00043
00044 #include <sys/packon.h>
00045
00046 /*
00047  * Interface Control Message Protocol Definitions.
00048  * Per RFC 792, September 1981.
00049  */
00050
00051 /*
00052  * Internal of an ICMP Router Advertisement
00053  */
00054 struct icmp_ra_addr {
00055         u_int32_t ira_addr;
00056         u_int32_t ira_preference;
00057 };
00058
00059 /*
00060  * Structure of an icmp header.
00061  */
00062 struct icmp {
00063         u_char  icmp_type;              /* type of message, see below */
00064         u_char  icmp_code;              /* type sub code */
00065         u_short icmp_cksum;             /* ones complement cksum of struct */
00066         union {
00067                 u_char ih_pptr;                 /* ICMP_PARAMPROB */
00068                 struct in_addr ih_gwaddr;       /* ICMP_REDIRECT */
00069                 struct ih_idseq {
00070                         n_short icd_id;
00071                         n_short icd_seq;
00072                 } ih_idseq;
00073                 u_int32_t ih_void;     /* was 'int' */
00074
00075                 /* ICMP_UNREACH_NEEDFRAG -- Path MTU Discovery (RFC1191) */
00076                 struct ih_pmtu {
00077                         n_short ipm_void;
00078                         n_short ipm_nextmtu;
00079                 } ih_pmtu;
00080
00081                 struct ih_rtradv {
00082                         u_char irt_num_addrs;
00083                         u_char irt_wpa;
00084                         u_int16_t irt_lifetime;
00085                 } ih_rtradv;
00086         } icmp_hun;
00087 #define icmp_pptr       icmp_hun.ih_pptr
00088 #define icmp_gwaddr     icmp_hun.ih_gwaddr
00089 #define icmp_id         icmp_hun.ih_idseq.icd_id
00090 #define icmp_seq        icmp_hun.ih_idseq.icd_seq
00091 #define icmp_void       icmp_hun.ih_void
00092 #define icmp_pmvoid     icmp_hun.ih_pmtu.ipm_void
00093 #define icmp_nextmtu    icmp_hun.ih_pmtu.ipm_nextmtu
00094 #define icmp_num_addrs  icmp_hun.ih_rtradv.irt_num_addrs
00095 #define icmp_wpa        icmp_hun.ih_rtradv.irt_wpa
00096 #define icmp_lifetime   icmp_hun.ih_rtradv.irt_lifetime
00097         union {
00098                 struct id_ts {
00099                         n_time its_otime;
00100                         n_time its_rtime;
00101                         n_time its_ttime;
00102                 } id_ts;
00103                 struct id_ip  {
00104                         struct ip idi_ip;
00105                         /* options and then 64 bits of data */
00106                 } id_ip;
00107                 struct icmp_ra_addr id_radv;
00108                 u_long  id_mask;
00109                 char    id_data[1];
00110         } icmp_dun;
00111 #define icmp_otime      icmp_dun.id_ts.its_otime
00112 #define icmp_rtime      icmp_dun.id_ts.its_rtime
00113 #define icmp_ttime      icmp_dun.id_ts.its_ttime
00114 #define icmp_ip         icmp_dun.id_ip.idi_ip
00115 #define icmp_radv       icmp_dun.id_radv
00116 #define icmp_mask       icmp_dun.id_mask
00117 #define icmp_data       icmp_dun.id_data
00118 };
00119
00120 #include <sys/packoff.h>
00121
00122 /*
00123  * Lower bounds on packet lengths for various types.
00124  * For the error advice packets must first insure that the
00125  * packet is large enough to contain the returned ip header.
00126  * Only then can we do the check to see if 64 bits of packet
00127  * data have been returned, since we need to check the returned
00128  * ip header length.
00129  */
00130 #define ICMP_MINLEN     8                               /* abs minimum */
00131 #define ICMP_TSLEN      (8 + 3 * sizeof (n_time))       /* timestamp */
00132 #define ICMP_MASKLEN    12                              /* address mask */
00133 #define ICMP_ADVLENMIN  (8 + sizeof (struct ip) + 8)    /* min */
00134 #ifndef _IP_VHL
00135 #define ICMP_ADVLEN(p)  (8 + ((p)->icmp_ip.ip_hl << 2) + 8)
00136         /* N.B.: must separately check that ip_hl >= 5 */
00137 #else
00138 #define ICMP_ADVLEN(p)  (8 + (IP_VHL_HL((p)->icmp_ip.ip_vhl) << 2) + 8)
00139         /* N.B.: must separately check that header length >= 5 */
00140 #endif
00141
00142 /*
00143  * Definition of type and code field values.
00144  */
00145 #define ICMP_ECHOREPLY          0               /* echo reply */
00146 #define ICMP_UNREACH            3               /* dest unreachable, codes: */
00147 #define         ICMP_UNREACH_NET        0               /* bad net */
00148 #define         ICMP_UNREACH_HOST       1               /* bad host */
00149 #define         ICMP_UNREACH_PROTOCOL   2               /* bad protocol */
00150 #define         ICMP_UNREACH_PORT       3               /* bad port */
00151 #define         ICMP_UNREACH_NEEDFRAG   4               /* IP_DF caused drop */
00152 #define         ICMP_UNREACH_SRCFAIL    5               /* src route failed */
00153 #define         ICMP_UNREACH_NET_UNKNOWN 6              /* unknown net */
00154 #define         ICMP_UNREACH_HOST_UNKNOWN 7             /* unknown host */
00155 #define         ICMP_UNREACH_ISOLATED   8               /* src host isolated */
00156 #define         ICMP_UNREACH_NET_PROHIB 9               /* prohibited access */
00157 #define         ICMP_UNREACH_HOST_PROHIB 10             /* ditto */
00158 #define         ICMP_UNREACH_TOSNET     11              /* bad tos for net */
00159 #define         ICMP_UNREACH_TOSHOST    12              /* bad tos for host */
00160 #define         ICMP_UNREACH_FILTER_PROHIB 13           /* admin prohib */
00161 #define         ICMP_UNREACH_HOST_PRECEDENCE 14         /* host prec vio. */
00162 #define         ICMP_UNREACH_PRECEDENCE_CUTOFF 15       /* prec cutoff */
00163 #define ICMP_SOURCEQUENCH       4               /* packet lost, slow down */
00164 #define ICMP_REDIRECT           5               /* shorter route, codes: */
00165 #define         ICMP_REDIRECT_NET       0               /* for network */
00166 #define         ICMP_REDIRECT_HOST      1               /* for host */
00167 #define         ICMP_REDIRECT_TOSNET    2               /* for tos and net */
00168 #define         ICMP_REDIRECT_TOSHOST   3               /* for tos and host */
00169 #define ICMP_ECHO               8               /* echo service */
00170 #define ICMP_ROUTERADVERT       9               /* router advertisement */
00171 #define ICMP_ROUTERSOLICIT      10              /* router solicitation */
00172 #define ICMP_TIMXCEED           11              /* time exceeded, code: */
00173 #define         ICMP_TIMXCEED_INTRANS   0               /* ttl==0 in transit */
00174 #define         ICMP_TIMXCEED_REASS     1               /* ttl==0 in reass */
00175 #define ICMP_PARAMPROB          12              /* ip header bad */
00176 #define         ICMP_PARAMPROB_OPTABSENT 1              /* req. opt. absent */
00177 #define ICMP_TSTAMP             13              /* timestamp request */
00178 #define ICMP_TSTAMPREPLY        14              /* timestamp reply */
00179 #define ICMP_IREQ               15              /* information request */
00180 #define ICMP_IREQREPLY          16              /* information reply */
00181 #define ICMP_MASKREQ            17              /* address mask request */
00182 #define ICMP_MASKREPLY          18              /* address mask reply */
00183
00184 #ifndef ICMP_MAXTYPE
00185 #define ICMP_MAXTYPE            18
00186 #endif
00187
00188 #define ICMP_INFOTYPE(type) \
00189         ((type) == ICMP_ECHOREPLY || (type) == ICMP_ECHO || \
00190         (type) == ICMP_ROUTERADVERT || (type) == ICMP_ROUTERSOLICIT || \
00191         (type) == ICMP_TSTAMP || (type) == ICMP_TSTAMPREPLY || \
00192         (type) == ICMP_IREQ || (type) == ICMP_IREQREPLY || \
00193         (type) == ICMP_MASKREQ || (type) == ICMP_MASKREPLY)
00194
00195 #endif
Generated on Wed Jan 25 15:42:33 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/netinet/IP_MROUT.H Source File

inc/netinet/IP_MROUT.H

Go to the documentation of this file.
00001
00005 /*
00006  * Copyright (c) 1989 Stephen Deering.
00007  * Copyright (c) 1992, 1993
00008  *      The Regents of the University of California.  All rights reserved.
00009  *
00010  * This code is derived from software contributed to Berkeley by
00011  * Stephen Deering of Stanford University.
00012  *
00013  * Redistribution and use in source and binary forms, with or without
00014  * modification, are permitted provided that the following conditions
00015  * are met:
00016  * 1. Redistributions of source code must retain the above copyright
00017  *    notice, this list of conditions and the following disclaimer.
00018  * 2. Redistributions in binary form must reproduce the above copyright
00019  *    notice, this list of conditions and the following disclaimer in the
00020  *    documentation and/or other materials provided with the distribution.
00021  * 3. All advertising materials mentioning features or use of this software
00022  *    must display the following acknowledgement:
00023  *      This product includes software developed by the University of
00024  *      California, Berkeley and its contributors.
00025  * 4. Neither the name of the University nor the names of its contributors
00026  *    may be used to endorse or promote products derived from this software
00027  *    without specific prior written permission.
00028  *
00029  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
00030  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00031  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00032  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
00033  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00034  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00035  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00036  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00037  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00038  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00039  * SUCH DAMAGE.
00040  *
00041  *      @(#)ip_mroute.h 8.1 (Berkeley) 6/10/93
00042  * $Id: ip_mroute.h,v 1.10.4.1 1997/02/22 19:47:28 joerg Exp $
00043  */
00044
00045 #ifndef __NETINET_IP_MROUTE_H
00046 #define __NETINET_IP_MROUTE_H
00047
00048 /*
00049  * Definitions for IP multicast forwarding.
00050  *
00051  * Written by David Waitzman, BBN Labs, August 1988.
00052  * Modified by Steve Deering, Stanford, February 1989.
00053  * Modified by Ajit Thyagarajan, PARC, August 1993.
00054  * Modified by Ajit Thyagarajan, PARC, August 1994.
00055  *
00056  * MROUTING Revision: 3.3.1.3
00057  */
00058
00059
00060 /*
00061  * Multicast Routing set/getsockopt commands.
00062  */
00063 #define MRT_INIT        100     /* initialize forwarder */
00064 #define MRT_DONE        101     /* shut down forwarder */
00065 #define MRT_ADD_VIF     102     /* create virtual interface */
00066 #define MRT_DEL_VIF     103     /* delete virtual interface */
00067 #define MRT_ADD_MFC     104     /* insert forwarding cache entry */
00068 #define MRT_DEL_MFC     105     /* delete forwarding cache entry */
00069 #define MRT_VERSION     106     /* get kernel version number */
00070 #define MRT_ASSERT      107     /* enable PIM assert processing */
00071
00072
00073 #define GET_TIME(t)     microtime(&t)
00074
00075 /*
00076  * Types and macros for handling bitmaps with one bit per virtual interface.
00077  */
00078 #define MAXVIFS 32
00079 typedef u_long vifbitmap_t;
00080 typedef u_short vifi_t;         /* type of a vif index */
00081 #define ALL_VIFS (vifi_t)-1
00082
00083 #define VIFM_SET(n, m)          ((m) |= (1 << (n)))
00084 #define VIFM_CLR(n, m)          ((m) &= ~(1 << (n)))
00085 #define VIFM_ISSET(n, m)        ((m) & (1 << (n)))
00086 #define VIFM_CLRALL(m)          ((m) = 0x00000000)
00087 #define VIFM_COPY(mfrom, mto)   ((mto) = (mfrom))
00088 #define VIFM_SAME(m1, m2)       ((m1) == (m2))
00089
00090
00091 /*
00092  * Argument structure for MRT_ADD_VIF.
00093  * (MRT_DEL_VIF takes a single vifi_t argument.)
00094  */
00095 struct vifctl {
00096         vifi_t  vifc_vifi;              /* the index of the vif to be added */
00097         u_char  vifc_flags;             /* VIFF_ flags defined below */
00098         u_char  vifc_threshold;         /* min ttl required to forward on vif */
00099         u_int   vifc_rate_limit;        /* max rate */
00100         struct  in_addr vifc_lcl_addr;  /* local interface address */
00101         struct  in_addr vifc_rmt_addr;  /* remote address (tunnels only) */
00102 };
00103
00104 #define VIFF_TUNNEL     0x1             /* vif represents a tunnel end-point */
00105 #define VIFF_SRCRT      0x2             /* tunnel uses IP source routing */
00106
00107 /*
00108  * Argument structure for MRT_ADD_MFC and MRT_DEL_MFC
00109  * (mfcc_tos to be added at a future point)
00110  */
00111 struct mfcctl {
00112     struct in_addr  mfcc_origin;                /* ip origin of mcasts       */
00113     struct in_addr  mfcc_mcastgrp;              /* multicast group associated*/
00114     vifi_t          mfcc_parent;                /* incoming vif              */
00115     u_char          mfcc_ttls[MAXVIFS];         /* forwarding ttls on vifs   */
00116 };
00117
00118 /*
00119  * The kernel's multicast routing statistics.
00120  */
00121 struct mrtstat {
00122     u_long      mrts_mfc_lookups;       /* # forw. cache hash table hits   */
00123     u_long      mrts_mfc_misses;        /* # forw. cache hash table misses */
00124     u_long      mrts_upcalls;           /* # calls to mrouted              */
00125     u_long      mrts_no_route;          /* no route for packet's origin    */
00126     u_long      mrts_bad_tunnel;        /* malformed tunnel options        */
00127     u_long      mrts_cant_tunnel;       /* no room for tunnel options      */
00128     u_long      mrts_wrong_if;          /* arrived on wrong interface      */
00129     u_long      mrts_upq_ovflw;         /* upcall Q overflow               */
00130     u_long      mrts_cache_cleanups;    /* # entries with no upcalls       */
00131     u_long      mrts_drop_sel;          /* pkts dropped selectively        */
00132     u_long      mrts_q_overflow;        /* pkts dropped - Q overflow       */
00133     u_long      mrts_pkt2large;         /* pkts dropped - size > BKT SIZE  */
00134     u_long      mrts_upq_sockfull;      /* upcalls dropped - socket full */
00135 };
00136
00137 /*
00138  * Argument structure used by mrouted to get src-grp pkt counts
00139  */
00140 struct sioc_sg_req {
00141     struct in_addr src;
00142     struct in_addr grp;
00143     u_long pktcnt;
00144     u_long bytecnt;
00145     u_long wrong_if;
00146 };
00147
00148 /*
00149  * Argument structure used by mrouted to get vif pkt counts
00150  */
00151 struct sioc_vif_req {
00152     vifi_t vifi;                /* vif number                           */
00153     u_long icount;              /* Input packet count on vif            */
00154     u_long ocount;              /* Output packet count on vif           */
00155     u_long ibytes;              /* Input byte count on vif              */
00156     u_long obytes;              /* Output byte count on vif             */
00157 };
00158
00159
00160 /*
00161  * The kernel's virtual-interface structure.
00162  */
00163 struct vif {
00164     u_char              v_flags;        /* VIFF_ flags defined above         */
00165     u_char              v_threshold;    /* min ttl required to forward on vif*/
00166     u_int               v_rate_limit;   /* max rate                          */
00167     struct tbf         *v_tbf;          /* token bucket structure at intf.   */
00168     struct in_addr      v_lcl_addr;     /* local interface address           */
00169     struct in_addr      v_rmt_addr;     /* remote address (tunnels only)     */
00170     struct ifnet       *v_ifp;          /* pointer to interface              */
00171     u_long              v_pkt_in;       /* # pkts in on interface            */
00172     u_long              v_pkt_out;      /* # pkts out on interface           */
00173     u_long              v_bytes_in;     /* # bytes in on interface           */
00174     u_long              v_bytes_out;    /* # bytes out on interface          */
00175     struct route        v_route;        /* cached route if this is a tunnel  */
00176     u_int               v_rsvp_on;      /* RSVP listening on this vif */
00177     struct socket      *v_rsvpd;        /* RSVP daemon socket */
00178 };
00179
00180 /*
00181  * The kernel's multicast forwarding cache entry structure
00182  * (A field for the type of service (mfc_tos) is to be added
00183  * at a future point)
00184  */
00185 struct mfc {
00186     struct in_addr  mfc_origin;                 /* IP origin of mcasts   */
00187     struct in_addr  mfc_mcastgrp;               /* multicast group associated*/
00188     vifi_t          mfc_parent;                 /* incoming vif              */
00189     u_char          mfc_ttls[MAXVIFS];          /* forwarding ttls on vifs   */
00190     u_long          mfc_pkt_cnt;                /* pkt count for src-grp     */
00191     u_long          mfc_byte_cnt;               /* byte count for src-grp    */
00192     u_long          mfc_wrong_if;               /* wrong if for src-grp      */
00193     int             mfc_expire;                 /* time to clean entry up    */
00194     struct timeval  mfc_last_assert;            /* last time I sent an assert*/
00195 };
00196
00197 /*
00198  * Struct used to communicate from kernel to multicast router
00199  * note the convenient similarity to an IP packet
00200  */
00201 struct igmpmsg {
00202     u_long          unused1;
00203     u_long          unused2;
00204     u_char          im_msgtype;                 /* what type of message     */
00205 #define IGMPMSG_NOCACHE         1
00206 #define IGMPMSG_WRONGVIF        2
00207     u_char          im_mbz;                     /* must be zero             */
00208     u_char          im_vif;                     /* vif rec'd on             */
00209     u_char          unused3;
00210     struct in_addr  im_src, im_dst;
00211 };
00212
00213 /*
00214  * Argument structure used for pkt info. while upcall is made
00215  */
00216 struct rtdetq {
00217     struct mbuf         *m;             /* A copy of the packet             */
00218     struct ifnet        *ifp;           /* Interface pkt came in on         */
00219     vifi_t              xmt_vif;        /* Saved copy of imo_multicast_vif  */
00220 #ifdef UPCALL_TIMING
00221     struct timeval      t;              /* Timestamp */
00222 #endif
00223 };
00224
00225 #define MFCTBLSIZ       256
00226 #if (MFCTBLSIZ & (MFCTBLSIZ - 1)) == 0    /* from sys:route.h */
00227 #define MFCHASHMOD(h)   ((h) & (MFCTBLSIZ - 1))
00228 #else
00229 #define MFCHASHMOD(h)   ((h) % MFCTBLSIZ)
00230 #endif
00231
00232 #define MAX_UPQ 4               /* max. no of pkts in upcall Q */
00233
00234 /*
00235  * Token Bucket filter code
00236  */
00237 #define MAX_BKT_SIZE    10000             /* 10K bytes size             */
00238 #define MAXQSIZE        10                /* max # of pkts in queue     */
00239
00240 /*
00241  * the token bucket filter at each vif
00242  */
00243 struct tbf
00244 {
00245     struct timeval tbf_last_pkt_t; /* arr. time of last pkt     */
00246     u_long tbf_n_tok;           /* no of tokens in bucket       */
00247     u_long tbf_q_len;           /* length of queue at this vif  */
00248     u_long tbf_max_q_len;       /* max. queue length            */
00249     struct mbuf *tbf_q;         /* Packet queue                 */
00250     struct mbuf *tbf_t;         /* tail-insertion pointer       */
00251 };
00252
00253 #endif
Generated on Wed Jan 25 15:42:33 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/netinet/IP_VAR.H Source File

inc/netinet/IP_VAR.H

Go to the documentation of this file.
00001
00005 /*
00006  * Copyright (c) 1982, 1986, 1993
00007  *      The Regents of the University of California.  All rights reserved.
00008  *
00009  * Redistribution and use in source and binary forms, with or without
00010  * modification, are permitted provided that the following conditions
00011  * are met:
00012  * 1. Redistributions of source code must retain the above copyright
00013  *    notice, this list of conditions and the following disclaimer.
00014  * 2. Redistributions in binary form must reproduce the above copyright
00015  *    notice, this list of conditions and the following disclaimer in the
00016  *    documentation and/or other materials provided with the distribution.
00017  * 3. All advertising materials mentioning features or use of this software
00018  *    must display the following acknowledgement:
00019  *      This product includes software developed by the University of
00020  *      California, Berkeley and its contributors.
00021  * 4. Neither the name of the University nor the names of its contributors
00022  *    may be used to endorse or promote products derived from this software
00023  *    without specific prior written permission.
00024  *
00025  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
00026  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00027  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00028  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
00029  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00030  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00031  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00032  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00033  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00034  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00035  * SUCH DAMAGE.
00036  *
00037  *      @(#)ip_var.h    8.2 (Berkeley) 1/9/95
00038  *      $Id: ip_var.h,v 1.24.2.2 1996/11/12 11:28:59 phk Exp $
00039  */
00040
00041 #ifndef __NETINET_IP_VAR_H
00042 #define __NETINET_IP_VAR_H
00043
00044 #include <sys/packon.h>
00045
00046 #if defined(__TURBOC__) || defined(__BORLANDC__)
00047 #pragma warn -bbf-   /* "Bitfields must be signed or unsigned int" warning */
00048 #endif
00049
00050 /*
00051  * Overlay for ip header used by other protocols (tcp, udp).
00052  */
00053 struct ipovly {
00054         caddr_t ih_next, ih_prev;       /* for protocol sequence q's */
00055         u_char  ih_x1;                  /* (unused) */
00056         u_char  ih_pr;                  /* protocol */
00057         u_short ih_len;                 /* protocol length */
00058         struct  in_addr ih_src;         /* source internet address */
00059         struct  in_addr ih_dst;         /* destination internet address */
00060 };
00061
00062
00063 /*
00064  * Ip header, when holding a fragment.
00065  *
00066  * Note: ipf_next must be at same offset as ipq_next above
00067  */
00068 struct  ipasfrag {
00069         u_char  ip_hl:4;
00070         u_char  ip_v:4;
00071         u_char  ipf_mff;                /* XXX overlays ip_tos: use low bit
00072                                          * to avoid destroying tos;
00073                                          * copied from (ip_off&IP_MF) */
00074         u_short ip_len;
00075         u_short ip_id;
00076         u_short ip_off;
00077         u_char  ip_ttl;
00078         u_char  ip_p;
00079         u_short ip_sum;
00080         struct  ipasfrag *ipf_next;     /* next fragment */
00081         struct  ipasfrag *ipf_prev;     /* previous fragment */
00082 };
00083
00084 #include <sys/packoff.h>
00085
00086 /*
00087  * Ip reassembly queue structure.  Each fragment
00088  * being reassembled is attached to one of these structures.
00089  * They are timed out after ipq_ttl drops to 0, and may also
00090  * be reclaimed if memory becomes tight.
00091  */
00092 struct ipq {
00093        struct  ipq *next,*prev;        /* to other reass headers */
00094        u_char  ipq_ttl;                /* time for reass q to live */
00095        u_char  ipq_p;                  /* protocol of this fragment */
00096        u_short ipq_id;                 /* sequence id for reassembly */
00097        struct  ipasfrag *ipq_next,*ipq_prev;
00098                                        /* to ip headers of fragments */
00099        struct  in_addr ipq_src,ipq_dst;
00100 #ifdef IPDIVERT
00101        u_short ipq_divert;             /* divert protocol port */
00102 #endif
00103 };
00104
00105 /*
00106  * Structure stored in mbuf in inpcb.ip_options
00107  * and passed to ip_output when ip options are in use.
00108  * The actual length of the options (including ipopt_dst)
00109  * is in m_len.
00110  */
00111 #define MAX_IPOPTLEN    40
00112
00113 struct ipoption {
00114         struct  in_addr ipopt_dst;      /* first-hop dst if source routed */
00115         char    ipopt_list[MAX_IPOPTLEN];       /* options proper */
00116 };
00117
00118 /*
00119  * Structure attached to inpcb.ip_moptions and
00120  * passed to ip_output when IP multicast options are in use.
00121  */
00122 struct ip_moptions {
00123         struct  ifnet *imo_multicast_ifp; /* ifp for outgoing multicasts */
00124         u_char  imo_multicast_ttl;      /* TTL for outgoing multicasts */
00125         u_char  imo_multicast_loop;     /* 1 => hear sends if a member */
00126         u_short imo_num_memberships;    /* no. memberships this socket */
00127         struct  in_multi *imo_membership[IP_MAX_MEMBERSHIPS];
00128         u_long  imo_multicast_vif;      /* vif num outgoing multicasts */
00129 };
00130
00131 struct  ipstat {
00132         u_long  ips_total;              /* total packets received */
00133         u_long  ips_badsum;             /* checksum bad */
00134         u_long  ips_tooshort;           /* packet too short */
00135         u_long  ips_toosmall;           /* not enough data */
00136         u_long  ips_badhlen;            /* ip header length < data size */
00137         u_long  ips_badlen;             /* ip length < ip header length */
00138         u_long  ips_fragments;          /* fragments received */
00139         u_long  ips_fragdropped;        /* frags dropped (dups, out of space) */
00140         u_long  ips_fragtimeout;        /* fragments timed out */
00141         u_long  ips_forward;            /* packets forwarded */
00142         u_long  ips_cantforward;        /* packets rcvd for unreachable dest */
00143         u_long  ips_redirectsent;       /* packets forwarded on same net */
00144         u_long  ips_noproto;            /* unknown or unsupported protocol */
00145         u_long  ips_delivered;          /* datagrams delivered to upper level*/
00146         u_long  ips_localout;           /* total ip packets generated here */
00147         u_long  ips_odropped;           /* lost out packets due to nobufs, etc. */
00148         u_long  ips_idropped;
00149         u_long  ips_reassembled;        /* total packets reassembled ok */
00150         u_long  ips_fragmented;         /* datagrams successfully fragmented */
00151         u_long  ips_ofragments;         /* output fragments created */
00152         u_long  ips_cantfrag;           /* don't fragment flag was set, etc. */
00153         u_long  ips_badoptions;         /* error in option processing */
00154         u_long  ips_noroute;            /* packets discarded due to no route */
00155         u_long  ips_badvers;            /* ip version != 4 */
00156         u_long  ips_rawout;             /* total raw ip packets generated */
00157         u_long  ips_toolong;            /* ip length > max ip packet size */
00158 };
00159
00160 #if defined(__TURBOC__) || defined(__BORLANDC__)
00161 #pragma warn -bbf.
00162 #endif
00163
00164 #endif
Generated on Wed Jan 25 15:42:33 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/netinet/IPV6.H Source File

inc/netinet/IPV6.H

Go to the documentation of this file.
00001
00005 /*
00006  *      Linux INET6 implementation
00007  *
00008  *      Authors:
00009  *      Pedro Roque             <roque@di.fc.ul.pt>
00010  *
00011  *      $Id: ipv6.h,v 1.6 1997/04/01 02:22:58 davem Exp $
00012  *
00013  *      This program is free software; you can redistribute it and/or
00014  *      modify it under the terms of the GNU General Public License
00015  *      as published by the Free Software Foundation; either version
00016  *      2 of the License, or (at your option) any later version.
00017  *
00018  *  NB! Don't ue this file. Use <netinet/in.h> instread.
00019  */
00020
00021 #ifndef _NET_IPV6_H
00022 #define _NET_IPV6_H
00023
00024 #ifndef __NETINET_IN_H
00025 #include <netinet/in.h>  /* in6_addr */
00026 #endif
00027
00028 /*
00029  *  Advanced API
00030  *  source interface/address selection, source routing, etc...
00031  *  *under construction*
00032  */
00033
00034 #include <sys/packon.h>
00035
00036 /*
00037  *  IPv6 fixed header
00038  */
00039 struct ipv6hdr {
00040        unsigned char   ipv6_priority:4;
00041        unsigned char   ipv6_version:4;
00042        unsigned char   ipv6_flow_lbl[3];
00043        unsigned short  ipv6_len;
00044        unsigned char   ipv6_nextheader;
00045        unsigned char   ipv6_hoplimit;
00046        struct in6_addr ipv6_src;
00047        struct in6_addr ipv6_dst;
00048      };
00049
00050
00051
00052 /*
00053  *  The length of this struct cannot be greater than the length of
00054  *  the proto_priv field in a sk_buff which is currently
00055  *  defined to be 16 bytes.
00056  *  Pointers take upto 8 bytes (sizeof(void *) is 8 on the alpha).
00057  */
00058 struct ipv6_options  {
00059        /* length of extension headers */
00060        unsigned short opt_flen;       /* after fragment hdr */
00061        unsigned short opt_nflen;      /* before fragment hdr */
00062       /*
00063        * protocol options
00064        * usualy carried in IPv6 extension headers
00065        */
00066        struct ipv6_rt_hdr *srcrt; /* Routing Header */
00067       };
00068
00069 struct in6_pktinfo {
00070        struct in6_addr ipi6_addr;
00071        int             ipi6_ifindex;
00072      };
00073
00074
00075 struct in6_ifreq {
00076        struct in6_addr ifr6_addr;
00077        unsigned long   ifr6_prefixlen;
00078        unsigned long   ifr6_ifindex;
00079      };
00080
00081 #define IPV6_SRCRT_STRICT       0x01    /* this hop must be a neighbor  */
00082 #define IPV6_SRCRT_TYPE_0       0       /* IPv6 type 0 Routing Header   */
00083
00084 /*
00085  *      routing header
00086  */
00087 struct ipv6_rt_hdr {
00088        unsigned char  nexthdr;
00089        unsigned char  hdrlen;
00090        unsigned char  type;
00091        unsigned char  segments_left;
00092        /*
00093         * type specific data
00094         * variable length field
00095         */
00096      };
00097
00098 /*
00099  * routing header type 0 (used in cmsghdr struct)
00100  */
00101 struct ipv6_rt0_hdr {
00102        struct ipv6_rt_hdr rt_hdr;
00103        unsigned long      bitmap;         /* strict/loose bit map */
00104 #ifndef __WATCOMC__
00105        struct in6_addr    addr[0];
00106 #endif
00107 #define rt0_type rt_hdr.type;
00108      };
00109
00110 /*
00111  *  NextHeader field of IPv6 header
00112  */
00113
00114 #define NEXTHDR_HOP             0       /* Hop-by-hop option header. */
00115 #define NEXTHDR_TCP             6       /* TCP segment. */
00116 #define NEXTHDR_UDP             17      /* UDP message. */
00117 #define NEXTHDR_IPV6            41      /* IPv6 in IPv6 */
00118 #define NEXTHDR_ROUTING         43      /* Routing header. */
00119 #define NEXTHDR_FRAGMENT        44      /* Fragmentation/reassembly header. */
00120 #define NEXTHDR_ESP             50      /* Encapsulating security payload. */
00121 #define NEXTHDR_AUTH            51      /* Authentication header. */
00122 #define NEXTHDR_ICMP            58      /* ICMP for IPv6. */
00123 #define NEXTHDR_NONE            59      /* No next header */
00124 #define NEXTHDR_DEST            60      /* Destination options header. */
00125
00126 #define NEXTHDR_MAX             255
00127
00128
00129 #define IPV6_DEFAULT_HOPLIMIT   64
00130 #define IPV6_DEFAULT_MCASTHOPS  1
00131
00132 /*
00133  *      Addr type
00134  *
00135  *      type    -       unicast | multicast | anycast
00136  *      scope   -       local   | site      | global
00137  *      v4      -       compat
00138  *      v4mapped
00139  *      any
00140  *      loopback
00141  */
00142
00143 #define IPV6_ADDR_ANY           0x0000U
00144
00145 #define IPV6_ADDR_UNICAST       0x0001U
00146 #define IPV6_ADDR_MULTICAST     0x0002U
00147 #define IPV6_ADDR_ANYCAST       0x0004U
00148
00149 #define IPV6_ADDR_LOOPBACK      0x0010U
00150 #define IPV6_ADDR_LINKLOCAL     0x0020U
00151 #define IPV6_ADDR_SITELOCAL     0x0040U
00152
00153 #define IPV6_ADDR_COMPATv4      0x0080U
00154
00155 #define IPV6_ADDR_SCOPE_MASK    0x00f0U
00156
00157 #define IPV6_ADDR_MAPPED        0x1000U
00158 #define IPV6_ADDR_RESERVED      0x2000U /* reserved address space */
00159
00160 /*
00161  *      fragmentation header
00162  */
00163
00164 struct ipv6_fraghdr {
00165        unsigned char   nexthdr;
00166        unsigned char   reserved;
00167        unsigned short  frag_off;
00168        unsigned long   identification;
00169      };
00170 #define fraghdr ipv6_fraghdr
00171
00172 #include <sys/packoff.h>
00173
00174 #endif
00175
Generated on Wed Jan 25 15:42:33 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/netinet/TCP.H Source File

inc/netinet/TCP.H

Go to the documentation of this file.
00001
00005 /*      $NetBSD: tcp.h,v 1.8 1995/04/17 05:32:58 cgd Exp $      */
00006
00007 /*
00008  * Copyright (c) 1982, 1986, 1993
00009  *      The Regents of the University of California.  All rights reserved.
00010  *
00011  * Redistribution and use in source and binary forms, with or without
00012  * modification, are permitted provided that the following conditions
00013  * are met:
00014  * 1. Redistributions of source code must retain the above copyright
00015  *    notice, this list of conditions and the following disclaimer.
00016  * 2. Redistributions in binary form must reproduce the above copyright
00017  *    notice, this list of conditions and the following disclaimer in the
00018  *    documentation and/or other materials provided with the distribution.
00019  * 3. All advertising materials mentioning features or use of this software
00020  *    must display the following acknowledgement:
00021  *      This product includes software developed by the University of
00022  *      California, Berkeley and its contributors.
00023  * 4. Neither the name of the University nor the names of its contributors
00024  *    may be used to endorse or promote products derived from this software
00025  *    without specific prior written permission.
00026  *
00027  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
00028  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00029  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00030  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
00031  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00032  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00033  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00034  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00035  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00036  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00037  * SUCH DAMAGE.
00038  *
00039  *      @(#)tcp.h       8.1 (Berkeley) 6/10/93
00040  */
00041
00042 #ifndef __NETINET_TCP_H
00043 #define __NETINET_TCP_H
00044
00045 typedef u_long  tcp_seq;
00046 typedef u_long  tcp_cc;                 /* connection count per rfc1644 */
00047
00048 #include <sys/packon.h>
00049
00050
00051 /*
00052  * TCP header.
00053  * Per RFC 793, September, 1981.
00054  */
00055 struct tcphdr {
00056         u_short th_sport;               /* source port */
00057         u_short th_dport;               /* destination port */
00058         tcp_seq th_seq;                 /* sequence number */
00059         tcp_seq th_ack;                 /* acknowledgement number */
00060         u_char  th_x2:4;                /* (unused) */
00061         u_char  th_off:4;               /* data offset */
00062         u_char  th_flags;
00063 #define TH_FIN  0x01
00064 #define TH_SYN  0x02
00065 #define TH_RST  0x04
00066 #define TH_PUSH 0x08
00067 #define TH_ACK  0x10
00068 #define TH_URG  0x20
00069 #define TH_FLAGS (TH_FIN|TH_SYN|TH_RST|TH_ACK|TH_URG)
00070
00071         u_short th_win;                 /* window */
00072         u_short th_sum;                 /* checksum */
00073         u_short th_urp;                 /* urgent pointer */
00074 };
00075
00076 #include <sys/packoff.h>
00077
00078 #define TCPOPT_EOL              0
00079 #define TCPOPT_NOP              1
00080 #define TCPOPT_MAXSEG           2
00081 #define    TCPOLEN_MAXSEG               4
00082 #define TCPOPT_WINDOW           3
00083 #define    TCPOLEN_WINDOW               3
00084 #define TCPOPT_SACK_PERMITTED   4
00085 #define    TCPOLEN_SACK_PERMITTED       2
00086 #define TCPOPT_SACK             5
00087 #define TCPOPT_TIMESTAMP        8
00088 #define    TCPOLEN_TIMESTAMP            10
00089 #define    TCPOLEN_TSTAMP_APPA          (TCPOLEN_TIMESTAMP+2) /* appendix A */
00090
00091 #define TCPOPT_TSTAMP_HDR       \
00092     (TCPOPT_NOP<<24|TCPOPT_NOP<<16|TCPOPT_TIMESTAMP<<8|TCPOLEN_TIMESTAMP)
00093
00094 #define TCPOPT_CC               11              /* CC options: RFC-1644 */
00095 #define TCPOPT_CCNEW            12
00096 #define TCPOPT_CCECHO           13
00097 #define    TCPOLEN_CC                   6
00098 #define    TCPOLEN_CC_APPA              (TCPOLEN_CC+2)
00099 #define    TCPOPT_CC_HDR(ccopt)         \
00100     (TCPOPT_NOP<<24|TCPOPT_NOP<<16|(ccopt)<<8|TCPOLEN_CC)
00101
00102 #define TCPOPT_SIGNATURE  19
00103 #define    TCP_SIGLEN 16
00104
00105 /*
00106  * Default maximum segment size for TCP.
00107  * With an IP MSS of 576, this is 536,
00108  * but 512 is probably more convenient.
00109  * This should be defined as MIN(512, IP_MSS - sizeof (struct tcpiphdr)).
00110  */
00111 #define TCP_MSS         512
00112
00113 #define TCP_MAXWIN      65535   /* largest value for (unscaled) window */
00114 #define TTCP_CLIENT_SND_WND     4096    /* dflt send window for T/TCP client */
00115
00116 #define TCP_MAX_WINSHIFT        14      /* maximum window shift */
00117
00118 #define TCP_MAXHLEN     (0xf<<2)        /* max length of header in bytes */
00119 #define TCP_MAXOLEN     (TCP_MAXHLEN - sizeof(struct tcphdr))
00120                                         /* max space left for options */
00121
00122 /*
00123  * User-settable options (used with setsockopt).
00124  */
00125 #define TCP_NODELAY     0x01    /* don't delay send to coalesce packets */
00126 #define TCP_MAXSEG      0x02    /* set maximum segment size */
00127 #ifdef TCP_AUTO
00128 #define TCP_AUTO_OP     0x03    /* 0 to disable autotuning, 1 to reenable */
00129 #endif
00130 #define TCP_NOPUSH      0x04    /* don't push last block of write */
00131 #define TCP_NOOPT       0x08    /* don't use TCP options */
00132
00133 /* For PSC modifications */
00134 #if defined(TCP_AUTO) || defined(TCP_SACK) || defined(TCP_FACK)
00135 #define PSC_VERSION "0.8"
00136 #endif
00137
00138 #endif
Generated on Wed Jan 25 15:42:33 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/netinet/TCP_DEBU.H Source File

inc/netinet/TCP_DEBU.H

Go to the documentation of this file.
00001
00005 /*
00006  * Copyright (c) 1982, 1986, 1993
00007  *      The Regents of the University of California.  All rights reserved.
00008  *
00009  * Redistribution and use in source and binary forms, with or without
00010  * modification, are permitted provided that the following conditions
00011  * are met:
00012  * 1. Redistributions of source code must retain the above copyright
00013  *    notice, this list of conditions and the following disclaimer.
00014  * 2. Redistributions in binary form must reproduce the above copyright
00015  *    notice, this list of conditions and the following disclaimer in the
00016  *    documentation and/or other materials provided with the distribution.
00017  * 3. All advertising materials mentioning features or use of this software
00018  *    must display the following acknowledgement:
00019  *      This product includes software developed by the University of
00020  *      California, Berkeley and its contributors.
00021  * 4. Neither the name of the University nor the names of its contributors
00022  *    may be used to endorse or promote products derived from this software
00023  *    without specific prior written permission.
00024  *
00025  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
00026  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00027  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00028  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
00029  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00030  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00031  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00032  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00033  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00034  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00035  * SUCH DAMAGE.
00036  *
00037  *      @(#)tcp_debug.h 8.1 (Berkeley) 6/10/93
00038  * $Id: tcp_debug.h,v 1.5 1996/04/13 12:45:57 bde Exp $
00039  */
00040
00041 #ifndef __NETINET_TCP_DEBUG_H
00042 #define __NETINET_TCP_DEBUG_H
00043
00044 struct tcp_debug {
00045        n_time           td_time;
00046        short            td_act;
00047        short            td_ostate;
00048        caddr_t          td_tcb;
00049        struct  tcpiphdr td_ti;
00050        short            td_req;
00051        struct  tcpcb    td_cb;
00052      };
00053
00054 #define TA_INPUT        0
00055 #define TA_OUTPUT       1
00056 #define TA_USER         2
00057 #define TA_RESPOND      3
00058 #define TA_DROP         4
00059
00060 #ifdef TANAMES
00061 static char *tanames[] = {
00062             "input", "output", "user", "respond", "drop"
00063           };
00064 #endif
00065
00066 #define TCP_NDEBUG 100
00067
00068 #ifdef TCP_AUTO_DEBUG
00069 #include <sys/wtime.h>
00070
00071 /* The following table is used as a circular buffer in which TCP
00072  * autotuning statistics can be kept.
00073  * It is intended that these statistics will be periodically read
00074  * by a debugging application using kvm.
00075  */
00076
00077 #define TAD_ENTRIES 1024            /* number of entries in monitor_table */
00078
00079 struct tad_entry {
00080        u_long         seq_no;            /* tad entry number */
00081        struct timeval time;              /* time of entry */
00082        u_long         snd_cwnd;          /* congestion window */
00083        u_long         sb_hiwat;          /* send socket buffer hi water mark */
00084        u_long         sb_target_hiwat;   /*      target for same */
00085        u_long         sb_cc;             /* space used in send socket buf */
00086        u_long         m_clused;          /* m_clusters - m_clfree */
00087        u_short        lport;             /* local port number */
00088        u_short        rport;             /* remote port number */
00089        u_long         debug;             /* used for debugging */
00090        tcp_seq        snd_max;           /* highest sequence number sent */
00091      } tad_table[TAD_ENTRIES];
00092
00093 extern struct tad_entry *tad_index;     /* insert point */
00094 extern u_long tad_seq;
00095 extern u_long tad_debug;
00096
00097 /* increment the index into the table
00098  */
00099 #define TAD_INDEX_INCR tad_index = (struct tad_entry*)((u_long)tad_index + \
00100                                     sizeof(struct tad_entry)); \
00101                        if ((u_long) tad_index >= \
00102                            (u_long) &tad_table[TAD_ENTRIES]) \
00103                           tad_index = tad_table;
00104
00105 /* add a log entry to the table
00106  */
00107 #define TAD_SNAPSHOT(tp, so)  tad_index->seq_no = tad_seq++; \
00108                    microtime(&(tad_index->time)); \
00109                    tad_index->snd_cwnd = tp->snd_cwnd; \
00110                    tad_index->sb_hiwat = so->so_snd.sb_hiwat; \
00111                    tad_index->sb_target_hiwat = so->so_snd.sb_net_target; \
00112                    tad_index->sb_cc = so->so_snd.sb_cc; \
00113                    tad_index->m_clused = mbstat.m_clusters - mbstat.m_clfree;\
00114                    tad_index->lport = tp->t_inpcb->inp_lport; \
00115                    tad_index->rport = tp->t_inpcb->inp_fport; \
00116                    tad_index->debug = tad_debug; \
00117                    tad_index->snd_max = tp->snd_max; \
00118                    TAD_INDEX_INCR;
00119
00120 #endif  /* TCP_AUTO_DEBUG */
00121
00122 #endif  /* __NETINET_TCP_DEBUG_H */
Generated on Wed Jan 25 15:42:33 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/netinet/TCP_FSM.H Source File

inc/netinet/TCP_FSM.H

Go to the documentation of this file.
00001
00005 /*
00006  * Copyright (c) 1982, 1986, 1993
00007  *      The Regents of the University of California.  All rights reserved.
00008  *
00009  * Redistribution and use in source and binary forms, with or without
00010  * modification, are permitted provided that the following conditions
00011  * are met:
00012  * 1. Redistributions of source code must retain the above copyright
00013  *    notice, this list of conditions and the following disclaimer.
00014  * 2. Redistributions in binary form must reproduce the above copyright
00015  *    notice, this list of conditions and the following disclaimer in the
00016  *    documentation and/or other materials provided with the distribution.
00017  * 3. All advertising materials mentioning features or use of this software
00018  *    must display the following acknowledgement:
00019  *      This product includes software developed by the University of
00020  *      California, Berkeley and its contributors.
00021  * 4. Neither the name of the University nor the names of its contributors
00022  *    may be used to endorse or promote products derived from this software
00023  *    without specific prior written permission.
00024  *
00025  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
00026  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00027  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00028  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
00029  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00030  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00031  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00032  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00033  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00034  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00035  * SUCH DAMAGE.
00036  *
00037  *      @(#)tcp_fsm.h   8.1 (Berkeley) 6/10/93
00038  * $Id: tcp_fsm.h,v 1.7 1995/11/14 20:34:34 phk Exp $
00039  */
00040
00041 #ifndef __NETINET_TCP_FSM_H
00042 #define __NETINET_TCP_FSM_H
00043
00044 /*
00045  * TCP FSM state definitions.
00046  * Per RFC793, September, 1981.
00047  */
00048
00049 #define TCP_NSTATES     11
00050
00051 #define TCPS_CLOSED             0       /* closed */
00052 #define TCPS_LISTEN             1       /* listening for connection */
00053 #define TCPS_SYN_SENT           2       /* active, have sent syn */
00054 #define TCPS_SYN_RECEIVED       3       /* have send and received syn */
00055 /* states < TCPS_ESTABLISHED are those where connections not established */
00056 #define TCPS_ESTABLISHED        4       /* established */
00057 #define TCPS_CLOSE_WAIT         5       /* rcvd fin, waiting for close */
00058 /* states > TCPS_CLOSE_WAIT are those where user has closed */
00059 #define TCPS_FIN_WAIT_1         6       /* have closed, sent fin */
00060 #define TCPS_CLOSING            7       /* closed xchd FIN; await FIN ACK */
00061 #define TCPS_LAST_ACK           8       /* had fin and close; await FIN ACK */
00062 /* states > TCPS_CLOSE_WAIT && < TCPS_FIN_WAIT_2 await ACK of FIN */
00063 #define TCPS_FIN_WAIT_2         9       /* have closed, fin is acked */
00064 #define TCPS_TIME_WAIT          10      /* in 2*msl quiet wait after close */
00065
00066 #define TCPS_HAVERCVDSYN(s)     ((s) >= TCPS_SYN_RECEIVED)
00067 #define TCPS_HAVEESTABLISHED(s) ((s) >= TCPS_ESTABLISHED)
00068 #define TCPS_HAVERCVDFIN(s)     ((s) >= TCPS_TIME_WAIT)
00069
00070 #ifdef  TCPOUTFLAGS
00071 /*
00072  * Flags used when sending segments in tcp_output.
00073  * Basic flags (TH_RST,TH_ACK,TH_SYN,TH_FIN) are totally
00074  * determined by state, with the proviso that TH_FIN is sent only
00075  * if all data queued for output is included in the segment.
00076  */
00077 static u_char   tcp_outflags[TCP_NSTATES] = {
00078     TH_RST|TH_ACK, 0, TH_SYN, TH_SYN|TH_ACK,
00079     TH_ACK, TH_ACK,
00080     TH_FIN|TH_ACK, TH_FIN|TH_ACK, TH_FIN|TH_ACK, TH_ACK, TH_ACK,
00081 };
00082 #endif
00083
00084 #ifdef KPROF
00085 int     tcp_acounts[TCP_NSTATES][PRU_NREQ];
00086 #endif
00087
00088 #ifdef  TCPSTATES
00089 char *tcpstates[] = {
00090         "CLOSED",       "LISTEN",       "SYN_SENT",     "SYN_RCVD",
00091         "ESTABLISHED",  "CLOSE_WAIT",   "FIN_WAIT_1",   "CLOSING",
00092         "LAST_ACK",     "FIN_WAIT_2",   "TIME_WAIT",
00093 };
00094 #endif
00095
00096 #endif
Generated on Wed Jan 25 15:42:33 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/netinet/TCP_SCOR.H Source File

inc/netinet/TCP_SCOR.H

Go to the documentation of this file.
00001
00005 /*
00006  * Copyright (c) 1997, Pittsburgh Supercomputing Center,
00007  * Jamshid Mahdavi, Matt Mathis, Jeffrey Semke
00008  * All rights reserved.
00009  *
00010  * Permission to use, copy, modify, and distribute this software and
00011  * its documentation for any purpose and without fee is hereby granted,
00012  * provided that the above copyright notice appear in all copies and
00013  * that both that copyright notice and this permission notice appear
00014  * in supporting documentation.
00015  *
00016  * This is experimental software under active development and may
00017  * potentially contain bugs.   Use at your own risk.
00018  *
00019  */
00020
00021 #ifndef __NETINET_TCP_SCOREBOARD_H
00022 #define __NETINET_TCP_SCOREBOARD_H
00023
00024 /**********************************************************************
00025  *
00026  *  Scoreboard module headers:
00027  *
00028  **********************************************************************/
00029
00030 /* Initialize the scoreboard
00031  */
00032 #define scrb_init(tp) { LIST_INIT(&((tp)->scrb.head));     \
00033                         (tp)->scrb.last_ack=(tp)->snd_una; \
00034                         (tp)->snd_retran_data = 0; }
00035
00036 /*
00037  *  Check to see if the scoreboard is empty
00038  *  scrb_isempty(struct tcpcp *tp)
00039  */
00040 #define scrb_isempty(tp)     (! ((tp)->scrb.scrb_head))
00041
00042 /* This macro quickly takes care of the common case of an empty
00043  *  scoreboard. Otherwise it called scrb_getnextretran_func to hunt
00044  *  through the scoreboard and return the next block of data to be
00045  *  retransmitted.  The start and end of the block are filled in to
00046  *  start_ptr and end_ptr, and the length of the block is returned.  A
00047  *  zero return value indicates that there is no data to be
00048  *  retransmitted at this time.  Note that end_ptr actually points to
00049  *  the first byte of data which is NOT to be retransmitted (or the
00050  *  first byte following the data to be retransmitted) similar in
00051  *  fashion to the rest of this code.
00052  *
00053  *  scrb_getnextretran(struct tcpcp *tp, tcp_seq *start, tcp_seq *end)
00054  */
00055
00056 #define scrb_getnextretran(tp,start,end)   \
00057            (scrb_isempty(tp) ? \
00058              (int)((tcp_seq*)*start = (tcp_seq*)*end = \
00059              (tcp_seq*)0) \
00060            : scrb_getnextretran_func(tp,start,end))
00061
00062
00063 /* sender side -- tracks packets sent that WERE selectively acknowledged
00064  * by the other end.
00065  * Each sb_entry represents a hole (missing data) followed by
00066  * consecutive received data.
00067  */
00068 struct scrb_entry {
00069       LIST_ENTRY(scrb_entry) ptrs;    /*  Next/Prev structure pointers */
00070       tcp_seq start;                  /*  Start of received data block */
00071       tcp_seq end;                    /*  End of received data block      */
00072       tcp_seq retran;                 /*  End of subsequent data
00073                                             retransmitted  */
00074       tcp_seq snd_max;                /*  Value of snd_max at the time of
00075                                             retransmission */
00076       int     sack_cnt;               /*  FACK ONLY:  Number of reports for
00077                                           this hole */
00078 };
00079
00080 #define scrb_next ptrs.le_next       /* next element */
00081 #define scrb_prev ptrs.le_prev       /* previous element */
00082
00083
00084 /* sender side -- tracks packets sent that were selectively
00085  * acknowledged by the other end
00086  */
00087 struct scoreboard {
00088       tcp_seq last_ack;               /* This value replicates snd_una,
00089                                          but is needed for internal
00090                                          scoreboard state.  */
00091       LIST_HEAD(scrb_head_internal, scrb_entry) head; /* Scoreboard list */
00092 };
00093
00094 #define scrb_head head.lh_first       /* first element of scoreboard */
00095
00096 /* return codes from routines that might have to clear the scoreboard
00097  */
00098 #define E_SCRB_CLEAR          -1
00099 #define E_SCRB_NOERR           0
00100
00101 /* reason parameters for scrb_clear
00102  */
00103 #define SCRB_INIT              0
00104 #define SCRB_RENEGE            1
00105 #define SCRB_NOMEM             2
00106 #define SCRB_TIMEOUT           3
00107
00108 #endif /* __NETINET_TCP_SCOREBOARD_H */
Generated on Wed Jan 25 15:42:33 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/netinet/TCP_SEQ.H Source File

inc/netinet/TCP_SEQ.H

Go to the documentation of this file.
00001
00005 /*
00006  * Copyright (c) 1982, 1986, 1993, 1995
00007  *      The Regents of the University of California.  All rights reserved.
00008  *
00009  * Redistribution and use in source and binary forms, with or without
00010  * modification, are permitted provided that the following conditions
00011  * are met:
00012  * 1. Redistributions of source code must retain the above copyright
00013  *    notice, this list of conditions and the following disclaimer.
00014  * 2. Redistributions in binary form must reproduce the above copyright
00015  *    notice, this list of conditions and the following disclaimer in the
00016  *    documentation and/or other materials provided with the distribution.
00017  * 3. All advertising materials mentioning features or use of this software
00018  *    must display the following acknowledgement:
00019  *      This product includes software developed by the University of
00020  *      California, Berkeley and its contributors.
00021  * 4. Neither the name of the University nor the names of its contributors
00022  *    may be used to endorse or promote products derived from this software
00023  *    without specific prior written permission.
00024  *
00025  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
00026  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00027  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00028  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
00029  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00030  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00031  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00032  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00033  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00034  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00035  * SUCH DAMAGE.
00036  *
00037  *      @(#)tcp_seq.h   8.3 (Berkeley) 6/21/95
00038  *      $Id: tcp_seq.h,v 1.6 1995/10/03 16:54:14 wollman Exp $
00039  */
00040
00041 #ifndef __NETINET_TCP_SEQ_H
00042 #define __NETINET_TCP_SEQ_H
00043
00044 /*
00045  * TCP sequence numbers are 32 bit integers operated
00046  * on with modular arithmetic.  These macros can be
00047  * used to compare such integers.
00048  */
00049 #define SEQ_LT(a,b)     ((long)((a)-(b)) < 0)
00050 #define SEQ_LEQ(a,b)    ((long)((a)-(b)) <= 0)
00051 #define SEQ_GT(a,b)     ((long)((a)-(b)) > 0)
00052 #define SEQ_GEQ(a,b)    ((long)((a)-(b)) >= 0)
00053
00054 /* for modulo comparisons of timestamps */
00055 #define TSTMP_LT(a,b)   ((long)((a)-(b)) < 0)
00056 #define TSTMP_GEQ(a,b)  ((long)((a)-(b)) >= 0)
00057
00058 /*
00059  * TCP connection counts are 32 bit integers operated
00060  * on with modular arithmetic.  These macros can be
00061  * used to compare such integers.
00062  */
00063 #define CC_LT(a,b)      ((long)((a)-(b)) < 0)
00064 #define CC_LEQ(a,b)     ((long)((a)-(b)) <= 0)
00065 #define CC_GT(a,b)      ((long)((a)-(b)) > 0)
00066 #define CC_GEQ(a,b)     ((long)((a)-(b)) >= 0)
00067
00068 /* Macro to increment a CC: skip 0 which has a special meaning */
00069 #define CC_INC(c)       (++(c) == 0 ? ++(c) : (c))
00070
00071 /*
00072  * Macros to initialize tcp sequence numbers for
00073  * send and receive from initial send and receive
00074  * sequence numbers.
00075  */
00076 #define tcp_rcvseqinit(tp) \
00077         (tp)->rcv_adv = (tp)->rcv_nxt = (tp)->irs + 1
00078
00079 #if defined(TCP_SACK)
00080 #define tcp_sendseqinit(tp) \
00081         (tp)->snd_una = (tp)->snd_nxt = (tp)->snd_max = (tp)->snd_up = \
00082             (tp)->recover = (tp)->sb.last_ack = (tp)->iss
00083
00084 #elif defined(TCP_FACK)
00085 #define tcp_sendseqinit(tp) \
00086         (tp)->snd_una = (tp)->snd_nxt = (tp)->snd_max = (tp)->snd_up = \
00087             (tp)->recover = (tp)->scrb.last_ack = (tp)->snd_fack = (tp)->iss
00088
00089 #else
00090 #define tcp_sendseqinit(tp) \
00091         (tp)->snd_una = (tp)->snd_nxt = (tp)->snd_max = (tp)->snd_up = \
00092             (tp)->iss
00093 #endif
00094
00095 #define TCP_PAWS_IDLE   (24 * 24 * 60 * 60 * PR_SLOWHZ)
00096                                    /* timestamp wrap-around time */
00097
00098 #define TCP_ISSINCR     (125*1024) /* increment for tcp_iss each second */
00099
00100 #ifdef _KERNEL
00101 tcp_seq tcp_iss;                   /* tcp initial send seq # */
00102 #endif
00103
00104 #endif
Generated on Wed Jan 25 15:42:33 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/netinet/TCP_TIME.H Source File

inc/netinet/TCP_TIME.H

Go to the documentation of this file.
00001
00005 /*
00006  * Copyright (c) 1982, 1986, 1993
00007  *      The Regents of the University of California.  All rights reserved.
00008  *
00009  * Redistribution and use in source and binary forms, with or without
00010  * modification, are permitted provided that the following conditions
00011  * are met:
00012  * 1. Redistributions of source code must retain the above copyright
00013  *    notice, this list of conditions and the following disclaimer.
00014  * 2. Redistributions in binary form must reproduce the above copyright
00015  *    notice, this list of conditions and the following disclaimer in the
00016  *    documentation and/or other materials provided with the distribution.
00017  * 3. All advertising materials mentioning features or use of this software
00018  *    must display the following acknowledgement:
00019  *      This product includes software developed by the University of
00020  *      California, Berkeley and its contributors.
00021  * 4. Neither the name of the University nor the names of its contributors
00022  *    may be used to endorse or promote products derived from this software
00023  *    without specific prior written permission.
00024  *
00025  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
00026  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00027  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00028  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
00029  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00030  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00031  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00032  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00033  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00034  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00035  * SUCH DAMAGE.
00036  *
00037  *      @(#)tcp_timer.h 8.1 (Berkeley) 6/10/93
00038  *      $Id: tcp_timer.h,v 1.10 1996/09/13 23:51:43 pst Exp $
00039  */
00040
00041 #ifndef __NETINET_TCP_TIMER_H
00042 #define __NETINET_TCP_TIMER_H
00043
00044 /*
00045  * Definitions of the TCP timers.  These timers are counted
00046  * down PR_SLOWHZ times a second.
00047  */
00048 #define TCPT_NTIMERS    4
00049
00050 #define TCPT_REXMT      0               /* retransmit */
00051 #define TCPT_PERSIST    1               /* retransmit persistence */
00052 #define TCPT_KEEP       2               /* keep alive */
00053 #define TCPT_2MSL       3               /* 2*msl quiet time timer */
00054
00055 /*
00056  * The TCPT_REXMT timer is used to force retransmissions.
00057  * The TCP has the TCPT_REXMT timer set whenever segments
00058  * have been sent for which ACKs are expected but not yet
00059  * received.  If an ACK is received which advances tp->snd_una,
00060  * then the retransmit timer is cleared (if there are no more
00061  * outstanding segments) or reset to the base value (if there
00062  * are more ACKs expected).  Whenever the retransmit timer goes off,
00063  * we retransmit one unacknowledged segment, and do a backoff
00064  * on the retransmit timer.
00065  *
00066  * The TCPT_PERSIST timer is used to keep window size information
00067  * flowing even if the window goes shut.  If all previous transmissions
00068  * have been acknowledged (so that there are no retransmissions in progress),
00069  * and the window is too small to bother sending anything, then we start
00070  * the TCPT_PERSIST timer.  When it expires, if the window is nonzero,
00071  * we go to transmit state.  Otherwise, at intervals send a single byte
00072  * into the peer's window to force him to update our window information.
00073  * We do this at most as often as TCPT_PERSMIN time intervals,
00074  * but no more frequently than the current estimate of round-trip
00075  * packet time.  The TCPT_PERSIST timer is cleared whenever we receive
00076  * a window update from the peer.
00077  *
00078  * The TCPT_KEEP timer is used to keep connections alive.  If an
00079  * connection is idle (no segments received) for TCPTV_KEEP_INIT amount of time,
00080  * but not yet established, then we drop the connection.  Once the connection
00081  * is established, if the connection is idle for TCPTV_KEEP_IDLE time
00082  * (and keepalives have been enabled on the socket), we begin to probe
00083  * the connection.  We force the peer to send us a segment by sending:
00084  *      <SEQ=SND.UNA-1><ACK=RCV.NXT><CTL=ACK>
00085  * This segment is (deliberately) outside the window, and should elicit
00086  * an ack segment in response from the peer.  If, despite the TCPT_KEEP
00087  * initiated segments we cannot elicit a response from a peer in TCPT_MAXIDLE
00088  * amount of time probing, then we drop the connection.
00089  */
00090
00091 /*
00092  * Time constants.
00093  */
00094 #define TCPTV_MSL       ( 30*PR_SLOWHZ)         /* max seg lifetime (hah!) */
00095 #define TCPTV_SRTTBASE  0                       /* base roundtrip time;
00096                                                    if 0, no idea yet */
00097 #define TCPTV_RTOBASE   (  3*PR_SLOWHZ)         /* assumed RTO if no info */
00098 #define TCPTV_SRTTDFLT  (  3*PR_SLOWHZ)         /* assumed RTT if no info */
00099
00100 #define TCPTV_PERSMIN   (  5*PR_SLOWHZ)         /* retransmit persistence */
00101 #define TCPTV_PERSMAX   ( 60*PR_SLOWHZ)         /* maximum persist interval */
00102
00103 #define TCPTV_KEEP_INIT ( 75*PR_SLOWHZ)         /* initial connect keep alive */
00104 #define TCPTV_KEEP_IDLE (120*60*PR_SLOWHZ)      /* dflt time before probing */
00105 #define TCPTV_KEEPINTVL ( 75*PR_SLOWHZ)         /* default probe interval */
00106 #define TCPTV_KEEPCNT   8                       /* max probes before drop */
00107
00108 #define TCPTV_MIN       (  1*PR_SLOWHZ)         /* minimum allowable value */
00109 #define TCPTV_REXMTMAX  ( 64*PR_SLOWHZ)         /* max allowable REXMT value */
00110
00111 #define TCPTV_TWTRUNC   8                       /* RTO factor to truncate TW */
00112
00113 #define TCP_LINGERTIME  120                     /* linger at most 2 minutes */
00114
00115 #define TCP_MAXRXTSHIFT 12                      /* maximum retransmits */
00116
00117 #ifdef  TCPTIMERS
00118 static char *tcptimers[] =
00119     { "REXMT", "PERSIST", "KEEP", "2MSL" };
00120 #endif
00121
00122 /*
00123  * Force a time value to be in a certain range.
00124  */
00125 #define TCPT_RANGESET(tv, value, tvmin, tvmax) { \
00126         (tv) = (value);                          \
00127         if ((u_long)(tv) < (u_long)(tvmin))      \
00128                 (tv) = (tvmin);                  \
00129         else if ((u_long)(tv) > (u_long)(tvmax)) \
00130                 (tv) = (tvmax);                  \
00131       }
00132
00133 #endif
Generated on Wed Jan 25 15:42:33 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/netinet/TCP_VAR.H Source File

inc/netinet/TCP_VAR.H

Go to the documentation of this file.
00001
00005 /*
00006  * Copyright (c) 1982, 1986, 1993, 1994, 1995
00007  *      The Regents of the University of California.  All rights reserved.
00008  *
00009  * Redistribution and use in source and binary forms, with or without
00010  * modification, are permitted provided that the following conditions
00011  * are met:
00012  * 1. Redistributions of source code must retain the above copyright
00013  *    notice, this list of conditions and the following disclaimer.
00014  * 2. Redistributions in binary form must reproduce the above copyright
00015  *    notice, this list of conditions and the following disclaimer in the
00016  *    documentation and/or other materials provided with the distribution.
00017  * 3. All advertising materials mentioning features or use of this software
00018  *    must display the following acknowledgement:
00019  *      This product includes software developed by the University of
00020  *      California, Berkeley and its contributors.
00021  * 4. Neither the name of the University nor the names of its contributors
00022  *    may be used to endorse or promote products derived from this software
00023  *    without specific prior written permission.
00024  *
00025  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
00026  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00027  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00028  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
00029  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00030  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00031  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00032  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00033  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00034  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00035  * SUCH DAMAGE.
00036  *
00037  *      @(#)tcp_var.h   8.4 (Berkeley) 5/24/95
00038  *      $Id: tcp_var.h,v 1.36 1996/09/13 23:54:03 pst Exp $
00039  */
00040
00041 #ifndef __NETINET_TCP_VAR_H
00042 #define __NETINET_TCP_VAR_H
00043
00044 /*
00045  * Kernel variables for tcp.
00046  */
00047
00048 #ifdef TCP_AUTO
00049   /* AUTO_RCV_HITHRESH flush reassembly queue, drop incoming packets
00050    */
00051   #define AUTO_RCV_HITHRESH   (u_long)(0.95 * NMBCLUSTERS)
00052
00053   /* AUTO_RCV_LOWTHRESH drop incoming packets
00054    */
00055   #define AUTO_RCV_LOWTHRESH  (u_long)(0.9 * NMBCLUSTERS)
00056
00057   /* AUTO_SND_THRESH reduce so_snd.sb_hiwat by acked
00058    */
00059   #define AUTO_SND_THRESH     (u_long)(0.50 * NMBCLUSTERS)
00060 #endif
00061
00062 #if defined(TCP_SACK) || defined(TCP_FACK)
00063 #include <netinet/tcp_scor.h>
00064
00065 struct sackblock {
00066        tcp_seq start;
00067        tcp_seq end;
00068      };
00069 #endif
00070
00071 /*
00072  * Tcp control block, one per tcp; fields:
00073  */
00074 struct tcpcb {
00075         struct  tcpiphdr *seg_next;     /* sequencing queue */
00076         struct  tcpiphdr *seg_prev;
00077   /* !! struct  ipqehead segq; */       /* sequencing queue */
00078         int     t_state;                /* state of this connection */
00079         int     t_timer[TCPT_NTIMERS];  /* tcp timers */
00080         int     t_rxtshift;             /* log(2) of rexmt exp. backoff */
00081         int     t_rxtcur;               /* current retransmit value */
00082 #ifdef TCP_FACK
00083         short   t_padd;                 /* filler to preserve alignment */
00084 #else
00085         short   t_dupacks;              /* consecutive dup acks recd */
00086 #endif
00087         u_int   t_maxseg;               /* maximum segment size */
00088         u_int   t_maxopd;               /* mss plus options */
00089         int     t_force;                /* 1 if forcing out a byte */
00090         u_int   t_flags;
00091 #define TF_ACKNOW       0x0001          /* ack peer immediately */
00092 #define TF_DELACK       0x0002          /* ack, but try to delay it */
00093 #define TF_NODELAY      0x0004          /* don't delay packets to coalesce */
00094 #define TF_NOOPT        0x0008          /* don't use tcp options */
00095 #define TF_SENTFIN      0x0010          /* have sent FIN */
00096 #define TF_REQ_SCALE    0x0020          /* have/will request window scaling */
00097 #define TF_RCVD_SCALE   0x0040          /* other side has requested scaling */
00098 #define TF_REQ_TSTMP    0x0080          /* have/will request timestamps */
00099 #define TF_RCVD_TSTMP   0x0100          /* a timestamp was received in SYN */
00100 #define TF_SACK_PERMIT  0x0200          /* other side said I could SACK */
00101 #define TF_NEEDSYN      0x0400          /* send SYN (implicit state) */
00102 #define TF_NEEDFIN      0x0800          /* send FIN (implicit state) */
00103 #define TF_NOPUSH       0x1000          /* don't push */
00104 #define TF_REQ_CC       0x2000          /* have/will request CC */
00105 #define TF_RCVD_CC      0x4000          /* a CC was received in SYN */
00106 #define TF_SENDCCNEW    0x8000          /* send CCnew instead of CC in SYN */
00107
00108         struct  tcpiphdr *t_template;   /* skeletal packet for transmit */
00109         struct  inpcb *t_inpcb;         /* back pointer to internet pcb */
00110 /*
00111  * The following fields are used as in the protocol specification.
00112  * See RFC783, Dec. 1981, page 21.
00113  */
00114 /* send sequence variables */
00115         tcp_seq snd_una;                /* send unacknowledged */
00116         tcp_seq snd_nxt;                /* send next */
00117         tcp_seq snd_up;                 /* send urgent pointer */
00118         tcp_seq snd_wl1;                /* window update seg seq number */
00119         tcp_seq snd_wl2;                /* window update seg ack number */
00120         tcp_seq iss;                    /* initial send sequence number */
00121         u_long  snd_wnd;                /* send window */
00122 /* receive sequence variables */
00123         u_long  rcv_wnd;                /* receive window */
00124         tcp_seq rcv_nxt;                /* receive next */
00125         tcp_seq rcv_up;                 /* receive urgent pointer */
00126         tcp_seq irs;                    /* initial receive sequence number */
00127 /*
00128  * Additional variables for this implementation.
00129  */
00130 /* receive variables */
00131         tcp_seq rcv_adv;                /* advertised window */
00132 /* retransmit variables */
00133         tcp_seq snd_max;                /* highest sequence number sent;
00134                                          * used to recognize retransmits
00135                                          */
00136 /* congestion control (for slow start, source quench, retransmit after loss) */
00137         u_long  snd_cwnd;               /* congestion-controlled window */
00138         u_long  snd_ssthresh;           /* snd_cwnd size threshold for
00139                                          * for slow start exponential to
00140                                          * linear switch
00141                                          */
00142 /*
00143  * transmit timing stuff.  See below for scale of srtt and rttvar.
00144  * "Variance" is actually smoothed difference.
00145  */
00146         u_int   t_idle;                 /* inactivity time */
00147         int     t_rtt;                  /* round trip time */
00148         tcp_seq t_rtseq;                /* sequence number being timed */
00149         int     t_srtt;                 /* smoothed round-trip time */
00150         int     t_rttvar;               /* variance in round-trip time */
00151         u_int   t_rttmin;               /* minimum rtt allowed */
00152         u_long  max_sndwnd;             /* largest window peer has offered */
00153
00154 /* out-of-band data */
00155         char    t_oobflags;             /* have some */
00156         char    t_iobc;                 /* input character */
00157 #define TCPOOB_HAVEDATA 0x01
00158 #define TCPOOB_HADDATA  0x02
00159         int     t_softerror;            /* possible error not yet reported */
00160
00161 /* RFC 1323 variables */
00162         u_char  snd_scale;              /* window scaling for send window */
00163         u_char  rcv_scale;              /* window scaling for recv window */
00164         u_char  request_r_scale;        /* pending window scaling */
00165         u_char  requested_s_scale;
00166         u_long  ts_recent;              /* timestamp echo data */
00167         u_long  ts_recent_age;          /* when last updated */
00168         tcp_seq last_ack_sent;
00169 /* RFC 1644 variables */
00170         tcp_cc  cc_send;                /* send connection count */
00171         tcp_cc  cc_recv;                /* receive connection count */
00172         u_long  t_duration;             /* connection duration */
00173
00174 /* TUBA stuff */
00175         caddr_t t_tuba_pcb;             /* next level down pcb for TCP over z */
00176 /* More RTT stuff */
00177         u_long  t_rttupdated;           /* number of times rtt sampled */
00178
00179 #if defined(TCP_FACK) || defined(TCP_AUTO)
00180         u_short t_alt_flags;   /* experimental flags */
00181 #define TAF_SACK_SEEN   0x0001 /* other side can send SACKs */
00182 #define TAF_RECOVERY    0x0002 /* We are recovering from a lost segment */
00183 #define TAF_RATEHALF    0x0004 /* We are reducing the window during recovery */
00184 #define TAF_REPAIRED    0x0008 /* We have retransmitted something */
00185 #define TAF_WHOLD       0x0010 /* we are in the window hold state */
00186 #define TAF_TOGGLE      0x0020 /* divide by 2 toggle */
00187 #define TAF_AUTO_OFF    0x0040 /* autotuning is forced off */
00188 #endif
00189
00190 #if defined(TCP_SACK) || defined(TCP_FACK)
00191 #define SACK_LIST_LEN 10
00192
00193 /* Needed for SACK and FACK:  */
00194         struct sackblock sack_list[SACK_LIST_LEN];  /*  Hack, keep 5 most recent SACKs  */
00195         struct scoreboard scrb;
00196         int snd_retran_data;
00197         tcp_seq recover;
00198 #endif
00199 #ifdef TCP_SACK
00200         int pipe;
00201 #endif
00202 #ifdef TCP_FACK
00203         tcp_seq snd_fack;
00204 #define TCP_FACK_REXMTTHRESH 3    /* number of SACKs before retransmitting a block */
00205         u_long lothresh;                /* recovery window floor */
00206         u_long hithresh;                /* maximum window following recovery */
00207 #endif
00208 };
00209
00210 /*
00211  * Structure to hold TCP options that are only used during segment
00212  * processing (in tcp_input), but not held in the tcpcb.
00213  * It's basically used to reduce the number of parameters
00214  * to tcp_dooptions.
00215  */
00216 struct tcpopt {
00217         u_long  to_flag;                /* which options are present */
00218 #define TOF_TS          0x0001          /* timestamp */
00219 #define TOF_CC          0x0002          /* CC and CCnew are exclusive */
00220 #define TOF_CCNEW       0x0004
00221 #define TOF_CCECHO      0x0008
00222         u_long  to_tsval;
00223         u_long  to_tsecr;
00224         tcp_cc  to_cc;          /* holds CC or CCnew */
00225         tcp_cc  to_ccecho;
00226 };
00227
00228 /*
00229  * The TAO cache entry which is stored in the protocol family specific
00230  * portion of the route metrics.
00231  */
00232 struct rmxp_tao {
00233         tcp_cc  tao_cc;                 /* latest CC in valid SYN */
00234         tcp_cc  tao_ccsent;             /* latest CC sent to peer */
00235         u_short tao_mssopt;             /* peer's cached MSS */
00236 #ifdef notyet
00237         u_short tao_flags;              /* cache status flags */
00238 #define TAOF_DONT       0x0001          /* peer doesn't understand rfc1644 */
00239 #define TAOF_OK         0x0002          /* peer does understand rfc1644 */
00240 #define TAOF_UNDEF      0               /* we don't know yet */
00241 #endif /* notyet */
00242 };
00243 #define rmx_taop(r)     ((struct rmxp_tao *)(r).rmx_filler)
00244
00245 #define intotcpcb(ip)   ((struct tcpcb *)(ip)->inp_ppcb)
00246 #define sototcpcb(so)   (intotcpcb(sotoinpcb(so)))
00247
00248 /*
00249  * The smoothed round-trip time and estimated variance
00250  * are stored as fixed point numbers scaled by the values below.
00251  * For convenience, these scales are also used in smoothing the average
00252  * (smoothed = (1/scale)sample + ((scale-1)/scale)smoothed).
00253  * With these scales, srtt has 3 bits to the right of the binary point,
00254  * and thus an "ALPHA" of 0.875.  rttvar has 2 bits to the right of the
00255  * binary point, and is smoothed with an ALPHA of 0.75.
00256  */
00257 #define TCP_RTT_SCALE           32      /* multiplier for srtt; 3 bits frac. */
00258 #define TCP_RTT_SHIFT           5       /* shift for srtt; 3 bits frac. */
00259 #define TCP_RTTVAR_SCALE        16      /* multiplier for rttvar; 2 bits */
00260 #define TCP_RTTVAR_SHIFT        4       /* shift for rttvar; 2 bits */
00261 #define TCP_DELTA_SHIFT         2       /* see tcp_input.c */
00262
00263 /*
00264  * The initial retransmission should happen at rtt + 4 * rttvar.
00265  * Because of the way we do the smoothing, srtt and rttvar
00266  * will each average +1/2 tick of bias.  When we compute
00267  * the retransmit timer, we want 1/2 tick of rounding and
00268  * 1 extra tick because of +-1/2 tick uncertainty in the
00269  * firing of the timer.  The bias will give us exactly the
00270  * 1.5 tick we need.  But, because the bias is
00271  * statistical, we have to test that we don't drop below
00272  * the minimum feasible timer (which is 2 ticks).
00273  * This version of the macro adapted from a paper by Lawrence
00274  * Brakmo and Larry Peterson which outlines a problem caused
00275  * by insufficient precision in the original implementation,
00276  * which results in inappropriately large RTO values for very
00277  * fast networks.
00278  */
00279 #define TCP_REXMTVAL(tp) \
00280         ((((tp)->t_srtt >> (TCP_RTT_SHIFT - TCP_DELTA_SHIFT))  \
00281           + (tp)->t_rttvar) >> TCP_DELTA_SHIFT)
00282
00283 /* XXX
00284  * We want to avoid doing m_pullup on incoming packets but that
00285  * means avoiding dtom on the tcp reassembly code.  That in turn means
00286  * keeping an mbuf pointer in the reassembly queue (since we might
00287  * have a cluster).  As a quick hack, the source & destination
00288  * port numbers (which are no longer needed once we've located the
00289  * tcpcb) are overlayed with an mbuf pointer.
00290  */
00291 #define REASS_MBUF(ti) (*(struct mbuf **)&((ti)->ti_t))
00292
00293 /*
00294  * TCP statistics.
00295  * Many of these should be kept per connection,
00296  * but that's inconvenient at the moment.
00297  */
00298 struct  tcpstat {
00299         u_long  tcps_connattempt;       /* connections initiated */
00300         u_long  tcps_accepts;           /* connections accepted */
00301         u_long  tcps_connects;          /* connections established */
00302         u_long  tcps_drops;             /* connections dropped */
00303         u_long  tcps_conndrops;         /* embryonic connections dropped */
00304         u_long  tcps_closed;            /* conn. closed (includes drops) */
00305         u_long  tcps_segstimed;         /* segs where we tried to get rtt */
00306         u_long  tcps_rttupdated;        /* times we succeeded */
00307         u_long  tcps_delack;            /* delayed acks sent */
00308         u_long  tcps_timeoutdrop;       /* conn. dropped in rxmt timeout */
00309         u_long  tcps_rexmttimeo;        /* retransmit timeouts */
00310         u_long  tcps_persisttimeo;      /* persist timeouts */
00311         u_long  tcps_keeptimeo;         /* keepalive timeouts */
00312         u_long  tcps_keepprobe;         /* keepalive probes sent */
00313         u_long  tcps_keepdrops;         /* connections dropped in keepalive */
00314
00315         u_long  tcps_sndtotal;          /* total packets sent */
00316         u_long  tcps_sndpack;           /* data packets sent */
00317         u_long  tcps_sndbyte;           /* data bytes sent */
00318         u_long  tcps_sndrexmitpack;     /* data packets retransmitted */
00319         u_long  tcps_sndrexmitbyte;     /* data bytes retransmitted */
00320         u_long  tcps_sndacks;           /* ack-only packets sent */
00321         u_long  tcps_sndprobe;          /* window probes sent */
00322         u_long  tcps_sndurg;            /* packets sent with URG only */
00323         u_long  tcps_sndwinup;          /* window update-only packets sent */
00324         u_long  tcps_sndctrl;           /* control (SYN|FIN|RST) packets sent */
00325
00326         u_long  tcps_rcvtotal;          /* total packets received */
00327         u_long  tcps_rcvpack;           /* packets received in sequence */
00328         u_long  tcps_rcvbyte;           /* bytes received in sequence */
00329         u_long  tcps_rcvbadsum;         /* packets received with ccksum errs */
00330         u_long  tcps_rcvbadoff;         /* packets received with bad offset */
00331         u_long  tcps_rcvshort;          /* packets received too short */
00332         u_long  tcps_rcvduppack;        /* duplicate-only packets received */
00333         u_long  tcps_rcvdupbyte;        /* duplicate-only bytes received */
00334         u_long  tcps_rcvpartduppack;    /* packets with some duplicate data */
00335         u_long  tcps_rcvpartdupbyte;    /* dup. bytes in part-dup. packets */
00336         u_long  tcps_rcvoopack;         /* out-of-order packets received */
00337         u_long  tcps_rcvoobyte;         /* out-of-order bytes received */
00338         u_long  tcps_rcvpackafterwin;   /* packets with data after window */
00339         u_long  tcps_rcvbyteafterwin;   /* bytes rcvd after window */
00340         u_long  tcps_rcvafterclose;     /* packets rcvd after "close" */
00341         u_long  tcps_rcvwinprobe;       /* rcvd window probe packets */
00342         u_long  tcps_rcvdupack;         /* rcvd duplicate acks */
00343         u_long  tcps_rcvacktoomuch;     /* rcvd acks for unsent data */
00344         u_long  tcps_rcvackpack;        /* rcvd ack packets */
00345         u_long  tcps_rcvackbyte;        /* bytes acked by rcvd acks */
00346         u_long  tcps_rcvwinupd;         /* rcvd window update packets */
00347         u_long  tcps_pawsdrop;          /* segments dropped due to PAWS */
00348         u_long  tcps_predack;           /* times hdr predict ok for acks */
00349         u_long  tcps_preddat;           /* times hdr predict ok for data pkts */
00350         u_long  tcps_pcbcachemiss;
00351         u_long  tcps_cachedrtt;         /* times cached RTT in route updated */
00352         u_long  tcps_cachedrttvar;      /* times cached rttvar updated */
00353         u_long  tcps_cachedssthresh;    /* times cached ssthresh updated */
00354         u_long  tcps_usedrtt;           /* times RTT initialized from route */
00355         u_long  tcps_usedrttvar;        /* times RTTVAR initialized from rt */
00356         u_long  tcps_usedssthresh;      /* times ssthresh initialized from rt*/
00357         u_long  tcps_persistdrop;       /* timeout in persist state */
00358         u_long  tcps_badsyn;            /* bogus SYN, e.g. premature ACK */
00359         u_long  tcps_mturesent;         /* resends due to MTU discovery */
00360         u_long  tcps_listendrop;        /* listen queue overflows */
00361
00362 #ifdef TCP_FACK
00363        /* NOTE: This may break some programs that rely on this structure
00364         * being fixed length.
00365         */
00366         u_long  tcps_fack_recovery;     /* fack: recovery episodes */
00367         u_long  tcps_fack_sndpack;      /* fack: data packets sent */
00368         u_long  tcps_fack_sndbyte;      /* fack: data bytes sent */
00369         u_long  tcps_fack_sndrexmitpack;/* fack: data packets retransmitted */
00370         u_long  tcps_fack_sndrexmitbyte;/* fack: data bytes retransmitted */
00371 #endif
00372 };
00373
00374 /*
00375  * Names for TCP sysctl objects
00376  */
00377 #define TCPCTL_DO_RFC1323       1       /* use RFC-1323 extensions */
00378 #define TCPCTL_DO_RFC1644       2       /* use RFC-1644 extensions */
00379 #define TCPCTL_MSSDFLT          3       /* MSS default */
00380 #define TCPCTL_STATS            4       /* statistics (read-only) */
00381 #define TCPCTL_RTTDFLT          5       /* default RTT estimate */
00382 #define TCPCTL_KEEPIDLE         6       /* keepalive idle timer */
00383 #define TCPCTL_KEEPINTVL        7       /* interval to send keepalives */
00384 #define TCPCTL_SENDSPACE        8       /* send buffer space */
00385 #define TCPCTL_RECVSPACE        9       /* receive buffer space */
00386 #define TCPCTL_KEEPINIT         10      /* receive buffer space */
00387 #define TCPCTL_MAXID            11
00388
00389 #define TCPCTL_NAMES { \
00390         { 0, 0 }, \
00391         { "rfc1323", CTLTYPE_INT }, \
00392         { "rfc1644", CTLTYPE_INT }, \
00393         { "mssdflt", CTLTYPE_INT }, \
00394         { "stats", CTLTYPE_STRUCT }, \
00395         { "rttdflt", CTLTYPE_INT }, \
00396         { "keepidle", CTLTYPE_INT }, \
00397         { "keepintvl", CTLTYPE_INT }, \
00398         { "sendspace", CTLTYPE_INT }, \
00399         { "recvspace", CTLTYPE_INT }, \
00400         { "keepinit", CTLTYPE_INT }, \
00401 }
00402
00403 #endif
Generated on Wed Jan 25 15:42:33 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/netinet/TCPIP.H Source File

inc/netinet/TCPIP.H

Go to the documentation of this file.
00001
00005 /*
00006  * Copyright (c) 1982, 1986, 1993
00007  *      The Regents of the University of California.  All rights reserved.
00008  *
00009  * Redistribution and use in source and binary forms, with or without
00010  * modification, are permitted provided that the following conditions
00011  * are met:
00012  * 1. Redistributions of source code must retain the above copyright
00013  *    notice, this list of conditions and the following disclaimer.
00014  * 2. Redistributions in binary form must reproduce the above copyright
00015  *    notice, this list of conditions and the following disclaimer in the
00016  *    documentation and/or other materials provided with the distribution.
00017  * 3. All advertising materials mentioning features or use of this software
00018  *    must display the following acknowledgement:
00019  *      This product includes software developed by the University of
00020  *      California, Berkeley and its contributors.
00021  * 4. Neither the name of the University nor the names of its contributors
00022  *    may be used to endorse or promote products derived from this software
00023  *    without specific prior written permission.
00024  *
00025  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
00026  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00027  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00028  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
00029  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00030  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00031  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00032  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00033  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00034  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00035  * SUCH DAMAGE.
00036  *
00037  *      @(#)tcpip.h     8.1 (Berkeley) 6/10/93
00038  * $Id: tcpip.h,v 1.4 1995/02/08 20:18:48 wollman Exp $
00039  */
00040
00041 #ifndef __NETINET_TCPIP_H
00042 #define __NETINET_TCPIP_H
00043
00044 #include <sys/packon.h>
00045
00046 /*
00047  * Tcp+ip header, after ip options removed.
00048  */
00049 struct tcpiphdr {
00050         struct  ipovly ti_i;            /* overlaid ip structure */
00051         struct  tcphdr ti_t;            /* tcp header */
00052 };
00053
00054 #ifdef notyet
00055 /*
00056  * Tcp+ip header, after ip options removed but including TCP options.
00057  */
00058 struct full_tcpiphdr {
00059         struct  ipovly ti_i;            /* overlaid ip structure */
00060         struct  tcphdr ti_t;            /* tcp header */
00061         char    ti_o[TCP_MAXOLEN];      /* space for tcp options */
00062 };
00063 #endif /* notyet */
00064
00065 #include <sys/packoff.h>
00066
00067 #define ti_next         ti_i.ih_next
00068 #define ti_prev         ti_i.ih_prev
00069 #define ti_x1           ti_i.ih_x1
00070 #define ti_pr           ti_i.ih_pr
00071 #define ti_len          ti_i.ih_len
00072 #define ti_src          ti_i.ih_src
00073 #define ti_dst          ti_i.ih_dst
00074 #define ti_sport        ti_t.th_sport
00075 #define ti_dport        ti_t.th_dport
00076 #define ti_seq          ti_t.th_seq
00077 #define ti_ack          ti_t.th_ack
00078 #define ti_x2           ti_t.th_x2
00079 #define ti_off          ti_t.th_off
00080 #define ti_flags        ti_t.th_flags
00081 #define ti_win          ti_t.th_win
00082 #define ti_sum          ti_t.th_sum
00083 #define ti_urp          ti_t.th_urp
00084
00085 #endif
Generated on Wed Jan 25 15:42:33 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/netinet/UDP.H Source File

inc/netinet/UDP.H

Go to the documentation of this file.
00001
00004 /*
00005  * Copyright (c) 1982, 1986, 1993
00006  *      The Regents of the University of California.  All rights reserved.
00007  *
00008  * Redistribution and use in source and binary forms, with or without
00009  * modification, are permitted provided that the following conditions
00010  * are met:
00011  * 1. Redistributions of source code must retain the above copyright
00012  *    notice, this list of conditions and the following disclaimer.
00013  * 2. Redistributions in binary form must reproduce the above copyright
00014  *    notice, this list of conditions and the following disclaimer in the
00015  *    documentation and/or other materials provided with the distribution.
00016  * 3. All advertising materials mentioning features or use of this software
00017  *    must display the following acknowledgement:
00018  *      This product includes software developed by the University of
00019  *      California, Berkeley and its contributors.
00020  * 4. Neither the name of the University nor the names of its contributors
00021  *    may be used to endorse or promote products derived from this software
00022  *    without specific prior written permission.
00023  *
00024  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
00025  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00026  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00027  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
00028  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00029  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00030  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00031  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00032  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00033  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00034  * SUCH DAMAGE.
00035  *
00036  *      @(#)udp.h       8.1 (Berkeley) 6/10/93
00037  * $FreeBSD: src/sys/netinet/udp.h,v 1.7 1999/08/28 00:49:34 peter Exp $
00038  */
00039
00040 #ifndef _NETINET_UDP_H_
00041 #define _NETINET_UDP_H_
00042
00043 /*
00044  * Udp protocol header.
00045  * Per RFC 768, September, 1981.
00046  */
00047 struct udphdr {
00048         u_short uh_sport;               /* source port */
00049         u_short uh_dport;               /* destination port */
00050         u_short uh_ulen;                /* udp length */
00051         u_short uh_sum;                 /* udp checksum */
00052 };
00053
00054 #endif
Generated on Wed Jan 25 15:42:33 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/netinet/UDP_VAR.H Source File

inc/netinet/UDP_VAR.H

Go to the documentation of this file.
00001
00005 /*
00006  * Copyright (c) 1982, 1986, 1989, 1993
00007  *      The Regents of the University of California.  All rights reserved.
00008  *
00009  * Redistribution and use in source and binary forms, with or without
00010  * modification, are permitted provided that the following conditions
00011  * are met:
00012  * 1. Redistributions of source code must retain the above copyright
00013  *    notice, this list of conditions and the following disclaimer.
00014  * 2. Redistributions in binary form must reproduce the above copyright
00015  *    notice, this list of conditions and the following disclaimer in the
00016  *    documentation and/or other materials provided with the distribution.
00017  * 3. All advertising materials mentioning features or use of this software
00018  *    must display the following acknowledgement:
00019  *      This product includes software developed by the University of
00020  *      California, Berkeley and its contributors.
00021  * 4. Neither the name of the University nor the names of its contributors
00022  *    may be used to endorse or promote products derived from this software
00023  *    without specific prior written permission.
00024  *
00025  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
00026  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00027  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00028  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
00029  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00030  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00031  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00032  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00033  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00034  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00035  * SUCH DAMAGE.
00036  *
00037  *      @(#)udp_var.h   8.1 (Berkeley) 6/10/93
00038  * $Id: udp_var.h,v 1.9 1996/06/05 17:20:35 wollman Exp $
00039  */
00040
00041 #ifndef __NETINET_UDP_VAR_H
00042 #define __NETINET_UDP_VAR_H
00043
00044 /*
00045  * UDP kernel structures and variables.
00046  */
00047 #ifdef NOT_NEEDED
00048   #include <sys/packon.h>
00049   struct  udpiphdr {
00050           struct  ipovly ui_i;            /* overlaid ip structure */
00051           struct  udphdr ui_u;            /* udp header */
00052         };
00053   #include <sys/packoff.h>
00054
00055   #define ui_next         ui_i.ih_next
00056   #define ui_prev         ui_i.ih_prev
00057   #define ui_x1           ui_i.ih_x1
00058   #define ui_pr           ui_i.ih_pr
00059   #define ui_len          ui_i.ih_len
00060   #define ui_src          ui_i.ih_src
00061   #define ui_dst          ui_i.ih_dst
00062   #define ui_sport        ui_u.uh_sport
00063   #define ui_dport        ui_u.uh_dport
00064   #define ui_ulen         ui_u.uh_ulen
00065   #define ui_sum          ui_u.uh_sum
00066 #endif
00067
00068 struct  udpstat {
00069         /* input statistics: */
00070         u_long  udps_ipackets;          /* total input packets */
00071         u_long  udps_hdrops;            /* packet shorter than header */
00072         u_long  udps_badsum;            /* checksum error */
00073         u_long  udps_badlen;            /* data length larger than packet */
00074         u_long  udps_noport;            /* no socket on port */
00075         u_long  udps_noportbcast;       /* of above, arrived as broadcast */
00076         u_long  udps_fullsock;          /* not delivered, input socket full */
00077         u_long  udpps_pcbcachemiss;     /* input packets missing pcb cache */
00078         u_long  udpps_pcbhashmiss;      /* input packets not for hashed pcb */
00079                                 /* output statistics: */
00080         u_long  udps_opackets;          /* total output packets */
00081 };
00082
00083 /*
00084  * Names for UDP sysctl objects
00085  */
00086 #define UDPCTL_CHECKSUM         1       /* checksum UDP packets */
00087 #define UDPCTL_STATS            2       /* statistics (read-only) */
00088 #define UDPCTL_MAXDGRAM         3       /* max datagram size */
00089 #define UDPCTL_RECVSPACE        4       /* default receive buffer space */
00090 #define UDPCTL_MAXID            5
00091
00092 #define UDPCTL_NAMES { \
00093         { 0, 0 }, \
00094         { "checksum", CTLTYPE_INT }, \
00095         { "stats", CTLTYPE_STRUCT }, \
00096         { "maxdgram", CTLTYPE_INT }, \
00097         { "recvspace", CTLTYPE_INT }, \
00098 }
00099
00100 #endif
Generated on Wed Jan 25 15:42:33 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/netinet6/AH.H Source File

inc/netinet6/AH.H

Go to the documentation of this file.
00001
00005 /*      $FreeBSD: src/sys/netinet6/ah.h,v 1.7 2002/04/19 04:46:22 suz Exp $     */
00006 /*      $KAME: ah.h,v 1.16 2001/09/04 08:43:19 itojun Exp $     */
00007
00008 /*
00009  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
00010  * All rights reserved.
00011  *
00012  * Redistribution and use in source and binary forms, with or without
00013  * modification, are permitted provided that the following conditions
00014  * are met:
00015  * 1. Redistributions of source code must retain the above copyright
00016  *    notice, this list of conditions and the following disclaimer.
00017  * 2. Redistributions in binary form must reproduce the above copyright
00018  *    notice, this list of conditions and the following disclaimer in the
00019  *    documentation and/or other materials provided with the distribution.
00020  * 3. Neither the name of the project nor the names of its contributors
00021  *    may be used to endorse or promote products derived from this software
00022  *    without specific prior written permission.
00023  *
00024  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
00025  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00026  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00027  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
00028  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00029  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00030  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00031  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00032  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00033  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00034  * SUCH DAMAGE.
00035  */
00036
00037 /*
00038  * RFC1826/2402 authentication header.
00039  */
00040
00041 #ifndef _NETINET6_AH_H_
00042 #define _NETINET6_AH_H_
00043
00044 #if defined(_KERNEL) && !defined(_LKM)
00045 #include "opt_inet.h"
00046 #endif
00047
00048 struct ah {
00049         u_int8_t        ah_nxt;         /* Next Header */
00050         u_int8_t        ah_len;         /* Length of data, in 32bit */
00051         u_int16_t       ah_reserve;     /* Reserved for future use */
00052         u_int32_t       ah_spi;         /* Security parameter index */
00053         /* variable size, 32bit bound*/ /* Authentication data */
00054 };
00055
00056 struct newah {
00057         u_int8_t        ah_nxt;         /* Next Header */
00058         u_int8_t        ah_len;         /* Length of data + 1, in 32bit */
00059         u_int16_t       ah_reserve;     /* Reserved for future use */
00060         u_int32_t       ah_spi;         /* Security parameter index */
00061         u_int32_t       ah_seq;         /* Sequence number field */
00062         /* variable size, 32bit bound*/ /* Authentication data */
00063 };
00064
00065 #ifdef _KERNEL
00066 struct secasvar;
00067
00068 struct ah_algorithm_state {
00069         struct secasvar *sav;
00070         void* foo;      /* per algorithm data - maybe */
00071 };
00072
00073 struct ah_algorithm {
00074         int (*sumsiz) __P((struct secasvar *));
00075         int (*mature) __P((struct secasvar *));
00076         int keymin;     /* in bits */
00077         int keymax;     /* in bits */
00078         const char *name;
00079         int (*init) __P((struct ah_algorithm_state *, struct secasvar *));
00080         void (*update) __P((struct ah_algorithm_state *, caddr_t, size_t));
00081         void (*result) __P((struct ah_algorithm_state *, caddr_t));
00082 };
00083
00084 #define AH_MAXSUMSIZE   16
00085
00086 extern const struct ah_algorithm *ah_algorithm_lookup __P((int));
00087
00088 /* cksum routines */
00089 extern int ah_hdrlen __P((struct secasvar *));
00090
00091 extern size_t ah_hdrsiz __P((struct ipsecrequest *));
00092 extern void ah4_input __P((struct mbuf *, int));
00093 extern int ah4_output __P((struct mbuf *, struct ipsecrequest *));
00094 extern int ah4_calccksum __P((struct mbuf *, caddr_t, size_t,
00095         const struct ah_algorithm *, struct secasvar *));
00096 #endif /* _KERNEL */
00097
00098 #endif /* _NETINET6_AH_H_ */
Generated on Wed Jan 25 15:42:33 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/netinet6/AH6.H Source File

inc/netinet6/AH6.H

Go to the documentation of this file.
00001
00005 /*      $FreeBSD: src/sys/netinet6/ah6.h,v 1.4 2001/06/11 12:39:03 ume Exp $    */
00006 /*      $KAME: ah.h,v 1.13 2000/10/18 21:28:00 itojun Exp $     */
00007
00008 /*
00009  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
00010  * All rights reserved.
00011  *
00012  * Redistribution and use in source and binary forms, with or without
00013  * modification, are permitted provided that the following conditions
00014  * are met:
00015  * 1. Redistributions of source code must retain the above copyright
00016  *    notice, this list of conditions and the following disclaimer.
00017  * 2. Redistributions in binary form must reproduce the above copyright
00018  *    notice, this list of conditions and the following disclaimer in the
00019  *    documentation and/or other materials provided with the distribution.
00020  * 3. Neither the name of the project nor the names of its contributors
00021  *    may be used to endorse or promote products derived from this software
00022  *    without specific prior written permission.
00023  *
00024  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
00025  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00026  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00027  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
00028  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00029  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00030  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00031  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00032  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00033  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00034  * SUCH DAMAGE.
00035  */
00036
00037 /*
00038  * RFC1826/2402 authentication header.
00039  */
00040
00041 #ifndef _NETINET6_AH6_H_
00042 #define _NETINET6_AH6_H_
00043
00044 #ifdef _KERNEL
00045 struct secasvar;
00046
00047 extern int ah6_input (struct mbuf **, int *, int));
00048 extern int ah6_output (struct mbuf *, u_char *, struct mbuf *,
00049                        struct ipsecrequest *);
00050 extern int ah6_calccksum (struct mbuf *, caddr_t, size_t,
00051                           const struct ah_algorithm *, struct secasvar *);
00052
00053 extern void ah6_ctlinput (int, struct sockaddr *, void *);
00054 #endif
00055
00056 #endif /*_NETINET6_AH6_H_*/
Generated on Wed Jan 25 15:42:33 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/netinet6/ESP.H Source File

inc/netinet6/ESP.H

Go to the documentation of this file.
00001
00005 /*      $FreeBSD: src/sys/netinet6/esp.h,v 1.6 2002/04/19 04:46:22 suz Exp $    */
00006 /*      $KAME: esp.h,v 1.19 2001/09/04 08:43:19 itojun Exp $    */
00007
00008 /*
00009  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
00010  * All rights reserved.
00011  *
00012  * Redistribution and use in source and binary forms, with or without
00013  * modification, are permitted provided that the following conditions
00014  * are met:
00015  * 1. Redistributions of source code must retain the above copyright
00016  *    notice, this list of conditions and the following disclaimer.
00017  * 2. Redistributions in binary form must reproduce the above copyright
00018  *    notice, this list of conditions and the following disclaimer in the
00019  *    documentation and/or other materials provided with the distribution.
00020  * 3. Neither the name of the project nor the names of its contributors
00021  *    may be used to endorse or promote products derived from this software
00022  *    without specific prior written permission.
00023  *
00024  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
00025  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00026  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00027  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
00028  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00029  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00030  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00031  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00032  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00033  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00034  * SUCH DAMAGE.
00035  */
00036
00037 /*
00038  * RFC1827/2406 Encapsulated Security Payload.
00039  */
00040
00041 #ifndef _NETINET6_ESP_H_
00042 #define _NETINET6_ESP_H_
00043
00044 #if defined(_KERNEL) && !defined(_LKM)
00045 #include "opt_inet.h"
00046 #endif
00047
00048 struct esp {
00049        u_int32_t       esp_spi;        /* ESP */
00050        /* variable size, 32bit bound *//* Initialization Vector */
00051        /* variable size */             /* Payload data */
00052        /* variable size */             /* padding */
00053        /* 8bit */                      /* pad size */
00054        /* 8bit */                      /* next header */
00055        /* 8bit */                      /* next header */
00056        /* variable size, 32bit bound */ /* Authentication data (new IPsec) */
00057      };
00058
00059 struct newesp {
00060        u_int32_t       esp_spi;        /* ESP */
00061        u_int32_t       esp_seq;        /* Sequence number */
00062        /* variable size */             /* (IV and) Payload data */
00063        /* variable size */             /* padding */
00064        /* 8bit */                      /* pad size */
00065        /* 8bit */                      /* next header */
00066        /* 8bit */                      /* next header */
00067        /* variable size, 32bit bound *//* Authentication data */
00068      };
00069
00070 struct esptail {
00071        u_int8_t        esp_padlen;     /* pad length */
00072        u_int8_t        esp_nxt;        /* Next header */
00073        /* variable size, 32bit bound *//* Authentication data (new IPsec)*/
00074      };
00075
00076 #ifdef _KERNEL
00077 struct secasvar;
00078
00079 struct esp_algorithm {
00080        size_t padbound;                 /* pad boundary, in byte */
00081        int    ivlenval;                 /* iv length, in byte */
00082        int  (*mature) (struct secasvar *);
00083        int    keymin;                   /* in bits */
00084        int    keymax;                   /* in bits */
00085        int  (*schedlen) (const struct esp_algorithm *);
00086        const char *name;
00087        int  (*ivlen) (const struct esp_algorithm *, struct secasvar *);
00088        int  (*decrypt) (struct mbuf *, size_t,
00089                        struct secasvar *, const struct esp_algorithm *, int);
00090        int  (*encrypt) (struct mbuf *, size_t, size_t,
00091                        struct secasvar *, const struct esp_algorithm *, int);
00092        /* not supposed to be called directly */
00093        int  (*schedule) (const struct esp_algorithm *, struct secasvar *);
00094        int  (*blockdecrypt) (const struct esp_algorithm *,
00095                              struct secasvar *, u_int8_t *, u_int8_t *);
00096        int  (*blockencrypt) (const struct esp_algorithm *,
00097                              struct secasvar *, u_int8_t *, u_int8_t *);
00098      };
00099
00100 extern const struct esp_algorithm *esp_algorithm_lookup (int);
00101 extern int                         esp_max_ivlen (void);
00102
00103 /* crypt routines */
00104 extern int    esp4_output (struct mbuf *, struct ipsecrequest *);
00105 extern void   esp4_input (struct mbuf *, int);
00106 extern size_t esp_hdrsiz (struct ipsecrequest *);
00107
00108 extern int    esp_schedule (const struct esp_algorithm *, struct secasvar *);
00109 extern int    esp_auth (struct mbuf *, size_t, size_t,
00110                         struct secasvar *, u_char *);
00111 #endif /* _KERNEL */
00112
00113 #endif /* _NETINET6_ESP_H_ */
Generated on Wed Jan 25 15:42:33 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/netinet6/ESP6.H Source File

inc/netinet6/ESP6.H

Go to the documentation of this file.
00001
00005 /*      $FreeBSD: src/sys/netinet6/esp6.h,v 1.4 2001/06/11 12:39:04 ume Exp $   */
00006 /*      $KAME: esp.h,v 1.16 2000/10/18 21:28:00 itojun Exp $    */
00007
00008 /*
00009  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
00010  * All rights reserved.
00011  *
00012  * Redistribution and use in source and binary forms, with or without
00013  * modification, are permitted provided that the following conditions
00014  * are met:
00015  * 1. Redistributions of source code must retain the above copyright
00016  *    notice, this list of conditions and the following disclaimer.
00017  * 2. Redistributions in binary form must reproduce the above copyright
00018  *    notice, this list of conditions and the following disclaimer in the
00019  *    documentation and/or other materials provided with the distribution.
00020  * 3. Neither the name of the project nor the names of its contributors
00021  *    may be used to endorse or promote products derived from this software
00022  *    without specific prior written permission.
00023  *
00024  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
00025  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00026  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00027  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
00028  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00029  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00030  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00031  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00032  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00033  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00034  * SUCH DAMAGE.
00035  */
00036
00037 /*
00038  * RFC1827/2406 Encapsulated Security Payload.
00039  */
00040
00041 #ifndef _NETINET6_ESP6_H_
00042 #define _NETINET6_ESP6_H_
00043
00044 #ifdef _KERNEL
00045 extern int esp6_output __P((struct mbuf *, u_char *, struct mbuf *,
00046         struct ipsecrequest *));
00047 extern int esp6_input __P((struct mbuf **, int *, int));
00048
00049 extern void esp6_ctlinput __P((int, struct sockaddr *, void *));
00050 #endif /*_KERNEL*/
00051
00052 #endif /*_NETINET6_ESP6_H_*/
Generated on Wed Jan 25 15:42:33 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/netinet6/ESP_RIJN.H Source File

inc/netinet6/ESP_RIJN.H

Go to the documentation of this file.
00001
00005 /*      $FreeBSD: src/sys/netinet6/esp_rijndael.h,v 1.1 2001/06/11 12:39:05 ume Exp $   */
00006 /*      $KAME: esp_rijndael.h,v 1.1 2000/09/20 18:15:22 itojun Exp $    */
00007
00008 /*
00009  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
00010  * All rights reserved.
00011  *
00012  * Redistribution and use in source and binary forms, with or without
00013  * modification, are permitted provided that the following conditions
00014  * are met:
00015  * 1. Redistributions of source code must retain the above copyright
00016  *    notice, this list of conditions and the following disclaimer.
00017  * 2. Redistributions in binary form must reproduce the above copyright
00018  *    notice, this list of conditions and the following disclaimer in the
00019  *    documentation and/or other materials provided with the distribution.
00020  * 3. Neither the name of the project nor the names of its contributors
00021  *    may be used to endorse or promote products derived from this software
00022  *    without specific prior written permission.
00023  *
00024  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
00025  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00026  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00027  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
00028  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00029  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00030  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00031  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00032  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00033  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00034  * SUCH DAMAGE.
00035  */
00036
00037 int esp_rijndael_schedlen __P((const struct esp_algorithm *));
00038 int esp_rijndael_schedule __P((const struct esp_algorithm *,
00039         struct secasvar *));
00040 int esp_rijndael_blockdecrypt __P((const struct esp_algorithm *,
00041         struct secasvar *, u_int8_t *, u_int8_t *));
00042 int esp_rijndael_blockencrypt __P((const struct esp_algorithm *,
00043         struct secasvar *, u_int8_t *, u_int8_t *));
Generated on Wed Jan 25 15:42:33 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/netinet6/IN6.H Source File

inc/netinet6/IN6.H

Go to the documentation of this file.
00001
00005 /*      $FreeBSD: src/sys/netinet6/in6.h,v 1.22 2002/07/25 20:40:09 ume Exp $   */
00006 /*      $KAME: in6.h,v 1.89 2001/05/27 13:28:35 itojun Exp $    */
00007
00008 /*
00009  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
00010  * All rights reserved.
00011  *
00012  * Redistribution and use in source and binary forms, with or without
00013  * modification, are permitted provided that the following conditions
00014  * are met:
00015  * 1. Redistributions of source code must retain the above copyright
00016  *    notice, this list of conditions and the following disclaimer.
00017  * 2. Redistributions in binary form must reproduce the above copyright
00018  *    notice, this list of conditions and the following disclaimer in the
00019  *    documentation and/or other materials provided with the distribution.
00020  * 3. Neither the name of the project nor the names of its contributors
00021  *    may be used to endorse or promote products derived from this software
00022  *    without specific prior written permission.
00023  *
00024  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
00025  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00026  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00027  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
00028  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00029  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00030  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00031  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00032  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00033  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00034  * SUCH DAMAGE.
00035  */
00036
00037 /*
00038  * Copyright (c) 1982, 1986, 1990, 1993
00039  *      The Regents of the University of California.  All rights reserved.
00040  *
00041  * Redistribution and use in source and binary forms, with or without
00042  * modification, are permitted provided that the following conditions
00043  * are met:
00044  * 1. Redistributions of source code must retain the above copyright
00045  *    notice, this list of conditions and the following disclaimer.
00046  * 2. Redistributions in binary form must reproduce the above copyright
00047  *    notice, this list of conditions and the following disclaimer in the
00048  *    documentation and/or other materials provided with the distribution.
00049  * 3. All advertising materials mentioning features or use of this software
00050  *    must display the following acknowledgement:
00051  *      This product includes software developed by the University of
00052  *      California, Berkeley and its contributors.
00053  * 4. Neither the name of the University nor the names of its contributors
00054  *    may be used to endorse or promote products derived from this software
00055  *    without specific prior written permission.
00056  *
00057  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
00058  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00059  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00060  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
00061  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00062  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00063  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00064  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00065  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00066  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00067  * SUCH DAMAGE.
00068  *
00069  *      @(#)in.h        8.3 (Berkeley) 1/3/94
00070  */
00071
00072 #ifndef _NETINET6_IN6_H_
00073 #define _NETINET6_IN6_H_
00074
00075 /*
00076  * Identification of the network protocol stack
00077  * for *BSD-current/release: http://www.kame.net/dev/cvsweb.cgi/kame/COVERAGE
00078  * has the table of implementation/integration differences.
00079  */
00080 #define __KAME__
00081 #define __KAME_VERSION          "20010528/FreeBSD"
00082
00083 /*
00084  * Local port number conventions:
00085  *
00086  * Ports < IPPORT_RESERVED are reserved for privileged processes (e.g. root),
00087  * unless a kernel is compiled with IPNOPRIVPORTS defined.
00088  *
00089  * When a user does a bind(2) or connect(2) with a port number of zero,
00090  * a non-conflicting local port address is chosen.
00091  *
00092  * The default range is IPPORT_ANONMIN to IPPORT_ANONMAX, although
00093  * that is settable by sysctl(3); net.inet.ip.anonportmin and
00094  * net.inet.ip.anonportmax respectively.
00095  *
00096  * A user may set the IPPROTO_IP option IP_PORTRANGE to change this
00097  * default assignment range.
00098  *
00099  * The value IP_PORTRANGE_DEFAULT causes the default behavior.
00100  *
00101  * The value IP_PORTRANGE_HIGH is the same as IP_PORTRANGE_DEFAULT,
00102  * and exists only for FreeBSD compatibility purposes.
00103  *
00104  * The value IP_PORTRANGE_LOW changes the range to the "low" are
00105  * that is (by convention) restricted to privileged processes.
00106  * This convention is based on "vouchsafe" principles only.
00107  * It is only secure if you trust the remote host to restrict these ports.
00108  * The range is IPPORT_RESERVEDMIN to IPPORT_RESERVEDMAX.
00109  */
00110 #if __BSD_VISIBLE
00111 #define IPV6PORT_RESERVED       1024
00112 #define IPV6PORT_ANONMIN        49152
00113 #define IPV6PORT_ANONMAX        65535
00114 #define IPV6PORT_RESERVEDMIN    600
00115 #define IPV6PORT_RESERVEDMAX    (IPV6PORT_RESERVED-1)
00116 #endif
00117
00118 /*
00119  * IPv6 address
00120  */
00121 struct in6_addr {
00122         union {
00123                 uint8_t         __u6_addr8[16];
00124                 uint16_t        __u6_addr16[8];
00125                 uint32_t        __u6_addr32[4];
00126         } __u6_addr;                    /* 128-bit IP6 address */
00127 };
00128
00129 #define s6_addr   __u6_addr.__u6_addr8
00130 #ifdef _KERNEL  /* XXX nonstandard */
00131 #define s6_addr8  __u6_addr.__u6_addr8
00132 #define s6_addr16 __u6_addr.__u6_addr16
00133 #define s6_addr32 __u6_addr.__u6_addr32
00134 #endif
00135
00136 #define INET6_ADDRSTRLEN        46
00137
00138 /*
00139  * XXX missing POSIX.1-2001 macro IPPROTO_IPV6.
00140  */
00141
00142 /*
00143  * Socket address for IPv6
00144  */
00145 #if __BSD_VISIBLE
00146 #define SIN6_LEN
00147 #endif
00148
00149 struct sockaddr_in6 {
00150         uint8_t         sin6_len;       /* length of this struct */
00151         sa_family_t     sin6_family;    /* AF_INET6 */
00152         in_port_t       sin6_port;      /* Transport layer port # */
00153         uint32_t        sin6_flowinfo;  /* IP6 flow information */
00154         struct in6_addr sin6_addr;      /* IP6 address */
00155         uint32_t        sin6_scope_id;  /* scope zone index */
00156 };
00157
00158 /*
00159  * Local definition for masks
00160  */
00161 #ifdef _KERNEL  /* XXX nonstandard */
00162 #define IN6MASK0        {{{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }}}
00163 #define IN6MASK32       {{{ 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, \
00164                             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }}}
00165 #define IN6MASK64       {{{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \
00166                             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }}}
00167 #define IN6MASK96       {{{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \
00168                             0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 }}}
00169 #define IN6MASK128      {{{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \
00170                             0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }}}
00171 #endif
00172
00173 #ifdef _KERNEL
00174 extern const struct sockaddr_in6 sa6_any;
00175
00176 extern const struct in6_addr in6mask0;
00177 extern const struct in6_addr in6mask32;
00178 extern const struct in6_addr in6mask64;
00179 extern const struct in6_addr in6mask96;
00180 extern const struct in6_addr in6mask128;
00181 #endif /* _KERNEL */
00182
00183 /*
00184  * Macros started with IPV6_ADDR is KAME local
00185  */
00186 #ifdef _KERNEL  /* XXX nonstandard */
00187 #if _BYTE_ORDER == _BIG_ENDIAN
00188 #define IPV6_ADDR_INT32_ONE     1
00189 #define IPV6_ADDR_INT32_TWO     2
00190 #define IPV6_ADDR_INT32_MNL     0xff010000
00191 #define IPV6_ADDR_INT32_MLL     0xff020000
00192 #define IPV6_ADDR_INT32_SMP     0x0000ffff
00193 #define IPV6_ADDR_INT16_ULL     0xfe80
00194 #define IPV6_ADDR_INT16_USL     0xfec0
00195 #define IPV6_ADDR_INT16_MLL     0xff02
00196 #elif _BYTE_ORDER == _LITTLE_ENDIAN
00197 #define IPV6_ADDR_INT32_ONE     0x01000000
00198 #define IPV6_ADDR_INT32_TWO     0x02000000
00199 #define IPV6_ADDR_INT32_MNL     0x000001ff
00200 #define IPV6_ADDR_INT32_MLL     0x000002ff
00201 #define IPV6_ADDR_INT32_SMP     0xffff0000
00202 #define IPV6_ADDR_INT16_ULL     0x80fe
00203 #define IPV6_ADDR_INT16_USL     0xc0fe
00204 #define IPV6_ADDR_INT16_MLL     0x02ff
00205 #endif
00206 #endif
00207
00208 /*
00209  * Definition of some useful macros to handle IP6 addresses
00210  */
00211 #if __BSD_VISIBLE
00212 #define IN6ADDR_ANY_INIT \
00213         {{{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
00214             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }}}
00215 #define IN6ADDR_LOOPBACK_INIT \
00216         {{{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
00217             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }}}
00218 #define IN6ADDR_NODELOCAL_ALLNODES_INIT \
00219         {{{ 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
00220             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }}}
00221 #define IN6ADDR_LINKLOCAL_ALLNODES_INIT \
00222         {{{ 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
00223             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }}}
00224 #define IN6ADDR_LINKLOCAL_ALLROUTERS_INIT \
00225         {{{ 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
00226             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02 }}}
00227 #endif
00228
00229 extern const struct in6_addr in6addr_any;
00230 extern const struct in6_addr in6addr_loopback;
00231 #if __BSD_VISIBLE
00232 extern const struct in6_addr in6addr_nodelocal_allnodes;
00233 extern const struct in6_addr in6addr_linklocal_allnodes;
00234 extern const struct in6_addr in6addr_linklocal_allrouters;
00235 #endif
00236
00237 /*
00238  * Equality
00239  * NOTE: Some of kernel programming environment (for example, openbsd/sparc)
00240  * does not supply memcmp().  For userland memcmp() is preferred as it is
00241  * in ANSI standard.
00242  */
00243 #ifdef _KERNEL
00244 #define IN6_ARE_ADDR_EQUAL(a, b)                        \
00245     (bcmp(&(a)->s6_addr[0], &(b)->s6_addr[0], sizeof(struct in6_addr)) == 0)
00246 #else
00247 #if __BSD_VISIBLE
00248 #define IN6_ARE_ADDR_EQUAL(a, b)                        \
00249     (memcmp(&(a)->s6_addr[0], &(b)->s6_addr[0], sizeof(struct in6_addr)) == 0)
00250 #endif
00251 #endif
00252
00253 #ifdef _KERNEL                  /* non standard */
00254 /* see if two addresses are equal in a scope-conscious manner. */
00255 #define SA6_ARE_ADDR_EQUAL(a, b) \
00256         (((a)->sin6_scope_id == 0 || (b)->sin6_scope_id == 0 || \
00257           ((a)->sin6_scope_id == (b)->sin6_scope_id)) && \
00258          (bcmp(&(a)->sin6_addr, &(b)->sin6_addr, sizeof(struct in6_addr)) == 0))
00259 #endif
00260
00261 /*
00262  * Unspecified
00263  */
00264 #define IN6_IS_ADDR_UNSPECIFIED(a)      \
00265         ((*(const u_int32_t *)(const void *)(&(a)->s6_addr[0]) == 0) && \
00266          (*(const u_int32_t *)(const void *)(&(a)->s6_addr[4]) == 0) && \
00267          (*(const u_int32_t *)(const void *)(&(a)->s6_addr[8]) == 0) && \
00268          (*(const u_int32_t *)(const void *)(&(a)->s6_addr[12]) == 0))
00269
00270 /*
00271  * Loopback
00272  */
00273 #define IN6_IS_ADDR_LOOPBACK(a)         \
00274         ((*(const u_int32_t *)(const void *)(&(a)->s6_addr[0]) == 0) && \
00275          (*(const u_int32_t *)(const void *)(&(a)->s6_addr[4]) == 0) && \
00276          (*(const u_int32_t *)(const void *)(&(a)->s6_addr[8]) == 0) && \
00277          (*(const u_int32_t *)(const void *)(&(a)->s6_addr[12]) == ntohl(1)))
00278
00279 /*
00280  * IPv4 compatible
00281  */
00282 #define IN6_IS_ADDR_V4COMPAT(a)         \
00283         ((*(const u_int32_t *)(const void *)(&(a)->s6_addr[0]) == 0) && \
00284          (*(const u_int32_t *)(const void *)(&(a)->s6_addr[4]) == 0) && \
00285          (*(const u_int32_t *)(const void *)(&(a)->s6_addr[8]) == 0) && \
00286          (*(const u_int32_t *)(const void *)(&(a)->s6_addr[12]) != 0) &&        \
00287          (*(const u_int32_t *)(const void *)(&(a)->s6_addr[12]) != ntohl(1)))
00288
00289 /*
00290  * Mapped
00291  */
00292 #define IN6_IS_ADDR_V4MAPPED(a)               \
00293         ((*(const u_int32_t *)(const void *)(&(a)->s6_addr[0]) == 0) && \
00294          (*(const u_int32_t *)(const void *)(&(a)->s6_addr[4]) == 0) && \
00295          (*(const u_int32_t *)(const void *)(&(a)->s6_addr[8]) == ntohl(0x0000ffff)))
00296
00297 /*
00298  * KAME Scope Values
00299  */
00300
00301 #ifdef _KERNEL  /* XXX nonstandard */
00302 #define IPV6_ADDR_SCOPE_NODELOCAL       0x01
00303 #define IPV6_ADDR_SCOPE_LINKLOCAL       0x02
00304 #define IPV6_ADDR_SCOPE_SITELOCAL       0x05
00305 #define IPV6_ADDR_SCOPE_ORGLOCAL        0x08    /* just used in this file */
00306 #define IPV6_ADDR_SCOPE_GLOBAL          0x0e
00307 #else
00308 #define __IPV6_ADDR_SCOPE_NODELOCAL     0x01
00309 #define __IPV6_ADDR_SCOPE_LINKLOCAL     0x02
00310 #define __IPV6_ADDR_SCOPE_SITELOCAL     0x05
00311 #define __IPV6_ADDR_SCOPE_ORGLOCAL      0x08    /* just used in this file */
00312 #define __IPV6_ADDR_SCOPE_GLOBAL        0x0e
00313 #endif
00314
00315 /*
00316  * Unicast Scope
00317  * Note that we must check topmost 10 bits only, not 16 bits (see RFC2373).
00318  */
00319 #define IN6_IS_ADDR_LINKLOCAL(a)        \
00320         (((a)->s6_addr[0] == 0xfe) && (((a)->s6_addr[1] & 0xc0) == 0x80))
00321 #define IN6_IS_ADDR_SITELOCAL(a)        \
00322         (((a)->s6_addr[0] == 0xfe) && (((a)->s6_addr[1] & 0xc0) == 0xc0))
00323
00324 /*
00325  * Multicast
00326  */
00327 #define IN6_IS_ADDR_MULTICAST(a)        ((a)->s6_addr[0] == 0xff)
00328
00329 #ifdef _KERNEL  /* XXX nonstandard */
00330 #define IPV6_ADDR_MC_SCOPE(a)           ((a)->s6_addr[1] & 0x0f)
00331 #else
00332 #define __IPV6_ADDR_MC_SCOPE(a)         ((a)->s6_addr[1] & 0x0f)
00333 #endif
00334
00335 /*
00336  * Multicast Scope
00337  */
00338 #ifdef _KERNEL  /* refers nonstandard items */
00339 #define IN6_IS_ADDR_MC_NODELOCAL(a)     \
00340         (IN6_IS_ADDR_MULTICAST(a) &&    \
00341          (IPV6_ADDR_MC_SCOPE(a) == IPV6_ADDR_SCOPE_NODELOCAL))
00342 #define IN6_IS_ADDR_MC_LINKLOCAL(a)     \
00343         (IN6_IS_ADDR_MULTICAST(a) &&    \
00344          (IPV6_ADDR_MC_SCOPE(a) == IPV6_ADDR_SCOPE_LINKLOCAL))
00345 #define IN6_IS_ADDR_MC_SITELOCAL(a)     \
00346         (IN6_IS_ADDR_MULTICAST(a) &&    \
00347          (IPV6_ADDR_MC_SCOPE(a) == IPV6_ADDR_SCOPE_SITELOCAL))
00348 #define IN6_IS_ADDR_MC_ORGLOCAL(a)      \
00349         (IN6_IS_ADDR_MULTICAST(a) &&    \
00350          (IPV6_ADDR_MC_SCOPE(a) == IPV6_ADDR_SCOPE_ORGLOCAL))
00351 #define IN6_IS_ADDR_MC_GLOBAL(a)        \
00352         (IN6_IS_ADDR_MULTICAST(a) &&    \
00353          (IPV6_ADDR_MC_SCOPE(a) == IPV6_ADDR_SCOPE_GLOBAL))
00354 #else
00355 #define IN6_IS_ADDR_MC_NODELOCAL(a)     \
00356         (IN6_IS_ADDR_MULTICAST(a) &&    \
00357          (__IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_NODELOCAL))
00358 #define IN6_IS_ADDR_MC_LINKLOCAL(a)     \
00359         (IN6_IS_ADDR_MULTICAST(a) &&    \
00360          (__IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_LINKLOCAL))
00361 #define IN6_IS_ADDR_MC_SITELOCAL(a)     \
00362         (IN6_IS_ADDR_MULTICAST(a) &&    \
00363          (__IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_SITELOCAL))
00364 #define IN6_IS_ADDR_MC_ORGLOCAL(a)      \
00365         (IN6_IS_ADDR_MULTICAST(a) &&    \
00366          (__IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_ORGLOCAL))
00367 #define IN6_IS_ADDR_MC_GLOBAL(a)        \
00368         (IN6_IS_ADDR_MULTICAST(a) &&    \
00369          (__IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_GLOBAL))
00370 #endif
00371
00372 #ifdef _KERNEL  /* nonstandard */
00373 /*
00374  * KAME Scope
00375  */
00376 #define IN6_IS_SCOPE_LINKLOCAL(a)       \
00377         ((IN6_IS_ADDR_LINKLOCAL(a)) ||  \
00378          (IN6_IS_ADDR_MC_LINKLOCAL(a)))
00379
00380 #define IFA6_IS_DEPRECATED(a) \
00381         ((a)->ia6_lifetime.ia6t_preferred != 0 && \
00382          (a)->ia6_lifetime.ia6t_preferred < time_second)
00383 #define IFA6_IS_INVALID(a) \
00384         ((a)->ia6_lifetime.ia6t_expire != 0 && \
00385          (a)->ia6_lifetime.ia6t_expire < time_second)
00386 #endif /* _KERNEL */
00387
00388 /*
00389  * IP6 route structure
00390  */
00391 struct route_in6 {
00392         struct  rtentry *ro_rt;
00393         struct  sockaddr_in6 ro_dst;
00394 };
00395
00396 /*
00397  * Options for use with [gs]etsockopt at the IPV6 level.
00398  * First word of comment is data type; bool is stored in int.
00399  */
00400 #define IPV6_JOIN_GROUP         12 /* ip6_mreq; join a group membership */
00401 #define IPV6_LEAVE_GROUP        13 /* ip6_mreq; leave a group membership */
00402 #define IPV6_MULTICAST_HOPS     10 /* int; set/get IP6 multicast hops */
00403 #define IPV6_MULTICAST_IF       9  /* u_int; set/get IP6 multicast i/f  */
00404 #define IPV6_MULTICAST_LOOP     11 /* u_int; set/get IP6 multicast loopback */
00405 #define IPV6_UNICAST_HOPS       4  /* int; IP6 hops */
00406 #define IPV6_V6ONLY             27 /* bool; only bind INET6 at wildcard bind */
00407
00408 #if __BSD_VISIBLE
00409 /* no hdrincl */
00410 #if 0 /* the followings are relic in IPv4 and hence are disabled */
00411 #define IPV6_OPTIONS            1  /* buf/ip6_opts; set/get IP6 options */
00412 #define IPV6_RECVOPTS           5  /* bool; receive all IP6 opts w/dgram */
00413 #define IPV6_RECVRETOPTS        6  /* bool; receive IP6 opts for response */
00414 #define IPV6_RECVDSTADDR        7  /* bool; receive IP6 dst addr w/dgram */
00415 #define IPV6_RETOPTS            8  /* ip6_opts; set/get IP6 options */
00416 #endif
00417 #define IPV6_SOCKOPT_RESERVED1  3  /* reserved for future use */
00418 #define IPV6_PORTRANGE          14 /* int; range to choose for unspec port */
00419 #define ICMP6_FILTER            18 /* icmp6_filter; icmp6 filter */
00420 /* RFC2292 options */
00421 #define IPV6_PKTINFO            19 /* bool; send/recv if, src/dst addr */
00422 #define IPV6_HOPLIMIT           20 /* bool; hop limit */
00423 #define IPV6_NEXTHOP            21 /* bool; next hop addr */
00424 #define IPV6_HOPOPTS            22 /* bool; hop-by-hop option */
00425 #define IPV6_DSTOPTS            23 /* bool; destination option */
00426 #define IPV6_RTHDR              24 /* bool; routing header */
00427 #define IPV6_PKTOPTIONS         25 /* buf/cmsghdr; set/get IPv6 options */
00428
00429 #define IPV6_CHECKSUM           26 /* int; checksum offset for raw socket */
00430 #ifndef _KERNEL
00431 #define IPV6_BINDV6ONLY         IPV6_V6ONLY
00432 #endif
00433
00434 #if 1 /* IPSEC */
00435 #define IPV6_IPSEC_POLICY       28 /* struct; get/set security policy */
00436 #endif
00437 #define IPV6_FAITH              29 /* bool; accept FAITH'ed connections */
00438
00439 #if 1 /* IPV6FIREWALL */
00440 #define IPV6_FW_ADD             30 /* add a firewall rule to chain */
00441 #define IPV6_FW_DEL             31 /* delete a firewall rule from chain */
00442 #define IPV6_FW_FLUSH           32 /* flush firewall rule chain */
00443 #define IPV6_FW_ZERO            33 /* clear single/all firewall counter(s) */
00444 #define IPV6_FW_GET             34 /* get entire firewall rule chain */
00445 #endif
00446
00447 /* to define items, should talk with KAME guys first, for *BSD compatibility */
00448
00449 #define IPV6_RTHDR_LOOSE     0 /* this hop need not be a neighbor. XXX old spec */
00450 #define IPV6_RTHDR_STRICT    1 /* this hop must be a neighbor. XXX old spec */
00451 #define IPV6_RTHDR_TYPE_0    0 /* IPv6 routing header type 0 */
00452
00453 /*
00454  * Defaults and limits for options
00455  */
00456 #define IPV6_DEFAULT_MULTICAST_HOPS 1   /* normally limit m'casts to 1 hop */
00457 #define IPV6_DEFAULT_MULTICAST_LOOP 1   /* normally hear sends if a member */
00458
00459 /*
00460  * Argument structure for IPV6_JOIN_GROUP and IPV6_LEAVE_GROUP.
00461  */
00462 struct ipv6_mreq {
00463         struct in6_addr ipv6mr_multiaddr;
00464         unsigned int    ipv6mr_interface;
00465 };
00466
00467 /*
00468  * IPV6_PKTINFO: Packet information(RFC2292 sec 5)
00469  */
00470 struct in6_pktinfo {
00471         struct in6_addr ipi6_addr;      /* src/dst IPv6 address */
00472         unsigned int    ipi6_ifindex;   /* send/recv interface index */
00473 };
00474
00475 /*
00476  * Argument for IPV6_PORTRANGE:
00477  * - which range to search when port is unspecified at bind() or connect()
00478  */
00479 #define IPV6_PORTRANGE_DEFAULT  0       /* default range */
00480 #define IPV6_PORTRANGE_HIGH     1       /* "high" - request firewall bypass */
00481 #define IPV6_PORTRANGE_LOW      2       /* "low" - vouchsafe security */
00482
00483 /*
00484  * Definitions for inet6 sysctl operations.
00485  *
00486  * Third level is protocol number.
00487  * Fourth level is desired variable within that protocol.
00488  */
00489 #define IPV6PROTO_MAXID (IPPROTO_PIM + 1)       /* don't list to IPV6PROTO_MAX */
00490
00491 #define CTL_IPV6PROTO_NAMES { \
00492         { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, \
00493         { 0, 0 }, \
00494         { "tcp6", CTLTYPE_NODE }, \
00495         { 0, 0 }, \
00496         { 0, 0 }, \
00497         { 0, 0 }, \
00498         { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, \
00499         { 0, 0 }, \
00500         { 0, 0 }, \
00501         { "udp6", CTLTYPE_NODE }, \
00502         { 0, 0 }, \
00503         { 0, 0 }, \
00504         { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, \
00505         { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, \
00506         { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, \
00507         { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, \
00508         { 0, 0 }, \
00509         { "ip6", CTLTYPE_NODE }, \
00510         { 0, 0 }, \
00511         { 0, 0 }, \
00512         { 0, 0 }, \
00513         { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, \
00514         { 0, 0 }, \
00515         { "ipsec6", CTLTYPE_NODE }, \
00516         { 0, 0 }, \
00517         { 0, 0 }, \
00518         { 0, 0 }, \
00519         { 0, 0 }, \
00520         { 0, 0 }, \
00521         { 0, 0 }, \
00522         { "icmp6", CTLTYPE_NODE }, \
00523         { 0, 0 }, \
00524         { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, \
00525         { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, \
00526         { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, \
00527         { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, \
00528         { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, \
00529         { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, \
00530         { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, \
00531         { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, \
00532         { 0, 0 }, \
00533         { 0, 0 }, \
00534         { 0, 0 }, \
00535         { "pim6", CTLTYPE_NODE }, \
00536 }
00537
00538 /*
00539  * Names for IP sysctl objects
00540  */
00541 #define IPV6CTL_FORWARDING      1       /* act as router */
00542 #define IPV6CTL_SENDREDIRECTS   2       /* may send redirects when forwarding*/
00543 #define IPV6CTL_DEFHLIM         3       /* default Hop-Limit */
00544 #ifdef notyet
00545 #define IPV6CTL_DEFMTU          4       /* default MTU */
00546 #endif
00547 #define IPV6CTL_FORWSRCRT       5       /* forward source-routed dgrams */
00548 #define IPV6CTL_STATS           6       /* stats */
00549 #define IPV6CTL_MRTSTATS        7       /* multicast forwarding stats */
00550 #define IPV6CTL_MRTPROTO        8       /* multicast routing protocol */
00551 #define IPV6CTL_MAXFRAGPACKETS  9       /* max packets reassembly queue */
00552 #define IPV6CTL_SOURCECHECK     10      /* verify source route and intf */
00553 #define IPV6CTL_SOURCECHECK_LOGINT 11   /* minimume logging interval */
00554 #define IPV6CTL_ACCEPT_RTADV    12
00555 #define IPV6CTL_KEEPFAITH       13
00556 #define IPV6CTL_LOG_INTERVAL    14
00557 #define IPV6CTL_HDRNESTLIMIT    15
00558 #define IPV6CTL_DAD_COUNT       16
00559 #define IPV6CTL_AUTO_FLOWLABEL  17
00560 #define IPV6CTL_DEFMCASTHLIM    18
00561 #define IPV6CTL_GIF_HLIM        19      /* default HLIM for gif encap packet */
00562 #define IPV6CTL_KAME_VERSION    20
00563 #define IPV6CTL_USE_DEPRECATED  21      /* use deprecated addr (RFC2462 5.5.4) */
00564 #define IPV6CTL_RR_PRUNE        22      /* walk timer for router renumbering */
00565 #if 0   /* obsolete */
00566 #define IPV6CTL_MAPPED_ADDR     23
00567 #endif
00568 #define IPV6CTL_V6ONLY          24
00569 #define IPV6CTL_RTEXPIRE        25      /* cloned route expiration time */
00570 #define IPV6CTL_RTMINEXPIRE     26      /* min value for expiration time */
00571 #define IPV6CTL_RTMAXCACHE      27      /* trigger level for dynamic expire */
00572
00573 #define IPV6CTL_USETEMPADDR     32      /* use temporary addresses (RFC3041) */
00574 #define IPV6CTL_TEMPPLTIME      33      /* preferred lifetime for tmpaddrs */
00575 #define IPV6CTL_TEMPVLTIME      34      /* valid lifetime for tmpaddrs */
00576 #define IPV6CTL_AUTO_LINKLOCAL  35      /* automatic link-local addr assign */
00577 #define IPV6CTL_RIP6STATS       36      /* raw_ip6 stats */
00578
00579 /* New entries should be added here from current IPV6CTL_MAXID value. */
00580 /* to define items, should talk with KAME guys first, for *BSD compatibility */
00581 #define IPV6CTL_MAXID           37
00582
00583 /*
00584  * Redefinition of mbuf flags
00585  */
00586 #define M_AUTHIPHDR     M_PROTO2
00587 #define M_DECRYPTED     M_PROTO3
00588 #define M_LOOP          M_PROTO4
00589 #define M_AUTHIPDGM     M_PROTO5
00590
00591 #ifdef _KERNEL
00592 struct cmsghdr;
00593
00594 int     in6_cksum __P((struct mbuf *, u_int8_t, u_int32_t, u_int32_t));
00595 int     in6_localaddr __P((struct in6_addr *));
00596 int     in6_addrscope __P((struct in6_addr *));
00597 struct  in6_ifaddr *in6_ifawithscope __P((struct ifnet *, struct in6_addr *));
00598 struct  in6_ifaddr *in6_ifawithifp __P((struct ifnet *, struct in6_addr *));
00599 extern void in6_if_up __P((struct ifnet *));
00600 struct sockaddr;
00601 extern  u_char  ip6_protox[];
00602
00603 void    in6_sin6_2_sin __P((struct sockaddr_in *sin,
00604                             struct sockaddr_in6 *sin6));
00605 void    in6_sin_2_v4mapsin6 __P((struct sockaddr_in *sin,
00606                                  struct sockaddr_in6 *sin6));
00607 void    in6_sin6_2_sin_in_sock __P((struct sockaddr *nam));
00608 void    in6_sin_2_v4mapsin6_in_sock __P((struct sockaddr **nam));
00609
00610 #define satosin6(sa)    ((struct sockaddr_in6 *)(sa))
00611 #define sin6tosa(sin6)  ((struct sockaddr *)(sin6))
00612 #define ifatoia6(ifa)   ((struct in6_ifaddr *)(ifa))
00613
00614 extern int      (*faithprefix_p)(struct in6_addr *);
00615 #endif /* _KERNEL */
00616
00617 #ifdef _BSD_SIZE_T_
00618 typedef _BSD_SIZE_T_    size_t;
00619 #undef _BSD_SIZE_T_
00620 #endif
00621
00622 __BEGIN_DECLS
00623 struct cmsghdr;
00624
00625 extern int inet6_option_space __P((int));
00626 extern int inet6_option_init __P((void *, struct cmsghdr **, int));
00627 extern int inet6_option_append __P((struct cmsghdr *, const uint8_t *,
00628         int, int));
00629 extern uint8_t *inet6_option_alloc __P((struct cmsghdr *, int, int, int));
00630 extern int inet6_option_next __P((const struct cmsghdr *, uint8_t **));
00631 extern int inet6_option_find __P((const struct cmsghdr *, uint8_t **, int));
00632
00633 extern size_t inet6_rthdr_space __P((int, int));
00634 extern struct cmsghdr *inet6_rthdr_init __P((void *, int));
00635 extern int inet6_rthdr_add __P((struct cmsghdr *, const struct in6_addr *,
00636                 unsigned int));
00637 extern int inet6_rthdr_lasthop __P((struct cmsghdr *, unsigned int));
00638 #if 0 /* not implemented yet */
00639 extern int inet6_rthdr_reverse __P((const struct cmsghdr *, struct cmsghdr *));
00640 #endif
00641 extern int inet6_rthdr_segments __P((const struct cmsghdr *));
00642 extern struct in6_addr *inet6_rthdr_getaddr __P((struct cmsghdr *, int));
00643 extern int inet6_rthdr_getflags __P((const struct cmsghdr *, int));
00644
00645 extern int inet6_opt_init __P((void *, size_t));
00646 extern int inet6_opt_append __P((void *, size_t, int, uint8_t,
00647                                  size_t, uint8_t, void **));
00648 extern int inet6_opt_finish __P((void *, size_t, int));
00649 extern int inet6_opt_set_val __P((void *, size_t, void *, int));
00650
00651 extern int inet6_opt_next __P((void *, size_t, int, uint8_t *,
00652                                size_t *, void **));
00653 extern int inet6_opt_find __P((void *, size_t, int, uint8_t,
00654                           size_t *, void **));
00655 extern int inet6_opt_get_val __P((void *, size_t, void *, int));
00656 extern size_t inet6_rth_space __P((int, int));
00657 extern void *inet6_rth_init __P((void *, int, int, int));
00658 extern int inet6_rth_add __P((void *, const struct in6_addr *));
00659 extern int inet6_rth_reverse __P((const void *, void *));
00660 extern int inet6_rth_segments __P((const void *));
00661 extern struct in6_addr *inet6_rth_getaddr __P((const void *, int));
00662 __END_DECLS
00663
00664 #endif /* __BSD_VISIBLE */
00665
00666 #endif /* !_NETINET6_IN6_H_ */
Generated on Wed Jan 25 15:42:33 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/netinet6/IN6_GIF.H Source File

inc/netinet6/IN6_GIF.H

Go to the documentation of this file.
00001
00005 /*      $FreeBSD: src/sys/netinet6/in6_gif.h,v 1.3 2000/07/04 16:35:09 itojun Exp $     */
00006 /*      $KAME: in6_gif.h,v 1.5 2000/04/14 08:36:03 itojun Exp $ */
00007
00008 /*
00009  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
00010  * All rights reserved.
00011  *
00012  * Redistribution and use in source and binary forms, with or without
00013  * modification, are permitted provided that the following conditions
00014  * are met:
00015  * 1. Redistributions of source code must retain the above copyright
00016  *    notice, this list of conditions and the following disclaimer.
00017  * 2. Redistributions in binary form must reproduce the above copyright
00018  *    notice, this list of conditions and the following disclaimer in the
00019  *    documentation and/or other materials provided with the distribution.
00020  * 3. Neither the name of the project nor the names of its contributors
00021  *    may be used to endorse or promote products derived from this software
00022  *    without specific prior written permission.
00023  *
00024  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
00025  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00026  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00027  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
00028  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00029  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00030  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00031  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00032  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00033  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00034  * SUCH DAMAGE.
00035  */
00036
00037 #ifndef _NETINET6_IN6_GIF_H_
00038 #define _NETINET6_IN6_GIF_H_
00039
00040 #define GIF_HLIM        30
00041
00042 int in6_gif_input __P((struct mbuf **, int *, int));
00043 int in6_gif_output __P((struct ifnet *, int, struct mbuf *, struct rtentry *));
00044 int gif_encapcheck6 __P((const struct mbuf *, int, int, void *));
00045
00046 #endif /*_NETINET6_IN6_GIF_H_*/
Generated on Wed Jan 25 15:42:33 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/netinet6/IN6_IFAT.H Source File

inc/netinet6/IN6_IFAT.H

Go to the documentation of this file.
00001
00005 /*      $FreeBSD: src/sys/netinet6/in6_ifattach.h,v 1.3 2001/06/11 12:39:05 ume Exp $   */
00006 /*      $KAME: in6_ifattach.h,v 1.14 2001/02/08 12:48:39 jinmei Exp $   */
00007
00008 /*
00009  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
00010  * All rights reserved.
00011  *
00012  * Redistribution and use in source and binary forms, with or without
00013  * modification, are permitted provided that the following conditions
00014  * are met:
00015  * 1. Redistributions of source code must retain the above copyright
00016  *    notice, this list of conditions and the following disclaimer.
00017  * 2. Redistributions in binary form must reproduce the above copyright
00018  *    notice, this list of conditions and the following disclaimer in the
00019  *    documentation and/or other materials provided with the distribution.
00020  * 3. Neither the name of the project nor the names of its contributors
00021  *    may be used to endorse or promote products derived from this software
00022  *    without specific prior written permission.
00023  *
00024  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
00025  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00026  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00027  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
00028  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00029  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00030  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00031  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00032  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00033  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00034  * SUCH DAMAGE.
00035  */
00036
00037 #ifndef _NETINET6_IN6_IFATTACH_H_
00038 #define _NETINET6_IN6_IFATTACH_H_
00039
00040 #ifdef _KERNEL
00041 void in6_nigroup_attach __P((const char *, int));
00042 void in6_nigroup_detach __P((const char *, int));
00043 void in6_ifattach __P((struct ifnet *, struct ifnet *));
00044 void in6_ifdetach __P((struct ifnet *));
00045 void in6_get_tmpifid __P((struct ifnet *, u_int8_t *, const u_int8_t *, int));
00046 void in6_tmpaddrtimer __P((void *));
00047 int in6_nigroup __P((struct ifnet *, const char *, int, struct in6_addr *));
00048 #endif /* _KERNEL */
00049
00050 #endif /* _NETINET6_IN6_IFATTACH_H_ */
Generated on Wed Jan 25 15:42:33 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/netinet6/IN6_PCB.H Source File

inc/netinet6/IN6_PCB.H

Go to the documentation of this file.
00001
00005 /*      $FreeBSD: src/sys/netinet6/in6_pcb.h,v 1.8 2002/06/14 08:35:21 hsu Exp $        */
00006 /*      $KAME: in6_pcb.h,v 1.13 2001/02/06 09:16:53 itojun Exp $        */
00007
00008 /*
00009  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
00010  * All rights reserved.
00011  *
00012  * Redistribution and use in source and binary forms, with or without
00013  * modification, are permitted provided that the following conditions
00014  * are met:
00015  * 1. Redistributions of source code must retain the above copyright
00016  *    notice, this list of conditions and the following disclaimer.
00017  * 2. Redistributions in binary form must reproduce the above copyright
00018  *    notice, this list of conditions and the following disclaimer in the
00019  *    documentation and/or other materials provided with the distribution.
00020  * 3. Neither the name of the project nor the names of its contributors
00021  *    may be used to endorse or promote products derived from this software
00022  *    without specific prior written permission.
00023  *
00024  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
00025  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00026  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00027  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
00028  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00029  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00030  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00031  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00032  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00033  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00034  * SUCH DAMAGE.
00035  *
00036  */
00037
00038 /*
00039  * Copyright (c) 1982, 1986, 1990, 1993
00040  *      The Regents of the University of California.  All rights reserved.
00041  *
00042  * Redistribution and use in source and binary forms, with or without
00043  * modification, are permitted provided that the following conditions
00044  * are met:
00045  * 1. Redistributions of source code must retain the above copyright
00046  *    notice, this list of conditions and the following disclaimer.
00047  * 2. Redistributions in binary form must reproduce the above copyright
00048  *    notice, this list of conditions and the following disclaimer in the
00049  *    documentation and/or other materials provided with the distribution.
00050  * 3. All advertising materials mentioning features or use of this software
00051  *    must display the following acknowledgement:
00052  *      This product includes software developed by the University of
00053  *      California, Berkeley and its contributors.
00054  * 4. Neither the name of the University nor the names of its contributors
00055  *    may be used to endorse or promote products derived from this software
00056  *    without specific prior written permission.
00057  *
00058  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
00059  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00060  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00061  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
00062  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00063  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00064  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00065  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00066  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00067  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00068  * SUCH DAMAGE.
00069  *
00070  *      @(#)in_pcb.h    8.1 (Berkeley) 6/10/93
00071  */
00072
00073 #ifndef _NETINET6_IN6_PCB_H_
00074 #define _NETINET6_IN6_PCB_H_
00075
00076 #ifdef _KERNEL
00077 #define satosin6(sa)    ((struct sockaddr_in6 *)(sa))
00078 #define sin6tosa(sin6)  ((struct sockaddr *)(sin6))
00079 #define ifatoia6(ifa)   ((struct in6_ifaddr *)(ifa))
00080
00081 void    in6_pcbpurgeif0 __P((struct in6pcb *, struct ifnet *));
00082 void    in6_losing __P((struct inpcb *));
00083 int     in6_pcballoc __P((struct socket *, struct inpcbinfo *, struct thread *));
00084 int     in6_pcbbind __P((struct inpcb *, struct sockaddr *, struct thread *));
00085 int     in6_pcbconnect __P((struct inpcb *, struct sockaddr *, struct thread *));
00086 void    in6_pcbdetach __P((struct inpcb *));
00087 void    in6_pcbdisconnect __P((struct inpcb *));
00088 int     in6_pcbladdr __P((struct inpcb *, struct sockaddr *,
00089                           struct in6_addr **));
00090 struct  inpcb *
00091         in6_pcblookup_local __P((struct inpcbinfo *,
00092                                  struct in6_addr *, u_int, int));
00093 struct  inpcb *
00094         in6_pcblookup_hash __P((struct inpcbinfo *,
00095                                 struct in6_addr *, u_int, struct in6_addr *,
00096                                 u_int, int, struct ifnet *));
00097 void    in6_pcbnotify __P((struct inpcbhead *, struct sockaddr *,
00098                            u_int, const struct sockaddr *, u_int, int,
00099                            struct inpcb *(*)(struct inpcb *, int)));
00100 struct inpcb *
00101         in6_rtchange __P((struct inpcb *, int));
00102 int     in6_setpeeraddr __P((struct socket *so, struct sockaddr **nam));
00103 int     in6_setsockaddr __P((struct socket *so, struct sockaddr **nam));
00104 int     in6_mapped_sockaddr __P((struct socket *so, struct sockaddr **nam));
00105 int     in6_mapped_peeraddr __P((struct socket *so, struct sockaddr **nam));
00106 struct  in6_addr *in6_selectsrc __P((struct sockaddr_in6 *,
00107                                      struct ip6_pktopts *,
00108                                      struct ip6_moptions *,
00109                                      struct route_in6 *,
00110                                      struct in6_addr *, int *));
00111 int     in6_selecthlim __P((struct in6pcb *, struct ifnet *));
00112 int     in6_pcbsetport __P((struct in6_addr *, struct inpcb *, struct thread *));
00113 void    init_sin6 __P((struct sockaddr_in6 *sin6, struct mbuf *m));
00114 #endif /* _KERNEL */
00115
00116 #endif /* !_NETINET6_IN6_PCB_H_ */
Generated on Wed Jan 25 15:42:33 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/netinet6/IN6_PREF.H Source File

inc/netinet6/IN6_PREF.H

Go to the documentation of this file.
00001
00005 /*      $FreeBSD: src/sys/netinet6/in6_prefix.h,v 1.5 2001/06/11 12:39:05 ume Exp $     */
00006 /*      $KAME: in6_prefix.h,v 1.10 2001/02/08 16:30:30 itojun Exp $     */
00007
00008 /*
00009  * Copyright (C) 1995, 1996, 1997, 1998 and 1999 WIDE Project.
00010  * All rights reserved.
00011  *
00012  * Redistribution and use in source and binary forms, with or without
00013  * modification, are permitted provided that the following conditions
00014  * are met:
00015  * 1. Redistributions of source code must retain the above copyright
00016  *    notice, this list of conditions and the following disclaimer.
00017  * 2. Redistributions in binary form must reproduce the above copyright
00018  *    notice, this list of conditions and the following disclaimer in the
00019  *    documentation and/or other materials provided with the distribution.
00020  * 3. Neither the name of the project nor the names of its contributors
00021  *    may be used to endorse or promote products derived from this software
00022  *    without specific prior written permission.
00023  *
00024  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
00025  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00026  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00027  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
00028  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00029  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00030  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00031  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00032  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00033  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00034  * SUCH DAMAGE.
00035  */
00036
00037 #include <sys/callout.h>
00038
00039 struct rr_prefix {
00040         struct ifprefix rp_ifpr;
00041         LIST_ENTRY(rr_prefix) rp_entry;
00042         LIST_HEAD(rp_addrhead, rp_addr) rp_addrhead;
00043         struct sockaddr_in6 rp_prefix;  /* prefix */
00044         u_int32_t rp_vltime;    /* advertised valid lifetime */
00045         u_int32_t rp_pltime;    /* advertised preferred lifetime */
00046         time_t rp_expire;       /* expiration time of the prefix */
00047         time_t rp_preferred;    /* preferred time of the prefix */
00048         struct in6_prflags rp_flags;
00049         u_char  rp_origin; /* from where this prefix info is obtained */
00050         struct  rp_stateflags {
00051                 /* if some prefix should be added to this prefix */
00052                 u_char addmark : 1;
00053                 u_char delmark : 1; /* if this prefix will be deleted */
00054         } rp_stateflags;
00055 };
00056
00057 #define rp_type         rp_ifpr.ifpr_type
00058 #define rp_ifp          rp_ifpr.ifpr_ifp
00059 #define rp_plen         rp_ifpr.ifpr_plen
00060
00061 #define rp_raf          rp_flags.prf_ra
00062 #define rp_raf_onlink           rp_flags.prf_ra.onlink
00063 #define rp_raf_auto             rp_flags.prf_ra.autonomous
00064
00065 #define rp_statef_addmark       rp_stateflags.addmark
00066 #define rp_statef_delmark       rp_stateflags.delmark
00067
00068 #define rp_rrf          rp_flags.prf_rr
00069 #define rp_rrf_decrvalid        rp_flags.prf_rr.decrvalid
00070 #define rp_rrf_decrprefd        rp_flags.prf_rr.decrprefd
00071
00072 struct rp_addr {
00073         LIST_ENTRY(rp_addr)     ra_entry;
00074         struct in6_addr         ra_ifid;
00075         struct in6_ifaddr       *ra_addr;
00076         struct ra_flags {
00077                 u_char anycast : 1;
00078         } ra_flags;
00079 };
00080
00081 #define ifpr2rp(ifpr)   ((struct rr_prefix *)(ifpr))
00082 #define rp2ifpr(rp)     ((struct ifprefix *)(rp))
00083
00084 #define RP_IN6(rp)      (&(rp)->rp_prefix.sin6_addr)
00085
00086 #define RR_INFINITE_LIFETIME            0xffffffff
00087
00088
00089 LIST_HEAD(rr_prhead, rr_prefix);
00090
00091 extern struct rr_prhead rr_prefix;
00092
00093 void in6_rr_timer __P((void *));
00094 extern struct callout in6_rr_timer_ch;
00095 int delete_each_prefix  __P((struct rr_prefix *rpp, u_char origin));
Generated on Wed Jan 25 15:42:33 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/netinet6/IN6_VAR.H Source File

inc/netinet6/IN6_VAR.H

Go to the documentation of this file.
00001
00005 /*      $FreeBSD: src/sys/netinet6/in6_var.h,v 1.10 2002/04/19 04:46:22 suz Exp $       */
00006 /*      $KAME: in6_var.h,v 1.56 2001/03/29 05:34:31 itojun Exp $        */
00007
00008 /*
00009  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
00010  * All rights reserved.
00011  *
00012  * Redistribution and use in source and binary forms, with or without
00013  * modification, are permitted provided that the following conditions
00014  * are met:
00015  * 1. Redistributions of source code must retain the above copyright
00016  *    notice, this list of conditions and the following disclaimer.
00017  * 2. Redistributions in binary form must reproduce the above copyright
00018  *    notice, this list of conditions and the following disclaimer in the
00019  *    documentation and/or other materials provided with the distribution.
00020  * 3. Neither the name of the project nor the names of its contributors
00021  *    may be used to endorse or promote products derived from this software
00022  *    without specific prior written permission.
00023  *
00024  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
00025  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00026  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00027  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
00028  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00029  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00030  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00031  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00032  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00033  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00034  * SUCH DAMAGE.
00035  */
00036
00037 /*
00038  * Copyright (c) 1985, 1986, 1993
00039  *      The Regents of the University of California.  All rights reserved.
00040  *
00041  * Redistribution and use in source and binary forms, with or without
00042  * modification, are permitted provided that the following conditions
00043  * are met:
00044  * 1. Redistributions of source code must retain the above copyright
00045  *    notice, this list of conditions and the following disclaimer.
00046  * 2. Redistributions in binary form must reproduce the above copyright
00047  *    notice, this list of conditions and the following disclaimer in the
00048  *    documentation and/or other materials provided with the distribution.
00049  * 3. All advertising materials mentioning features or use of this software
00050  *    must display the following acknowledgement:
00051  *      This product includes software developed by the University of
00052  *      California, Berkeley and its contributors.
00053  * 4. Neither the name of the University nor the names of its contributors
00054  *    may be used to endorse or promote products derived from this software
00055  *    without specific prior written permission.
00056  *
00057  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
00058  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00059  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00060  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
00061  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00062  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00063  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00064  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00065  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00066  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00067  * SUCH DAMAGE.
00068  *
00069  *      @(#)in_var.h    8.1 (Berkeley) 6/10/93
00070  */
00071
00072 #ifndef _NETINET6_IN6_VAR_H_
00073 #define _NETINET6_IN6_VAR_H_
00074
00075 /*
00076  * Interface address, Internet version.  One of these structures
00077  * is allocated for each interface with an Internet address.
00078  * The ifaddr structure contains the protocol-independent part
00079  * of the structure and is assumed to be first.
00080  */
00081
00082 /*
00083  * pltime/vltime are just for future reference (required to implements 2
00084  * hour rule for hosts).  they should never be modified by nd6_timeout or
00085  * anywhere else.
00086  *      userland -> kernel: accept pltime/vltime
00087  *      kernel -> userland: throw up everything
00088  *      in kernel: modify preferred/expire only
00089  */
00090 struct in6_addrlifetime {
00091         time_t ia6t_expire;     /* valid lifetime expiration time */
00092         time_t ia6t_preferred;  /* preferred lifetime expiration time */
00093         u_int32_t ia6t_vltime;  /* valid lifetime */
00094         u_int32_t ia6t_pltime;  /* prefix lifetime */
00095 };
00096
00097 struct  in6_ifaddr {
00098         struct  ifaddr ia_ifa;          /* protocol-independent info */
00099 #define ia_ifp          ia_ifa.ifa_ifp
00100 #define ia_flags        ia_ifa.ifa_flags
00101         struct  sockaddr_in6 ia_addr;   /* interface address */
00102         struct  sockaddr_in6 ia_net;    /* network number of interface */
00103         struct  sockaddr_in6 ia_dstaddr; /* space for destination addr */
00104         struct  sockaddr_in6 ia_prefixmask; /* prefix mask */
00105         u_int32_t ia_plen;              /* prefix length */
00106         struct  in6_ifaddr *ia_next;    /* next in6 list of IP6 addresses */
00107         int     ia6_flags;
00108
00109         struct in6_addrlifetime ia6_lifetime;
00110         struct ifprefix *ia6_ifpr; /* back pointer to ifprefix */
00111
00112         struct nd_prefix *ia6_ndpr; /* back pointer to the ND prefix
00113                                      * (for autoconfigured addresses only)
00114                                      */
00115 };
00116
00117 /*
00118  * IPv6 interface statistics, as defined in RFC2465 Ipv6IfStatsEntry (p12).
00119  */
00120 struct in6_ifstat {
00121         u_quad_t ifs6_in_receive;       /* # of total input datagram */
00122         u_quad_t ifs6_in_hdrerr;        /* # of datagrams with invalid hdr */
00123         u_quad_t ifs6_in_toobig;        /* # of datagrams exceeded MTU */
00124         u_quad_t ifs6_in_noroute;       /* # of datagrams with no route */
00125         u_quad_t ifs6_in_addrerr;       /* # of datagrams with invalid dst */
00126         u_quad_t ifs6_in_protounknown;  /* # of datagrams with unknown proto */
00127                                         /* NOTE: increment on final dst if */
00128         u_quad_t ifs6_in_truncated;     /* # of truncated datagrams */
00129         u_quad_t ifs6_in_discard;       /* # of discarded datagrams */
00130                                         /* NOTE: fragment timeout is not here */
00131         u_quad_t ifs6_in_deliver;       /* # of datagrams delivered to ULP */
00132                                         /* NOTE: increment on final dst if */
00133         u_quad_t ifs6_out_forward;      /* # of datagrams forwarded */
00134                                         /* NOTE: increment on outgoing if */
00135         u_quad_t ifs6_out_request;      /* # of outgoing datagrams from ULP */
00136                                         /* NOTE: does not include forwrads */
00137         u_quad_t ifs6_out_discard;      /* # of discarded datagrams */
00138         u_quad_t ifs6_out_fragok;       /* # of datagrams fragmented */
00139         u_quad_t ifs6_out_fragfail;     /* # of datagrams failed on fragment */
00140         u_quad_t ifs6_out_fragcreat;    /* # of fragment datagrams */
00141                                         /* NOTE: this is # after fragment */
00142         u_quad_t ifs6_reass_reqd;       /* # of incoming fragmented packets */
00143                                         /* NOTE: increment on final dst if */
00144         u_quad_t ifs6_reass_ok;         /* # of reassembled packets */
00145                                         /* NOTE: this is # after reass */
00146                                         /* NOTE: increment on final dst if */
00147         u_quad_t ifs6_reass_fail;       /* # of reass failures */
00148                                         /* NOTE: may not be packet count */
00149                                         /* NOTE: increment on final dst if */
00150         u_quad_t ifs6_in_mcast;         /* # of inbound multicast datagrams */
00151         u_quad_t ifs6_out_mcast;        /* # of outbound multicast datagrams */
00152 };
00153
00154 /*
00155  * ICMPv6 interface statistics, as defined in RFC2466 Ipv6IfIcmpEntry.
00156  * XXX: I'm not sure if this file is the right place for this structure...
00157  */
00158 struct icmp6_ifstat {
00159         /*
00160          * Input statistics
00161          */
00162         /* ipv6IfIcmpInMsgs, total # of input messages */
00163         u_quad_t ifs6_in_msg;
00164         /* ipv6IfIcmpInErrors, # of input error messages */
00165         u_quad_t ifs6_in_error;
00166         /* ipv6IfIcmpInDestUnreachs, # of input dest unreach errors */
00167         u_quad_t ifs6_in_dstunreach;
00168         /* ipv6IfIcmpInAdminProhibs, # of input administratively prohibited errs */
00169         u_quad_t ifs6_in_adminprohib;
00170         /* ipv6IfIcmpInTimeExcds, # of input time exceeded errors */
00171         u_quad_t ifs6_in_timeexceed;
00172         /* ipv6IfIcmpInParmProblems, # of input parameter problem errors */
00173         u_quad_t ifs6_in_paramprob;
00174         /* ipv6IfIcmpInPktTooBigs, # of input packet too big errors */
00175         u_quad_t ifs6_in_pkttoobig;
00176         /* ipv6IfIcmpInEchos, # of input echo requests */
00177         u_quad_t ifs6_in_echo;
00178         /* ipv6IfIcmpInEchoReplies, # of input echo replies */
00179         u_quad_t ifs6_in_echoreply;
00180         /* ipv6IfIcmpInRouterSolicits, # of input router solicitations */
00181         u_quad_t ifs6_in_routersolicit;
00182         /* ipv6IfIcmpInRouterAdvertisements, # of input router advertisements */
00183         u_quad_t ifs6_in_routeradvert;
00184         /* ipv6IfIcmpInNeighborSolicits, # of input neighbor solicitations */
00185         u_quad_t ifs6_in_neighborsolicit;
00186         /* ipv6IfIcmpInNeighborAdvertisements, # of input neighbor advertisements */
00187         u_quad_t ifs6_in_neighboradvert;
00188         /* ipv6IfIcmpInRedirects, # of input redirects */
00189         u_quad_t ifs6_in_redirect;
00190         /* ipv6IfIcmpInGroupMembQueries, # of input MLD queries */
00191         u_quad_t ifs6_in_mldquery;
00192         /* ipv6IfIcmpInGroupMembResponses, # of input MLD reports */
00193         u_quad_t ifs6_in_mldreport;
00194         /* ipv6IfIcmpInGroupMembReductions, # of input MLD done */
00195         u_quad_t ifs6_in_mlddone;
00196
00197         /*
00198          * Output statistics. We should solve unresolved routing problem...
00199          */
00200         /* ipv6IfIcmpOutMsgs, total # of output messages */
00201         u_quad_t ifs6_out_msg;
00202         /* ipv6IfIcmpOutErrors, # of output error messages */
00203         u_quad_t ifs6_out_error;
00204         /* ipv6IfIcmpOutDestUnreachs, # of output dest unreach errors */
00205         u_quad_t ifs6_out_dstunreach;
00206         /* ipv6IfIcmpOutAdminProhibs, # of output administratively prohibited errs */
00207         u_quad_t ifs6_out_adminprohib;
00208         /* ipv6IfIcmpOutTimeExcds, # of output time exceeded errors */
00209         u_quad_t ifs6_out_timeexceed;
00210         /* ipv6IfIcmpOutParmProblems, # of output parameter problem errors */
00211         u_quad_t ifs6_out_paramprob;
00212         /* ipv6IfIcmpOutPktTooBigs, # of output packet too big errors */
00213         u_quad_t ifs6_out_pkttoobig;
00214         /* ipv6IfIcmpOutEchos, # of output echo requests */
00215         u_quad_t ifs6_out_echo;
00216         /* ipv6IfIcmpOutEchoReplies, # of output echo replies */
00217         u_quad_t ifs6_out_echoreply;
00218         /* ipv6IfIcmpOutRouterSolicits, # of output router solicitations */
00219         u_quad_t ifs6_out_routersolicit;
00220         /* ipv6IfIcmpOutRouterAdvertisements, # of output router advertisements */
00221         u_quad_t ifs6_out_routeradvert;
00222         /* ipv6IfIcmpOutNeighborSolicits, # of output neighbor solicitations */
00223         u_quad_t ifs6_out_neighborsolicit;
00224         /* ipv6IfIcmpOutNeighborAdvertisements, # of output neighbor advertisements */
00225         u_quad_t ifs6_out_neighboradvert;
00226         /* ipv6IfIcmpOutRedirects, # of output redirects */
00227         u_quad_t ifs6_out_redirect;
00228         /* ipv6IfIcmpOutGroupMembQueries, # of output MLD queries */
00229         u_quad_t ifs6_out_mldquery;
00230         /* ipv6IfIcmpOutGroupMembResponses, # of output MLD reports */
00231         u_quad_t ifs6_out_mldreport;
00232         /* ipv6IfIcmpOutGroupMembReductions, # of output MLD done */
00233         u_quad_t ifs6_out_mlddone;
00234 };
00235
00236 struct  in6_ifreq {
00237         char    ifr_name[IFNAMSIZ];
00238         union {
00239                 struct  sockaddr_in6 ifru_addr;
00240                 struct  sockaddr_in6 ifru_dstaddr;
00241                 short   ifru_flags;
00242                 int     ifru_flags6;
00243                 int     ifru_metric;
00244                 caddr_t ifru_data;
00245                 struct in6_addrlifetime ifru_lifetime;
00246                 struct in6_ifstat ifru_stat;
00247                 struct icmp6_ifstat ifru_icmp6stat;
00248                 u_int32_t ifru_scope_id[16];
00249         } ifr_ifru;
00250 };
00251
00252 struct  in6_aliasreq {
00253         char    ifra_name[IFNAMSIZ];
00254         struct  sockaddr_in6 ifra_addr;
00255         struct  sockaddr_in6 ifra_dstaddr;
00256         struct  sockaddr_in6 ifra_prefixmask;
00257         int     ifra_flags;
00258         struct in6_addrlifetime ifra_lifetime;
00259 };
00260
00261 /* prefix type macro */
00262 #define IN6_PREFIX_ND   1
00263 #define IN6_PREFIX_RR   2
00264
00265 /*
00266  * prefix related flags passed between kernel(NDP related part) and
00267  * user land command(ifconfig) and daemon(rtadvd).
00268  */
00269 struct in6_prflags {
00270         struct prf_ra {
00271                 u_char onlink : 1;
00272                 u_char autonomous : 1;
00273                 u_char reserved : 6;
00274         } prf_ra;
00275         u_char prf_reserved1;
00276         u_short prf_reserved2;
00277         /* want to put this on 4byte offset */
00278         struct prf_rr {
00279                 u_char decrvalid : 1;
00280                 u_char decrprefd : 1;
00281                 u_char reserved : 6;
00282         } prf_rr;
00283         u_char prf_reserved3;
00284         u_short prf_reserved4;
00285 };
00286
00287 struct  in6_prefixreq {
00288         char    ipr_name[IFNAMSIZ];
00289         u_char  ipr_origin;
00290         u_char  ipr_plen;
00291         u_int32_t ipr_vltime;
00292         u_int32_t ipr_pltime;
00293         struct in6_prflags ipr_flags;
00294         struct  sockaddr_in6 ipr_prefix;
00295 };
00296
00297 #define PR_ORIG_RA      0
00298 #define PR_ORIG_RR      1
00299 #define PR_ORIG_STATIC  2
00300 #define PR_ORIG_KERNEL  3
00301
00302 #define ipr_raf_onlink          ipr_flags.prf_ra.onlink
00303 #define ipr_raf_auto            ipr_flags.prf_ra.autonomous
00304
00305 #define ipr_statef_onlink       ipr_flags.prf_state.onlink
00306
00307 #define ipr_rrf_decrvalid       ipr_flags.prf_rr.decrvalid
00308 #define ipr_rrf_decrprefd       ipr_flags.prf_rr.decrprefd
00309
00310 struct  in6_rrenumreq {
00311         char    irr_name[IFNAMSIZ];
00312         u_char  irr_origin;
00313         u_char  irr_m_len;      /* match len for matchprefix */
00314         u_char  irr_m_minlen;   /* minlen for matching prefix */
00315         u_char  irr_m_maxlen;   /* maxlen for matching prefix */
00316         u_char  irr_u_uselen;   /* uselen for adding prefix */
00317         u_char  irr_u_keeplen;  /* keeplen from matching prefix */
00318         struct irr_raflagmask {
00319                 u_char onlink : 1;
00320                 u_char autonomous : 1;
00321                 u_char reserved : 6;
00322         } irr_raflagmask;
00323         u_int32_t irr_vltime;
00324         u_int32_t irr_pltime;
00325         struct in6_prflags irr_flags;
00326         struct  sockaddr_in6 irr_matchprefix;
00327         struct  sockaddr_in6 irr_useprefix;
00328 };
00329
00330 #define irr_raf_mask_onlink     irr_raflagmask.onlink
00331 #define irr_raf_mask_auto       irr_raflagmask.autonomous
00332 #define irr_raf_mask_reserved   irr_raflagmask.reserved
00333
00334 #define irr_raf_onlink          irr_flags.prf_ra.onlink
00335 #define irr_raf_auto            irr_flags.prf_ra.autonomous
00336
00337 #define irr_statef_onlink       irr_flags.prf_state.onlink
00338
00339 #define irr_rrf                 irr_flags.prf_rr
00340 #define irr_rrf_decrvalid       irr_flags.prf_rr.decrvalid
00341 #define irr_rrf_decrprefd       irr_flags.prf_rr.decrprefd
00342
00343 /*
00344  * Given a pointer to an in6_ifaddr (ifaddr),
00345  * return a pointer to the addr as a sockaddr_in6
00346  */
00347 #define IA6_IN6(ia)     (&((ia)->ia_addr.sin6_addr))
00348 #define IA6_DSTIN6(ia)  (&((ia)->ia_dstaddr.sin6_addr))
00349 #define IA6_MASKIN6(ia) (&((ia)->ia_prefixmask.sin6_addr))
00350 #define IA6_SIN6(ia)    (&((ia)->ia_addr))
00351 #define IA6_DSTSIN6(ia) (&((ia)->ia_dstaddr))
00352 #define IFA_IN6(x)      (&((struct sockaddr_in6 *)((x)->ifa_addr))->sin6_addr)
00353 #define IFA_DSTIN6(x)   (&((struct sockaddr_in6 *)((x)->ifa_dstaddr))->sin6_addr)
00354
00355 #define IFPR_IN6(x)     (&((struct sockaddr_in6 *)((x)->ifpr_prefix))->sin6_addr)
00356
00357 #ifdef _KERNEL
00358 #define IN6_ARE_MASKED_ADDR_EQUAL(d, a, m)      (       \
00359         (((d)->s6_addr32[0] ^ (a)->s6_addr32[0]) & (m)->s6_addr32[0]) == 0 && \
00360         (((d)->s6_addr32[1] ^ (a)->s6_addr32[1]) & (m)->s6_addr32[1]) == 0 && \
00361         (((d)->s6_addr32[2] ^ (a)->s6_addr32[2]) & (m)->s6_addr32[2]) == 0 && \
00362         (((d)->s6_addr32[3] ^ (a)->s6_addr32[3]) & (m)->s6_addr32[3]) == 0 )
00363 #endif
00364
00365 #define SIOCSIFADDR_IN6          _IOW('i', 12, struct in6_ifreq)
00366 #define SIOCGIFADDR_IN6         _IOWR('i', 33, struct in6_ifreq)
00367
00368 #ifdef _KERNEL
00369 /*
00370  * SIOCSxxx ioctls should be unused (see comments in in6.c), but
00371  * we do not shift numbers for binary compatibility.
00372  */
00373 #define SIOCSIFDSTADDR_IN6       _IOW('i', 14, struct in6_ifreq)
00374 #define SIOCSIFNETMASK_IN6       _IOW('i', 22, struct in6_ifreq)
00375 #endif
00376
00377 #define SIOCGIFDSTADDR_IN6      _IOWR('i', 34, struct in6_ifreq)
00378 #define SIOCGIFNETMASK_IN6      _IOWR('i', 37, struct in6_ifreq)
00379
00380 #define SIOCDIFADDR_IN6          _IOW('i', 25, struct in6_ifreq)
00381 #define SIOCAIFADDR_IN6          _IOW('i', 26, struct in6_aliasreq)
00382
00383 #define SIOCSIFPHYADDR_IN6       _IOW('i', 70, struct in6_aliasreq)
00384 #define SIOCGIFPSRCADDR_IN6     _IOWR('i', 71, struct in6_ifreq)
00385 #define SIOCGIFPDSTADDR_IN6     _IOWR('i', 72, struct in6_ifreq)
00386
00387 #define SIOCGIFAFLAG_IN6        _IOWR('i', 73, struct in6_ifreq)
00388
00389 #define SIOCGDRLST_IN6          _IOWR('i', 74, struct in6_drlist)
00390 #define SIOCGPRLST_IN6          _IOWR('i', 75, struct in6_prlist)
00391 #ifdef _KERNEL
00392 #define OSIOCGIFINFO_IN6        _IOWR('i', 76, struct in6_ondireq)
00393 #endif
00394 #define SIOCGIFINFO_IN6         _IOWR('i', 108, struct in6_ndireq)
00395 #define SIOCSNDFLUSH_IN6        _IOWR('i', 77, struct in6_ifreq)
00396 #define SIOCGNBRINFO_IN6        _IOWR('i', 78, struct in6_nbrinfo)
00397 #define SIOCSPFXFLUSH_IN6       _IOWR('i', 79, struct in6_ifreq)
00398 #define SIOCSRTRFLUSH_IN6       _IOWR('i', 80, struct in6_ifreq)
00399
00400 #define SIOCGIFALIFETIME_IN6    _IOWR('i', 81, struct in6_ifreq)
00401 #define SIOCSIFALIFETIME_IN6    _IOWR('i', 82, struct in6_ifreq)
00402 #define SIOCGIFSTAT_IN6         _IOWR('i', 83, struct in6_ifreq)
00403 #define SIOCGIFSTAT_ICMP6       _IOWR('i', 84, struct in6_ifreq)
00404
00405 #define SIOCSDEFIFACE_IN6       _IOWR('i', 85, struct in6_ndifreq)
00406 #define SIOCGDEFIFACE_IN6       _IOWR('i', 86, struct in6_ndifreq)
00407
00408 #define SIOCSIFINFO_FLAGS       _IOWR('i', 87, struct in6_ndireq) /* XXX */
00409
00410 #define SIOCSSCOPE6             _IOW('i', 88, struct in6_ifreq)
00411 #define SIOCGSCOPE6             _IOWR('i', 89, struct in6_ifreq)
00412 #define SIOCGSCOPE6DEF          _IOWR('i', 90, struct in6_ifreq)
00413
00414 #define SIOCSIFPREFIX_IN6       _IOW('i', 100, struct in6_prefixreq) /* set */
00415 #define SIOCGIFPREFIX_IN6       _IOWR('i', 101, struct in6_prefixreq) /* get */
00416 #define SIOCDIFPREFIX_IN6       _IOW('i', 102, struct in6_prefixreq) /* del */
00417 #define SIOCAIFPREFIX_IN6       _IOW('i', 103, struct in6_rrenumreq) /* add */
00418 #define SIOCCIFPREFIX_IN6       _IOW('i', 104, \
00419                                      struct in6_rrenumreq) /* change */
00420 #define SIOCSGIFPREFIX_IN6      _IOW('i', 105, \
00421                                      struct in6_rrenumreq) /* set global */
00422
00423 #define SIOCGETSGCNT_IN6        _IOWR('u', 106, \
00424                                       struct sioc_sg_req6) /* get s,g pkt cnt */
00425 #define SIOCGETMIFCNT_IN6       _IOWR('u', 107, \
00426                                       struct sioc_mif_req6) /* get pkt cnt per if */
00427
00428 #define IN6_IFF_ANYCAST         0x01    /* anycast address */
00429 #define IN6_IFF_TENTATIVE       0x02    /* tentative address */
00430 #define IN6_IFF_DUPLICATED      0x04    /* DAD detected duplicate */
00431 #define IN6_IFF_DETACHED        0x08    /* may be detached from the link */
00432 #define IN6_IFF_DEPRECATED      0x10    /* deprecated address */
00433 #define IN6_IFF_NODAD           0x20    /* don't perform DAD on this address
00434                                          * (used only at first SIOC* call)
00435                                          */
00436 #define IN6_IFF_AUTOCONF        0x40    /* autoconfigurable address. */
00437 #define IN6_IFF_TEMPORARY       0x80    /* temporary (anonymous) address. */
00438 #define IN6_IFF_NOPFX           0x8000  /* skip kernel prefix management.
00439                                          * XXX: this should be temporary.
00440                                          */
00441
00442 /* do not input/output */
00443 #define IN6_IFF_NOTREADY (IN6_IFF_TENTATIVE|IN6_IFF_DUPLICATED)
00444
00445 #ifdef _KERNEL
00446 #define IN6_ARE_SCOPE_CMP(a,b) ((a)-(b))
00447 #define IN6_ARE_SCOPE_EQUAL(a,b) ((a)==(b))
00448 #endif
00449
00450 #ifdef _KERNEL
00451 extern struct in6_ifaddr *in6_ifaddr;
00452
00453 extern struct in6_ifstat **in6_ifstat;
00454 extern size_t in6_ifstatmax;
00455 extern struct icmp6stat icmp6stat;
00456 extern struct icmp6_ifstat **icmp6_ifstat;
00457 extern size_t icmp6_ifstatmax;
00458 #define in6_ifstat_inc(ifp, tag) \
00459 do {                                                            \
00460         if ((ifp) && (ifp)->if_index <= if_index                \
00461          && (ifp)->if_index < in6_ifstatmax                     \
00462          && in6_ifstat && in6_ifstat[(ifp)->if_index]) {        \
00463                 in6_ifstat[(ifp)->if_index]->tag++;             \
00464         }                                                       \
00465 } while (0)
00466
00467 extern struct ifqueue ip6intrq;         /* IP6 packet input queue */
00468 extern struct in6_addr zeroin6_addr;
00469 extern u_char inet6ctlerrmap[];
00470 extern unsigned long in6_maxmtu;
00471 #ifdef MALLOC_DECLARE
00472 MALLOC_DECLARE(M_IPMADDR);
00473 #endif
00474
00475 /*
00476  * Macro for finding the internet address structure (in6_ifaddr) corresponding
00477  * to a given interface (ifnet structure).
00478  */
00479
00480 #define IFP_TO_IA6(ifp, ia)                             \
00481 /* struct ifnet *ifp; */                                \
00482 /* struct in6_ifaddr *ia; */                            \
00483 do {                                                                    \
00484         struct ifaddr *ifa;                                             \
00485         for (ifa = (ifp)->if_addrlist.tqh_first; ifa; ifa = ifa->ifa_list.tqe_next) {   \
00486                 if (!ifa->ifa_addr)                                     \
00487                         continue;                                       \
00488                 if (ifa->ifa_addr->sa_family == AF_INET6)               \
00489                         break;                                          \
00490         }                                                               \
00491         (ia) = (struct in6_ifaddr *)ifa;                                \
00492 } while (0)
00493
00494 #endif /* _KERNEL */
00495
00496 /*
00497  * Multi-cast membership entry.  One for each group/ifp that a PCB
00498  * belongs to.
00499  */
00500 struct in6_multi_mship {
00501         struct  in6_multi *i6mm_maddr;  /* Multicast address pointer */
00502         LIST_ENTRY(in6_multi_mship) i6mm_chain;  /* multicast options chain */
00503 };
00504
00505 struct  in6_multi {
00506         LIST_ENTRY(in6_multi) in6m_entry; /* list glue */
00507         struct  in6_addr in6m_addr;     /* IP6 multicast address */
00508         struct  ifnet *in6m_ifp;        /* back pointer to ifnet */
00509         struct  ifmultiaddr *in6m_ifma; /* back pointer to ifmultiaddr */
00510         u_int   in6m_refcount;          /* # membership claims by sockets */
00511         u_int   in6m_state;             /* state of the membership */
00512         u_int   in6m_timer;             /* MLD6 listener report timer */
00513 };
00514
00515 #ifdef _KERNEL
00516 extern LIST_HEAD(in6_multihead, in6_multi) in6_multihead;
00517
00518 /*
00519  * Structure used by macros below to remember position when stepping through
00520  * all of the in6_multi records.
00521  */
00522 struct  in6_multistep {
00523         struct  in6_ifaddr *i_ia;
00524         struct  in6_multi *i_in6m;
00525 };
00526
00527 /*
00528  * Macros for looking up the in6_multi record for a given IP6 multicast
00529  * address on a given interface. If no matching record is found, "in6m"
00530  * returns NLL.
00531  */
00532
00533 #define IN6_LOOKUP_MULTI(addr, ifp, in6m)                       \
00534 /* struct in6_addr addr; */                                     \
00535 /* struct ifnet *ifp; */                                        \
00536 /* struct in6_multi *in6m; */                                   \
00537 do { \
00538         struct ifmultiaddr *ifma; \
00539         TAILQ_FOREACH(ifma, &(ifp)->if_multiaddrs, ifma_link) { \
00540                 if (ifma->ifma_addr->sa_family == AF_INET6 \
00541                     && IN6_ARE_ADDR_EQUAL(&((struct sockaddr_in6 *)ifma->ifma_addr)->sin6_addr, \
00542                                           &(addr))) \
00543                         break; \
00544         } \
00545         (in6m) = (struct in6_multi *)(ifma ? ifma->ifma_protospec : 0); \
00546 } while(0)
00547
00548 /*
00549  * Macro to step through all of the in6_multi records, one at a time.
00550  * The current position is remembered in "step", which the caller must
00551  * provide.  IN6_FIRST_MULTI(), below, must be called to initialize "step"
00552  * and get the first record.  Both macros return a NULL "in6m" when there
00553  * are no remaining records.
00554  */
00555 #define IN6_NEXT_MULTI(step, in6m)                                      \
00556 /* struct in6_multistep step; */                                        \
00557 /* struct in6_multi *in6m; */                                           \
00558 do { \
00559         if (((in6m) = (step).i_in6m) != NULL) \
00560                 (step).i_in6m = (step).i_in6m->in6m_entry.le_next; \
00561 } while(0)
00562
00563 #define IN6_FIRST_MULTI(step, in6m)             \
00564 /* struct in6_multistep step; */                \
00565 /* struct in6_multi *in6m */                    \
00566 do { \
00567         (step).i_in6m = in6_multihead.lh_first; \
00568                 IN6_NEXT_MULTI((step), (in6m)); \
00569 } while(0)
00570
00571 struct  in6_multi *in6_addmulti __P((struct in6_addr *, struct ifnet *,
00572                                      int *));
00573 void    in6_delmulti __P((struct in6_multi *));
00574 extern int in6_ifindex2scopeid __P((int));
00575 extern int in6_mask2len __P((struct in6_addr *, u_char *));
00576 extern void in6_len2mask __P((struct in6_addr *, int));
00577 int     in6_control __P((struct socket *,
00578                          u_long, caddr_t, struct ifnet *, struct thread *));
00579 int     in6_update_ifa __P((struct ifnet *, struct in6_aliasreq *,
00580                             struct in6_ifaddr *));
00581 void    in6_purgeaddr __P((struct ifaddr *));
00582 int     in6if_do_dad __P((struct ifnet *));
00583 void    in6_purgeif __P((struct ifnet *));
00584 void    in6_savemkludge __P((struct in6_ifaddr *));
00585 void    in6_setmaxmtu   __P((void));
00586 void    in6_restoremkludge __P((struct in6_ifaddr *, struct ifnet *));
00587 void    in6_purgemkludge __P((struct ifnet *));
00588 struct in6_ifaddr *in6ifa_ifpforlinklocal __P((struct ifnet *, int));
00589 struct in6_ifaddr *in6ifa_ifpwithaddr __P((struct ifnet *,
00590                                              struct in6_addr *));
00591 char    *ip6_sprintf __P((const struct in6_addr *));
00592 int     in6_addr2scopeid __P((struct ifnet *, struct in6_addr *));
00593 int     in6_matchlen __P((struct in6_addr *, struct in6_addr *));
00594 int     in6_are_prefix_equal __P((struct in6_addr *p1, struct in6_addr *p2,
00595                                   int len));
00596 void    in6_prefixlen2mask __P((struct in6_addr *maskp, int len));
00597 int     in6_prefix_ioctl __P((struct socket *so, u_long cmd, caddr_t data,
00598                               struct ifnet *ifp));
00599 int     in6_prefix_add_ifid __P((int iilen, struct in6_ifaddr *ia));
00600 void    in6_prefix_remove_ifid __P((int iilen, struct in6_ifaddr *ia));
00601 void    in6_purgeprefix __P((struct ifnet *));
00602
00603 int     in6_is_addr_deprecated __P((struct sockaddr_in6 *));
00604 struct inpcb;
00605 int in6_embedscope __P((struct in6_addr *, const struct sockaddr_in6 *,
00606         struct inpcb *, struct ifnet **));
00607 int in6_recoverscope __P((struct sockaddr_in6 *, const struct in6_addr *,
00608         struct ifnet *));
00609 void in6_clearscope __P((struct in6_addr *));
00610 #endif /* _KERNEL */
00611
00612 #endif /* _NETINET6_IN6_VAR_H_ */
Generated on Wed Jan 25 15:42:33 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/netinet6/IP6_ECN.H Source File

inc/netinet6/IP6_ECN.H

Go to the documentation of this file.
00001
00005 /*      $FreeBSD: src/sys/netinet6/ip6_ecn.h,v 1.4 2001/06/11 12:39:05 ume Exp $        */
00006 /*      $KAME: ip_ecn.h,v 1.5 2000/03/27 04:58:38 sumikawa Exp $        */
00007
00008 /*
00009  * Copyright (C) 1999 WIDE Project.
00010  * All rights reserved.
00011  *
00012  * Redistribution and use in source and binary forms, with or without
00013  * modification, are permitted provided that the following conditions
00014  * are met:
00015  * 1. Redistributions of source code must retain the above copyright
00016  *    notice, this list of conditions and the following disclaimer.
00017  * 2. Redistributions in binary form must reproduce the above copyright
00018  *    notice, this list of conditions and the following disclaimer in the
00019  *    documentation and/or other materials provided with the distribution.
00020  * 3. Neither the name of the project nor the names of its contributors
00021  *    may be used to endorse or promote products derived from this software
00022  *    without specific prior written permission.
00023  *
00024  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
00025  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00026  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00027  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
00028  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00029  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00030  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00031  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00032  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00033  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00034  * SUCH DAMAGE.
00035  *
00036  */
00037 /*
00038  * ECN consideration on tunnel ingress/egress operation.
00039  * http://www.aciri.org/floyd/papers/draft-ipsec-ecn-00.txt
00040  */
00041
00042 #ifdef _KERNEL
00043 extern void ip6_ecn_ingress __P((int, u_int32_t *, const u_int32_t *));
00044 extern void ip6_ecn_egress __P((int, const u_int32_t *, u_int32_t *));
00045 #endif
Generated on Wed Jan 25 15:42:33 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/netinet6/IP6_FW.H Source File

inc/netinet6/IP6_FW.H

Go to the documentation of this file.
00001
00005 /*      $FreeBSD: src/sys/netinet6/ip6_fw.h,v 1.12 2002/04/19 04:46:22 suz Exp $        */
00006 /*      $KAME: ip6_fw.h,v 1.9 2001/08/01 04:29:57 sumikawa Exp $        */
00007
00008 /*
00009  * Copyright (C) 1998, 1999, 2000 and 2001 WIDE Project.
00010  * All rights reserved.
00011  *
00012  * Redistribution and use in source and binary forms, with or without
00013  * modification, are permitted provided that the following conditions
00014  * are met:
00015  * 1. Redistributions of source code must retain the above copyright
00016  *    notice, this list of conditions and the following disclaimer.
00017  * 2. Redistributions in binary form must reproduce the above copyright
00018  *    notice, this list of conditions and the following disclaimer in the
00019  *    documentation and/or other materials provided with the distribution.
00020  * 3. Neither the name of the project nor the names of its contributors
00021  *    may be used to endorse or promote products derived from this software
00022  *    without specific prior written permission.
00023  *
00024  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
00025  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00026  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00027  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
00028  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00029  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00030  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00031  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00032  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00033  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00034  * SUCH DAMAGE.
00035  */
00036
00037 /*
00038  * Copyright (c) 1993 Daniel Boulet
00039  * Copyright (c) 1994 Ugen J.S.Antsilevich
00040  *
00041  * Redistribution and use in source forms, with and without modification,
00042  * are permitted provided that this entire comment appears intact.
00043  *
00044  * Redistribution in binary form may occur without any restrictions.
00045  * Obviously, it would be nice if you gave credit where credit is due
00046  * but requiring it would be too onerous.
00047  *
00048  * This software is provided ``AS IS'' without any warranties of any kind.
00049  *
00050  */
00051
00052 #ifndef _IP6_FW_H
00053 #define _IP6_FW_H
00054
00055 #include <net/if.h>
00056
00057 /*
00058  * This union structure identifies an interface, either explicitly
00059  * by name or implicitly by IP address. The flags IP_FW_F_IIFNAME
00060  * and IP_FW_F_OIFNAME say how to interpret this structure. An
00061  * interface unit number of -1 matches any unit number, while an
00062  * IP address of 0.0.0.0 indicates matches any interface.
00063  *
00064  * The receive and transmit interfaces are only compared against the
00065  * the packet if the corresponding bit (IP_FW_F_IIFACE or IP_FW_F_OIFACE)
00066  * is set. Note some packets lack a receive or transmit interface
00067  * (in which case the missing "interface" never matches).
00068  */
00069
00070 union ip6_fw_if {
00071     struct in6_addr fu_via_ip6; /* Specified by IPv6 address */
00072     struct {                    /* Specified by interface name */
00073 #define IP6FW_IFNLEN     IFNAMSIZ
00074             char  name[IP6FW_IFNLEN];
00075             short unit;         /* -1 means match any unit */
00076     } fu_via_if;
00077 };
00078
00079 /*
00080  * Format of an IP firewall descriptor
00081  *
00082  * fw_src, fw_dst, fw_smsk, fw_dmsk are always stored in network byte order.
00083  * fw_flg and fw_n*p are stored in host byte order (of course).
00084  * Port numbers are stored in HOST byte order.
00085  * Warning: setsockopt() will fail if sizeof(struct ip_fw) > MLEN (108)
00086  */
00087
00088 struct ip6_fw {
00089     u_long fw_pcnt,fw_bcnt;             /* Packet and byte counters */
00090     struct in6_addr fw_src, fw_dst;     /* Source and destination IPv6 addr */
00091     struct in6_addr fw_smsk, fw_dmsk;   /* Mask for src and dest IPv6 addr */
00092     u_short fw_number;                  /* Rule number */
00093     u_short fw_flg;                     /* Flags word */
00094 #define IPV6_FW_MAX_PORTS       10      /* A reasonable maximum */
00095     u_int fw_ipflg;                     /* IP flags word */
00096     u_short fw_pts[IPV6_FW_MAX_PORTS];  /* Array of port numbers to match */
00097     u_char fw_ip6opt,fw_ip6nopt;        /* IPv6 options set/unset */
00098     u_char fw_tcpf,fw_tcpnf;            /* TCP flags set/unset */
00099 #define IPV6_FW_ICMPTYPES_DIM (256 / (sizeof(unsigned) * 8))
00100     unsigned fw_icmp6types[IPV6_FW_ICMPTYPES_DIM]; /* ICMP types bitmap */
00101     long timestamp;                     /* timestamp (tv_sec) of last match */
00102     union ip6_fw_if fw_in_if, fw_out_if;/* Incoming and outgoing interfaces */
00103     union {
00104         u_short fu_divert_port;         /* Divert/tee port (options IP6DIVERT) */
00105         u_short fu_skipto_rule;         /* SKIPTO command rule number */
00106         u_short fu_reject_code;         /* REJECT response code */
00107     } fw_un;
00108     u_char fw_prot;                     /* IPv6 protocol */
00109     u_char fw_nports;                   /* N'of src ports and # of dst ports */
00110                                         /* in ports array (dst ports follow */
00111                                         /* src ports; max of 10 ports in all; */
00112                                         /* count of 0 means match all ports) */
00113 };
00114
00115 #define IPV6_FW_GETNSRCP(rule)          ((rule)->fw_nports & 0x0f)
00116 #define IPV6_FW_SETNSRCP(rule, n)               do {                            \
00117                                           (rule)->fw_nports &= ~0x0f;   \
00118                                           (rule)->fw_nports |= (n);     \
00119                                         } while (0)
00120 #define IPV6_FW_GETNDSTP(rule)          ((rule)->fw_nports >> 4)
00121 #define IPV6_FW_SETNDSTP(rule, n)               do {                            \
00122                                           (rule)->fw_nports &= ~0xf0;   \
00123                                           (rule)->fw_nports |= (n) << 4;\
00124                                         } while (0)
00125
00126 #define fw_divert_port  fw_un.fu_divert_port
00127 #define fw_skipto_rule  fw_un.fu_skipto_rule
00128 #define fw_reject_code  fw_un.fu_reject_code
00129
00130 struct ip6_fw_chain {
00131         LIST_ENTRY(ip6_fw_chain) chain;
00132         struct ip6_fw    *rule;
00133 };
00134
00135 /*
00136  * Values for "flags" field .
00137  */
00138 #define IPV6_FW_F_IN    0x0001  /* Check inbound packets                */
00139 #define IPV6_FW_F_OUT   0x0002  /* Check outbound packets               */
00140 #define IPV6_FW_F_IIFACE        0x0004  /* Apply inbound interface test         */
00141 #define IPV6_FW_F_OIFACE        0x0008  /* Apply outbound interface test        */
00142
00143 #define IPV6_FW_F_COMMAND 0x0070        /* Mask for type of chain entry:        */
00144 #define IPV6_FW_F_DENY  0x0000  /* This is a deny rule                  */
00145 #define IPV6_FW_F_REJECT        0x0010  /* Deny and send a response packet      */
00146 #define IPV6_FW_F_ACCEPT        0x0020  /* This is an accept rule               */
00147 #define IPV6_FW_F_COUNT 0x0030  /* This is a count rule                 */
00148 #define IPV6_FW_F_DIVERT        0x0040  /* This is a divert rule                */
00149 #define IPV6_FW_F_TEE   0x0050  /* This is a tee rule                   */
00150 #define IPV6_FW_F_SKIPTO        0x0060  /* This is a skipto rule                */
00151
00152 #define IPV6_FW_F_PRN   0x0080  /* Print if this rule matches           */
00153
00154 #define IPV6_FW_F_SRNG  0x0100  /* The first two src ports are a min    *
00155                                  * and max range (stored in host byte   *
00156                                  * order).                              */
00157
00158 #define IPV6_FW_F_DRNG  0x0200  /* The first two dst ports are a min    *
00159                                  * and max range (stored in host byte   *
00160                                  * order).                              */
00161
00162 #define IPV6_FW_F_IIFNAME       0x0400  /* In interface by name/unit (not IP)   */
00163 #define IPV6_FW_F_OIFNAME       0x0800  /* Out interface by name/unit (not IP)  */
00164
00165 #define IPV6_FW_F_INVSRC        0x1000  /* Invert sense of src check            */
00166 #define IPV6_FW_F_INVDST        0x2000  /* Invert sense of dst check            */
00167
00168 #define IPV6_FW_F_FRAG  0x4000  /* Fragment                             */
00169
00170 #define IPV6_FW_F_ICMPBIT 0x8000        /* ICMP type bitmap is valid            */
00171
00172 #define IPV6_FW_F_MASK  0xFFFF  /* All possible flag bits mask          */
00173
00174 /*
00175  * Flags for the 'fw_ipflg' field, for comparing values of ip and its protocols. */
00176 #define IPV6_FW_IF_TCPEST 0x00000020    /* established TCP connection   */
00177 #define IPV6_FW_IF_TCPMSK 0x00000020    /* mask of all TCP values */
00178
00179 /*
00180  * For backwards compatibility with rules specifying "via iface" but
00181  * not restricted to only "in" or "out" packets, we define this combination
00182  * of bits to represent this configuration.
00183  */
00184
00185 #define IF6_FW_F_VIAHACK        (IPV6_FW_F_IN|IPV6_FW_F_OUT|IPV6_FW_F_IIFACE|IPV6_FW_F_OIFACE)
00186
00187 /*
00188  * Definitions for REJECT response codes.
00189  * Values less than 256 correspond to ICMP unreachable codes.
00190  */
00191 #define IPV6_FW_REJECT_RST      0x0100          /* TCP packets: send RST */
00192
00193 /*
00194  * Definitions for IPv6 option names.
00195  */
00196 #define IPV6_FW_IP6OPT_HOPOPT   0x01
00197 #define IPV6_FW_IP6OPT_ROUTE    0x02
00198 #define IPV6_FW_IP6OPT_FRAG     0x04
00199 #define IPV6_FW_IP6OPT_ESP      0x08
00200 #define IPV6_FW_IP6OPT_AH       0x10
00201 #define IPV6_FW_IP6OPT_NONXT    0x20
00202 #define IPV6_FW_IP6OPT_OPTS     0x40
00203
00204 /*
00205  * Definitions for TCP flags.
00206  */
00207 #define IPV6_FW_TCPF_FIN        TH_FIN
00208 #define IPV6_FW_TCPF_SYN        TH_SYN
00209 #define IPV6_FW_TCPF_RST        TH_RST
00210 #define IPV6_FW_TCPF_PSH        TH_PUSH
00211 #define IPV6_FW_TCPF_ACK        TH_ACK
00212 #define IPV6_FW_TCPF_URG        TH_URG
00213
00214 /*
00215  * Main firewall chains definitions and global var's definitions.
00216  */
00217 #ifdef _KERNEL
00218
00219 /*
00220  * Function definitions.
00221  */
00222 void ip6_fw_init(void);
00223
00224 /* Firewall hooks */
00225 struct ip6_hdr;
00226 typedef int ip6_fw_chk_t __P((struct ip6_hdr**, struct ifnet*,
00227                                 u_short *, struct mbuf**));
00228 typedef int ip6_fw_ctl_t __P((int, struct mbuf**));
00229 extern  ip6_fw_chk_t *ip6_fw_chk_ptr;
00230 extern  ip6_fw_ctl_t *ip6_fw_ctl_ptr;
00231 extern  int ip6_fw_enable;
00232
00233 #endif /* _KERNEL */
00234
00235 #endif /* _IP6_FW_H */
Generated on Wed Jan 25 15:42:33 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/netinet6/IP6_MROU.H Source File

inc/netinet6/IP6_MROU.H

Go to the documentation of this file.
00001
00005 /*      $FreeBSD: src/sys/netinet6/ip6_mroute.h,v 1.5 2002/04/19 04:46:23 suz Exp $     */
00006 /*      $KAME: ip6_mroute.h,v 1.19 2001/06/14 06:12:55 suz Exp $        */
00007
00008 /*
00009  * Copyright (C) 1998 WIDE Project.
00010  * All rights reserved.
00011  *
00012  * Redistribution and use in source and binary forms, with or without
00013  * modification, are permitted provided that the following conditions
00014  * are met:
00015  * 1. Redistributions of source code must retain the above copyright
00016  *    notice, this list of conditions and the following disclaimer.
00017  * 2. Redistributions in binary form must reproduce the above copyright
00018  *    notice, this list of conditions and the following disclaimer in the
00019  *    documentation and/or other materials provided with the distribution.
00020  * 3. Neither the name of the project nor the names of its contributors
00021  *    may be used to endorse or promote products derived from this software
00022  *    without specific prior written permission.
00023  *
00024  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
00025  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00026  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00027  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
00028  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00029  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00030  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00031  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00032  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00033  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00034  * SUCH DAMAGE.
00035  */
00036
00037 /*      BSDI ip_mroute.h,v 2.5 1996/10/11 16:01:48 pjd Exp      */
00038
00039 /*
00040  * Definitions for IP multicast forwarding.
00041  *
00042  * Written by David Waitzman, BBN Labs, August 1988.
00043  * Modified by Steve Deering, Stanford, February 1989.
00044  * Modified by Ajit Thyagarajan, PARC, August 1993.
00045  * Modified by Ajit Thyagarajan, PARC, August 1994.
00046  * Modified by Ahmed Helmy, USC, September 1996.
00047  *
00048  * MROUTING Revision: 1.2
00049  */
00050
00051 #ifndef _NETINET6_IP6_MROUTE_H_
00052 #define _NETINET6_IP6_MROUTE_H_
00053
00054 /*
00055  * Multicast Routing set/getsockopt commands.
00056  */
00057 #ifdef _KERNEL
00058 #define MRT6_OINIT              100     /* initialize forwarder (omrt6msg) */
00059 #endif
00060 #define MRT6_DONE               101     /* shut down forwarder */
00061 #define MRT6_ADD_MIF            102     /* add multicast interface */
00062 #define MRT6_DEL_MIF            103     /* delete multicast interface */
00063 #define MRT6_ADD_MFC            104     /* insert forwarding cache entry */
00064 #define MRT6_DEL_MFC            105     /* delete forwarding cache entry */
00065 #define MRT6_PIM                107     /* enable pim code */
00066 #define MRT6_INIT               108     /* initialize forwarder (mrt6msg) */
00067
00068 #if BSD >= 199103
00069 #define GET_TIME(t)     microtime(&t)
00070 #elif defined(sun)
00071 #define GET_TIME(t)     uniqtime(&t)
00072 #else
00073 #define GET_TIME(t)     ((t) = time)
00074 #endif
00075
00076 /*
00077  * Types and macros for handling bitmaps with one bit per multicast interface.
00078  */
00079 typedef u_short mifi_t;         /* type of a mif index */
00080 #define MAXMIFS         64
00081
00082 #ifndef IF_SETSIZE
00083 #define IF_SETSIZE      256
00084 #endif
00085
00086 typedef u_int32_t       if_mask;
00087 #define NIFBITS (sizeof(if_mask) * NBBY)        /* bits per mask */
00088
00089 #ifndef howmany
00090 #define howmany(x, y)   (((x) + ((y) - 1)) / (y))
00091 #endif
00092
00093 typedef struct if_set {
00094         if_mask ifs_bits[howmany(IF_SETSIZE, NIFBITS)];
00095 } if_set;
00096
00097 #define IF_SET(n, p)    ((p)->ifs_bits[(n)/NIFBITS] |= (1 << ((n) % NIFBITS)))
00098 #define IF_CLR(n, p)    ((p)->ifs_bits[(n)/NIFBITS] &= ~(1 << ((n) % NIFBITS)))
00099 #define IF_ISSET(n, p)  ((p)->ifs_bits[(n)/NIFBITS] & (1 << ((n) % NIFBITS)))
00100 #define IF_COPY(f, t)   bcopy(f, t, sizeof(*(f)))
00101 #define IF_ZERO(p)      bzero(p, sizeof(*(p)))
00102
00103 /*
00104  * Argument structure for MRT6_ADD_IF.
00105  */
00106 struct mif6ctl {
00107         mifi_t      mif6c_mifi;         /* the index of the mif to be added  */
00108         u_char      mif6c_flags;        /* MIFF_ flags defined below         */
00109         u_short     mif6c_pifi;         /* the index of the physical IF */
00110 #ifdef notyet
00111         u_int       mif6c_rate_limit;    /* max rate                         */
00112 #endif
00113 };
00114
00115 #define MIFF_REGISTER   0x1     /* mif represents a register end-point */
00116
00117 /*
00118  * Argument structure for MRT6_ADD_MFC and MRT6_DEL_MFC
00119  */
00120 struct mf6cctl {
00121         struct sockaddr_in6 mf6cc_origin;       /* IPv6 origin of mcasts */
00122         struct sockaddr_in6 mf6cc_mcastgrp; /* multicast group associated */
00123         mifi_t          mf6cc_parent;   /* incoming ifindex */
00124         struct if_set   mf6cc_ifset;    /* set of forwarding ifs */
00125 };
00126
00127 /*
00128  * The kernel's multicast routing statistics.
00129  */
00130 struct mrt6stat {
00131         u_quad_t mrt6s_mfc_lookups;     /* # forw. cache hash table hits   */
00132         u_quad_t mrt6s_mfc_misses;      /* # forw. cache hash table misses */
00133         u_quad_t mrt6s_upcalls;         /* # calls to mrouted              */
00134         u_quad_t mrt6s_no_route;        /* no route for packet's origin    */
00135         u_quad_t mrt6s_bad_tunnel;      /* malformed tunnel options        */
00136         u_quad_t mrt6s_cant_tunnel;     /* no room for tunnel options      */
00137         u_quad_t mrt6s_wrong_if;        /* arrived on wrong interface      */
00138         u_quad_t mrt6s_upq_ovflw;       /* upcall Q overflow               */
00139         u_quad_t mrt6s_cache_cleanups;  /* # entries with no upcalls       */
00140         u_quad_t mrt6s_drop_sel;        /* pkts dropped selectively        */
00141         u_quad_t mrt6s_q_overflow;      /* pkts dropped - Q overflow       */
00142         u_quad_t mrt6s_pkt2large;       /* pkts dropped - size > BKT SIZE  */
00143         u_quad_t mrt6s_upq_sockfull;    /* upcalls dropped - socket full   */
00144 };
00145
00146 #ifdef MRT6_OINIT
00147 /*
00148  * Struct used to communicate from kernel to multicast router
00149  * note the convenient similarity to an IPv6 header.
00150  * XXX old version, superseded by mrt6msg.
00151  */
00152 struct omrt6msg {
00153         u_long      unused1;
00154         u_char      im6_msgtype;                /* what type of message     */
00155 #if 0
00156 #define MRT6MSG_NOCACHE 1
00157 #define MRT6MSG_WRONGMIF        2
00158 #define MRT6MSG_WHOLEPKT        3               /* used for user level encap*/
00159 #endif
00160         u_char      im6_mbz;                    /* must be zero             */
00161         u_char      im6_mif;                    /* mif rec'd on             */
00162         u_char      unused2;
00163         struct in6_addr  im6_src, im6_dst;
00164 };
00165 #endif
00166
00167 /*
00168  * Structure used to communicate from kernel to multicast router.
00169  * We'll overlay the structure onto an MLD header (not an IPv6 header
00170  * like igmpmsg{} used for IPv4 implementation). This is because this
00171  * structure will be passed via an IPv6 raw socket, on which an application
00172  * will only receive the payload i.e. the data after the IPv6 header and all
00173  * the extension headers. (see Section 3 of draft-ietf-ipngwg-2292bis-01)
00174  */
00175 struct mrt6msg {
00176 #define MRT6MSG_NOCACHE         1
00177 #define MRT6MSG_WRONGMIF        2
00178 #define MRT6MSG_WHOLEPKT        3               /* used for user level encap*/
00179         u_char      im6_mbz;                    /* must be zero             */
00180         u_char      im6_msgtype;                /* what type of message     */
00181         u_int16_t   im6_mif;                    /* mif rec'd on             */
00182         u_int32_t   im6_pad;                    /* padding for 64bit arch   */
00183         struct in6_addr  im6_src, im6_dst;
00184 };
00185
00186 /*
00187  * Argument structure used by multicast routing daemon to get src-grp
00188  * packet counts
00189  */
00190 struct sioc_sg_req6 {
00191         struct sockaddr_in6 src;
00192         struct sockaddr_in6 grp;
00193         u_quad_t pktcnt;
00194         u_quad_t bytecnt;
00195         u_quad_t wrong_if;
00196 };
00197
00198 /*
00199  * Argument structure used by mrouted to get mif pkt counts
00200  */
00201 struct sioc_mif_req6 {
00202         mifi_t mifi;            /* mif number                           */
00203         u_quad_t icount;        /* Input packet count on mif            */
00204         u_quad_t ocount;        /* Output packet count on mif           */
00205         u_quad_t ibytes;        /* Input byte count on mif              */
00206         u_quad_t obytes;        /* Output byte count on mif             */
00207 };
00208
00209 #if defined(_KERNEL) || defined(KERNEL)
00210 /*
00211  * The kernel's multicast-interface structure.
00212  */
00213 struct mif6 {
00214         u_char          m6_flags;       /* MIFF_ flags defined above         */
00215         u_int           m6_rate_limit;  /* max rate                          */
00216 #ifdef notyet
00217         struct tbf      *m6_tbf;        /* token bucket structure at intf.   */
00218 #endif
00219         struct in6_addr m6_lcl_addr;    /* local interface address           */
00220         struct ifnet    *m6_ifp;        /* pointer to interface              */
00221         u_quad_t        m6_pkt_in;      /* # pkts in on interface            */
00222         u_quad_t        m6_pkt_out;     /* # pkts out on interface           */
00223         u_quad_t        m6_bytes_in;    /* # bytes in on interface           */
00224         u_quad_t        m6_bytes_out;   /* # bytes out on interface          */
00225         struct route_in6 m6_route;/* cached route if this is a tunnel */
00226 #ifdef notyet
00227         u_int           m6_rsvp_on;     /* RSVP listening on this vif */
00228         struct socket   *m6_rsvpd;      /* RSVP daemon socket */
00229 #endif
00230 };
00231
00232 /*
00233  * The kernel's multicast forwarding cache entry structure
00234  */
00235 struct mf6c {
00236         struct sockaddr_in6  mf6c_origin;       /* IPv6 origin of mcasts     */
00237         struct sockaddr_in6  mf6c_mcastgrp;     /* multicast group associated*/
00238         mifi_t           mf6c_parent;           /* incoming IF               */
00239         struct if_set    mf6c_ifset;            /* set of outgoing IFs */
00240
00241         u_quad_t        mf6c_pkt_cnt;           /* pkt count for src-grp     */
00242         u_quad_t        mf6c_byte_cnt;          /* byte count for src-grp    */
00243         u_quad_t        mf6c_wrong_if;          /* wrong if for src-grp      */
00244         int             mf6c_expire;            /* time to clean entry up    */
00245         struct timeval  mf6c_last_assert;       /* last time I sent an assert*/
00246         struct rtdetq  *mf6c_stall;             /* pkts waiting for route */
00247         struct mf6c    *mf6c_next;              /* hash table linkage */
00248 };
00249
00250 #define MF6C_INCOMPLETE_PARENT ((mifi_t)-1)
00251
00252 /*
00253  * Argument structure used for pkt info. while upcall is made
00254  */
00255 #ifndef _NETINET_IP_MROUTE_H_
00256 struct rtdetq {         /* XXX: rtdetq is also defined in ip_mroute.h */
00257     struct mbuf         *m;             /* A copy of the packet             */
00258     struct ifnet        *ifp;           /* Interface pkt came in on         */
00259 #ifdef UPCALL_TIMING
00260     struct timeval      t;              /* Timestamp */
00261 #endif /* UPCALL_TIMING */
00262     struct rtdetq       *next;
00263 };
00264 #endif /* _NETINET_IP_MROUTE_H_ */
00265
00266 #define MF6CTBLSIZ      256
00267 #if (MF6CTBLSIZ & (MF6CTBLSIZ - 1)) == 0          /* from sys:route.h */
00268 #define MF6CHASHMOD(h)  ((h) & (MF6CTBLSIZ - 1))
00269 #else
00270 #define MF6CHASHMOD(h)  ((h) % MF6CTBLSIZ)
00271 #endif
00272
00273 #define MAX_UPQ6        4               /* max. no of pkts in upcall Q */
00274
00275 int     ip6_mrouter_set __P((struct socket *so, struct sockopt *sopt));
00276 int     ip6_mrouter_get __P((struct socket *so, struct sockopt *sopt));
00277 int     ip6_mrouter_done __P((void));
00278 int     mrt6_ioctl __P((int, caddr_t));
00279 #endif /* _KERNEL */
00280
00281 #endif /* !_NETINET6_IP6_MROUTE_H_ */
Generated on Wed Jan 25 15:42:33 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/netinet6/IP6_VAR.H Source File

inc/netinet6/IP6_VAR.H

Go to the documentation of this file.
00001
00005 /*      $FreeBSD: src/sys/netinet6/ip6_var.h,v 1.9 2002/07/25 17:40:45 ume Exp $        */
00006 /*      $KAME: ip6_var.h,v 1.62 2001/05/03 14:51:48 itojun Exp $        */
00007
00008 /*
00009  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
00010  * All rights reserved.
00011  *
00012  * Redistribution and use in source and binary forms, with or without
00013  * modification, are permitted provided that the following conditions
00014  * are met:
00015  * 1. Redistributions of source code must retain the above copyright
00016  *    notice, this list of conditions and the following disclaimer.
00017  * 2. Redistributions in binary form must reproduce the above copyright
00018  *    notice, this list of conditions and the following disclaimer in the
00019  *    documentation and/or other materials provided with the distribution.
00020  * 3. Neither the name of the project nor the names of its contributors
00021  *    may be used to endorse or promote products derived from this software
00022  *    without specific prior written permission.
00023  *
00024  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
00025  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00026  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00027  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
00028  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00029  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00030  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00031  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00032  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00033  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00034  * SUCH DAMAGE.
00035  */
00036
00037 /*
00038  * Copyright (c) 1982, 1986, 1993
00039  *      The Regents of the University of California.  All rights reserved.
00040  *
00041  * Redistribution and use in source and binary forms, with or without
00042  * modification, are permitted provided that the following conditions
00043  * are met:
00044  * 1. Redistributions of source code must retain the above copyright
00045  *    notice, this list of conditions and the following disclaimer.
00046  * 2. Redistributions in binary form must reproduce the above copyright
00047  *    notice, this list of conditions and the following disclaimer in the
00048  *    documentation and/or other materials provided with the distribution.
00049  * 3. All advertising materials mentioning features or use of this software
00050  *    must display the following acknowledgement:
00051  *      This product includes software developed by the University of
00052  *      California, Berkeley and its contributors.
00053  * 4. Neither the name of the University nor the names of its contributors
00054  *    may be used to endorse or promote products derived from this software
00055  *    without specific prior written permission.
00056  *
00057  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
00058  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00059  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00060  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
00061  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00062  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00063  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00064  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00065  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00066  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00067  * SUCH DAMAGE.
00068  *
00069  *      @(#)ip_var.h    8.1 (Berkeley) 6/10/93
00070  */
00071
00072 #ifndef _NETINET6_IP6_VAR_H_
00073 #define _NETINET6_IP6_VAR_H_
00074
00075 #include <sys/queue.h>
00076
00077 #if !defined(__BORLANDC__) /* stop warnings for undefined structs */
00078 /*
00079  * IP6 reassembly queue structure.  Each fragment
00080  * being reassembled is attached to one of these structures.
00081  */
00082 struct  ip6q {
00083         u_int32_t       ip6q_head;
00084         u_int16_t       ip6q_len;
00085         u_int8_t        ip6q_nxt;       /* ip6f_nxt in first fragment */
00086         u_int8_t        ip6q_hlim;
00087         struct ip6asfrag *ip6q_down;
00088         struct ip6asfrag *ip6q_up;
00089         u_int32_t       ip6q_ident;
00090         u_int8_t        ip6q_arrive;
00091         u_int8_t        ip6q_ttl;
00092         struct in6_addr ip6q_src, ip6q_dst;
00093         struct ip6q     *ip6q_next;
00094         struct ip6q     *ip6q_prev;
00095         int             ip6q_unfrglen;  /* len of unfragmentable part */
00096 #ifdef notyet
00097         u_char          *ip6q_nxtp;
00098 #endif
00099 };
00100
00101 struct  ip6asfrag {
00102         u_int32_t       ip6af_head;
00103         u_int16_t       ip6af_len;
00104         u_int8_t        ip6af_nxt;
00105         u_int8_t        ip6af_hlim;
00106         /* must not override the above members during reassembling */
00107         struct ip6asfrag *ip6af_down;
00108         struct ip6asfrag *ip6af_up;
00109         struct mbuf     *ip6af_m;
00110         int             ip6af_offset;   /* offset in ip6af_m to next header */
00111         int             ip6af_frglen;   /* fragmentable part length */
00112         int             ip6af_off;      /* fragment offset */
00113         u_int16_t       ip6af_mff;      /* more fragment bit in frag off */
00114 };
00115
00116 #define IP6_REASS_MBUF(ip6af) (*(struct mbuf **)&((ip6af)->ip6af_m))
00117
00118 struct  ip6_moptions {
00119         struct  ifnet *im6o_multicast_ifp; /* ifp for outgoing multicasts */
00120         u_char  im6o_multicast_hlim;    /* hoplimit for outgoing multicasts */
00121         u_char  im6o_multicast_loop;    /* 1 >= hear sends if a member */
00122         LIST_HEAD(dummy, in6_multi_mship) im6o_memberships;
00123 };
00124 #endif   /* __BORLANDC__ */
00125
00126 #ifndef _NETINET6_IN6_H_
00127 struct  route_in6 {
00128         struct  rtentry *ro_rt;
00129         struct  sockaddr_in6 ro_dst;
00130 };
00131 #endif
00132
00133 /*
00134  * Control options for outgoing packets
00135  */
00136
00137 /* Routing header related info */
00138 #if !defined(__BORLANDC__)
00139 struct  ip6po_rhinfo {
00140         struct  ip6_rthdr *ip6po_rhi_rthdr; /* Routing header */
00141         struct  route_in6 ip6po_rhi_route; /* Route to the 1st hop */
00142 };
00143 #define ip6po_rthdr     ip6po_rhinfo.ip6po_rhi_rthdr
00144 #define ip6po_route     ip6po_rhinfo.ip6po_rhi_route
00145
00146 struct  ip6_pktopts {
00147         struct  mbuf *ip6po_m;  /* Pointer to mbuf storing the data */
00148         int     ip6po_hlim;     /* Hoplimit for outgoing packets */
00149
00150         /* Outgoing IF/address information */
00151         struct  in6_pktinfo *ip6po_pktinfo;
00152
00153         struct  sockaddr *ip6po_nexthop; /* Next-hop address */
00154
00155         struct  ip6_hbh *ip6po_hbh; /* Hop-by-Hop options header */
00156
00157         /* Destination options header (before a routing header) */
00158         struct  ip6_dest *ip6po_dest1;
00159
00160         /* Routing header related info. */
00161         struct  ip6po_rhinfo ip6po_rhinfo;
00162
00163         /* Destination options header (after a routing header) */
00164         struct  ip6_dest *ip6po_dest2;
00165 };
00166 #endif   /* __BORLANDC__ */
00167
00168 /*
00169  * Control options for incoming packets
00170  */
00171
00172 struct  ip6stat {
00173         u_quad_t ip6s_total;            /* total packets received */
00174         u_quad_t ip6s_tooshort;         /* packet too short */
00175         u_quad_t ip6s_toosmall;         /* not enough data */
00176         u_quad_t ip6s_fragments;        /* fragments received */
00177         u_quad_t ip6s_fragdropped;      /* frags dropped(dups, out of space) */
00178         u_quad_t ip6s_fragtimeout;      /* fragments timed out */
00179         u_quad_t ip6s_fragoverflow;     /* fragments that exceeded limit */
00180         u_quad_t ip6s_forward;          /* packets forwarded */
00181         u_quad_t ip6s_cantforward;      /* packets rcvd for unreachable dest */
00182         u_quad_t ip6s_redirectsent;     /* packets forwarded on same net */
00183         u_quad_t ip6s_delivered;        /* datagrams delivered to upper level*/
00184         u_quad_t ip6s_localout;         /* total ip packets generated here */
00185         u_quad_t ip6s_odropped;         /* lost packets due to nobufs, etc. */
00186         u_quad_t ip6s_reassembled;      /* total packets reassembled ok */
00187         u_quad_t ip6s_fragmented;       /* datagrams sucessfully fragmented */
00188         u_quad_t ip6s_ofragments;       /* output fragments created */
00189         u_quad_t ip6s_cantfrag;         /* don't fragment flag was set, etc. */
00190         u_quad_t ip6s_badoptions;       /* error in option processing */
00191         u_quad_t ip6s_noroute;          /* packets discarded due to no route */
00192         u_quad_t ip6s_badvers;          /* ip6 version != 6 */
00193         u_quad_t ip6s_rawout;           /* total raw ip packets generated */
00194         u_quad_t ip6s_badscope;         /* scope error */
00195         u_quad_t ip6s_notmember;        /* don't join this multicast group */
00196         u_quad_t ip6s_nxthist[256];     /* next header history */
00197         u_quad_t ip6s_m1;               /* one mbuf */
00198         u_quad_t ip6s_m2m[32];          /* two or more mbuf */
00199         u_quad_t ip6s_mext1;            /* one ext mbuf */
00200         u_quad_t ip6s_mext2m;           /* two or more ext mbuf */
00201         u_quad_t ip6s_exthdrtoolong;    /* ext hdr are not continuous */
00202         u_quad_t ip6s_nogif;            /* no match gif found */
00203         u_quad_t ip6s_toomanyhdr;       /* discarded due to too many headers */
00204
00205         /*
00206          * statistics for improvement of the source address selection
00207          * algorithm:
00208          * XXX: hardcoded 16 = # of ip6 multicast scope types + 1
00209          */
00210         /* number of times that address selection fails */
00211         u_quad_t ip6s_sources_none;
00212         /* number of times that an address on the outgoing I/F is chosen */
00213         u_quad_t ip6s_sources_sameif[16];
00214         /* number of times that an address on a non-outgoing I/F is chosen */
00215         u_quad_t ip6s_sources_otherif[16];
00216         /*
00217          * number of times that an address that has the same scope
00218          * from the destination is chosen.
00219          */
00220         u_quad_t ip6s_sources_samescope[16];
00221         /*
00222          * number of times that an address that has a different scope
00223          * from the destination is chosen.
00224          */
00225         u_quad_t ip6s_sources_otherscope[16];
00226         /* number of times that an deprecated address is chosen */
00227         u_quad_t ip6s_sources_deprecated[16];
00228
00229         u_quad_t ip6s_forward_cachehit;
00230         u_quad_t ip6s_forward_cachemiss;
00231 };
00232
00233 #ifdef _KERNEL
00234 /*
00235  * IPv6 onion peeling state.
00236  * it will be initialized when we come into ip6_input().
00237  * XXX do not make it a kitchen sink!
00238  */
00239 struct ip6aux {
00240         u_int32_t ip6a_flags;
00241 #define IP6A_SWAP       0x01            /* swapped home/care-of on packet */
00242 #define IP6A_HASEEN     0x02            /* HA was present */
00243 #define IP6A_BRUID      0x04            /* BR Unique Identifier was present */
00244 #define IP6A_RTALERTSEEN 0x08           /* rtalert present */
00245
00246         /* ip6.ip6_src */
00247         struct in6_addr ip6a_careof;    /* care-of address of the peer */
00248         struct in6_addr ip6a_home;      /* home address of the peer */
00249         u_int16_t       ip6a_bruid;     /* BR unique identifier */
00250
00251         /* ip6.ip6_dst */
00252         struct in6_ifaddr *ip6a_dstia6; /* my ifaddr that matches ip6_dst */
00253
00254         /* rtalert */
00255         u_int16_t ip6a_rtalert;         /* rtalert option value */
00256
00257         /*
00258          * decapsulation history will be here.
00259          * with IPsec it may not be accurate.
00260          */
00261 };
00262 #endif
00263
00264 #ifdef _KERNEL
00265 /* flags passed to ip6_output as last parameter */
00266 #define IPV6_DADOUTPUT          0x01    /* DAD */
00267 #define IPV6_FORWARDING         0x02    /* most of IPv6 header exists */
00268 #define IPV6_MINMTU             0x04    /* use minimum MTU (IPV6_USE_MIN_MTU) */
00269
00270 extern struct   ip6stat ip6stat;        /* statistics */
00271 extern u_int32_t ip6_id;                /* fragment identifier */
00272 extern int      ip6_defhlim;            /* default hop limit */
00273 extern int      ip6_defmcasthlim;       /* default multicast hop limit */
00274 extern int      ip6_forwarding;         /* act as router? */
00275 extern int      ip6_forward_srcrt;      /* forward src-routed? */
00276 extern int      ip6_gif_hlim;           /* Hop limit for gif encap packet */
00277 extern int      ip6_use_deprecated;     /* allow deprecated addr as source */
00278 extern int      ip6_rr_prune;           /* router renumbering prefix
00279                                          * walk list every 5 sec.    */
00280 extern int      ip6_v6only;
00281
00282 extern struct socket *ip6_mrouter;      /* multicast routing daemon */
00283 extern int      ip6_sendredirects;      /* send IP redirects when forwarding? */
00284 extern int      ip6_maxfragpackets; /* Maximum packets in reassembly queue */
00285 extern int      ip6_sourcecheck;        /* Verify source interface */
00286 extern int      ip6_sourcecheck_interval; /* Interval between log messages */
00287 extern int      ip6_accept_rtadv;       /* Acts as a host not a router */
00288 extern int      ip6_keepfaith;          /* Firewall Aided Internet Translator */
00289 extern int      ip6_log_interval;
00290 extern time_t   ip6_log_time;
00291 extern int      ip6_hdrnestlimit; /* upper limit of # of extension headers */
00292 extern int      ip6_dad_count;          /* DupAddrDetectionTransmits */
00293
00294 extern u_int32_t ip6_flow_seq;
00295 extern int ip6_auto_flowlabel;
00296 extern int ip6_auto_linklocal;
00297
00298 extern int   ip6_anonportmin;           /* minimum ephemeral port */
00299 extern int   ip6_anonportmax;           /* maximum ephemeral port */
00300 extern int   ip6_lowportmin;            /* minimum reserved port */
00301 extern int   ip6_lowportmax;            /* maximum reserved port */
00302
00303 extern int      ip6_use_tempaddr; /* whether to use temporary addresses. */
00304
00305 extern struct   pr_usrreqs rip6_usrreqs;
00306 struct sockopt;
00307
00308 struct inpcb;
00309
00310 int     icmp6_ctloutput __P((struct socket *, struct sockopt *sopt));
00311
00312 struct in6_ifaddr;
00313 void    ip6_init __P((void));
00314 void    ip6intr __P((void));
00315 void    ip6_input __P((struct mbuf *));
00316 struct in6_ifaddr *ip6_getdstifaddr __P((struct mbuf *));
00317 void    ip6_freepcbopts __P((struct ip6_pktopts *));
00318 void    ip6_freemoptions __P((struct ip6_moptions *));
00319 int     ip6_unknown_opt __P((u_int8_t *, struct mbuf *, int));
00320 char *  ip6_get_prevhdr __P((struct mbuf *, int));
00321 int     ip6_nexthdr __P((struct mbuf *, int, int, int *));
00322 int     ip6_lasthdr __P((struct mbuf *, int, int, int *));
00323
00324 struct mbuf *ip6_addaux __P((struct mbuf *));
00325 struct mbuf *ip6_findaux __P((struct mbuf *));
00326 void    ip6_delaux __P((struct mbuf *));
00327
00328 int     ip6_mforward __P((struct ip6_hdr *, struct ifnet *, struct mbuf *));
00329 int     ip6_process_hopopts __P((struct mbuf *, u_int8_t *, int, u_int32_t *,
00330                                  u_int32_t *));
00331 void    ip6_savecontrol __P((struct inpcb *, struct mbuf **, struct ip6_hdr *,
00332                              struct mbuf *));
00333 void    ip6_notify_pmtu __P((struct inpcb *, struct sockaddr_in6 *,
00334                              u_int32_t *));
00335 int     ip6_sysctl __P((int *, u_int, void *, size_t *, void *, size_t));
00336
00337 void    ip6_forward __P((struct mbuf *, int));
00338
00339 void    ip6_mloopback __P((struct ifnet *, struct mbuf *, struct sockaddr_in6 *));
00340 int     ip6_output __P((struct mbuf *, struct ip6_pktopts *,
00341                         struct route_in6 *,
00342                         int,
00343                         struct ip6_moptions *, struct ifnet **));
00344 int     ip6_ctloutput __P((struct socket *, struct sockopt *sopt));
00345 void    init_ip6pktopts __P((struct ip6_pktopts *));
00346 int     ip6_setpktoptions __P((struct mbuf *, struct ip6_pktopts *, int, int));
00347 void    ip6_clearpktopts __P((struct ip6_pktopts *, int, int));
00348 struct ip6_pktopts *ip6_copypktopts __P((struct ip6_pktopts *, int));
00349 int     ip6_optlen __P((struct inpcb *));
00350
00351 int     route6_input __P((struct mbuf **, int *, int));
00352
00353 void    frag6_init __P((void));
00354 int     frag6_input __P((struct mbuf **, int *, int));
00355 void    frag6_slowtimo __P((void));
00356 void    frag6_drain __P((void));
00357
00358 void    rip6_init __P((void));
00359 int     rip6_input __P((struct mbuf **mp, int *offp, int proto));
00360 void    rip6_ctlinput __P((int, struct sockaddr *, void *));
00361 int     rip6_ctloutput __P((struct socket *so, struct sockopt *sopt));
00362 int     rip6_output __P((struct mbuf *, ...));
00363 int     rip6_usrreq __P((struct socket *,
00364             int, struct mbuf *, struct mbuf *, struct mbuf *, struct thread *));
00365
00366 int     dest6_input __P((struct mbuf **, int *, int));
00367 int     none_input __P((struct mbuf **, int *, int));
00368 #endif /* _KERNEL */
00369
00370 #endif /* !_NETINET6_IP6_VAR_H_ */
Generated on Wed Jan 25 15:42:33 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/netinet6/IP6PROTO.H Source File

inc/netinet6/IP6PROTO.H

Go to the documentation of this file.
00001
00005 /*      $FreeBSD: src/sys/netinet6/ip6protosw.h,v 1.9 2002/04/19 04:46:23 suz Exp $     */
00006 /*      $KAME: ip6protosw.h,v 1.25 2001/09/26 06:13:03 keiichi Exp $    */
00007
00008 /*
00009  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
00010  * All rights reserved.
00011  *
00012  * Redistribution and use in source and binary forms, with or without
00013  * modification, are permitted provided that the following conditions
00014  * are met:
00015  * 1. Redistributions of source code must retain the above copyright
00016  *    notice, this list of conditions and the following disclaimer.
00017  * 2. Redistributions in binary form must reproduce the above copyright
00018  *    notice, this list of conditions and the following disclaimer in the
00019  *    documentation and/or other materials provided with the distribution.
00020  * 3. Neither the name of the project nor the names of its contributors
00021  *    may be used to endorse or promote products derived from this software
00022  *    without specific prior written permission.
00023  *
00024  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
00025  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00026  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00027  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
00028  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00029  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00030  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00031  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00032  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00033  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00034  * SUCH DAMAGE.
00035  *
00036  */
00037
00038 /*      BSDI protosw.h,v 2.3 1996/10/11 16:02:40 pjd Exp        */
00039
00040 /*-
00041  * Copyright (c) 1982, 1986, 1993
00042  *      The Regents of the University of California.  All rights reserved.
00043  *
00044  * Redistribution and use in source and binary forms, with or without
00045  * modification, are permitted provided that the following conditions
00046  * are met:
00047  * 1. Redistributions of source code must retain the above copyright
00048  *    notice, this list of conditions and the following disclaimer.
00049  * 2. Redistributions in binary form must reproduce the above copyright
00050  *    notice, this list of conditions and the following disclaimer in the
00051  *    documentation and/or other materials provided with the distribution.
00052  * 3. All advertising materials mentioning features or use of this software
00053  *    must display the following acknowledgement:
00054  *      This product includes software developed by the University of
00055  *      California, Berkeley and its contributors.
00056  * 4. Neither the name of the University nor the names of its contributors
00057  *    may be used to endorse or promote products derived from this software
00058  *    without specific prior written permission.
00059  *
00060  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
00061  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00062  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00063  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
00064  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00065  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00066  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00067  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00068  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00069  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00070  * SUCH DAMAGE.
00071  *
00072  *      @(#)protosw.h   8.1 (Berkeley) 6/2/93
00073  */
00074
00075 #ifndef _NETINET6_IP6PROTOSW_H_
00076 #define _NETINET6_IP6PROTOSW_H_
00077
00078 /*
00079  * For pfil_head structure.
00080  */
00081 #include <net/pfil.h>
00082
00083 /*
00084  * Protocol switch table for IPv6.
00085  * All other definitions should refer to sys/protosw.h
00086  */
00087
00088 struct mbuf;
00089 struct sockaddr;
00090 struct socket;
00091 struct domain;
00092 struct thread;
00093 struct ip6_hdr;
00094 struct icmp6_hdr;
00095 struct in6_addr;
00096 struct pr_usrreqs;
00097
00098 /*
00099  * argument type for the last arg of pr_ctlinput().
00100  * should be consulted only with AF_INET6 family.
00101  *
00102  * IPv6 ICMP IPv6 [exthdrs] finalhdr paylaod
00103  * ^    ^    ^              ^
00104  * |    |    ip6c_ip6       ip6c_off
00105  * |    ip6c_icmp6
00106  * ip6c_m
00107  *
00108  * ip6c_finaldst usually points to ip6c_ip6->ip6_dst.  if the original
00109  * (internal) packet carries a routing header, it may point the final
00110  * dstination address in the routing header.
00111  *
00112  * ip6c_src: ip6c_ip6->ip6_src + scope info + flowlabel in ip6c_ip6
00113  *      (beware of flowlabel, if you try to compare it against others)
00114  * ip6c_dst: ip6c_finaldst + scope info
00115  */
00116 struct ip6ctlparam {
00117         struct mbuf *ip6c_m;            /* start of mbuf chain */
00118         struct icmp6_hdr *ip6c_icmp6;   /* icmp6 header of target packet */
00119         struct ip6_hdr *ip6c_ip6;       /* ip6 header of target packet */
00120         int ip6c_off;                   /* offset of the target proto header */
00121         struct sockaddr_in6 *ip6c_src;  /* srcaddr w/ additional info */
00122         struct sockaddr_in6 *ip6c_dst;  /* (final) dstaddr w/ additional info */
00123         struct in6_addr *ip6c_finaldst; /* final destination address */
00124         void *ip6c_cmdarg;              /* control command dependent data */
00125         u_int8_t ip6c_nxt;              /* final next header field */
00126 };
00127
00128 struct ip6protosw {
00129         short   pr_type;                /* socket type used for */
00130         struct  domain *pr_domain;      /* domain protocol a member of */
00131         short   pr_protocol;            /* protocol number */
00132         short   pr_flags;               /* see below */
00133
00134 /* protocol-protocol hooks */
00135         int     (*pr_input)             /* input to protocol (from below) */
00136                         __P((struct mbuf **, int *, int));
00137         int     (*pr_output)            /* output to protocol (from above) */
00138                         __P((struct mbuf *, ...));
00139         void    (*pr_ctlinput)          /* control input (from below) */
00140                         __P((int, struct sockaddr *, void *));
00141         int     (*pr_ctloutput)         /* control output (from above) */
00142                         __P((struct socket *, struct sockopt *));
00143
00144 /* user-protocol hook */
00145         int     (*pr_usrreq)            /* user request: see list below */
00146                         __P((struct socket *, int, struct mbuf *,
00147                              struct mbuf *, struct mbuf *, struct thread *));
00148
00149 /* utility hooks */
00150         void    (*pr_init)              /* initialization hook */
00151                         __P((void));
00152
00153         void    (*pr_fasttimo)          /* fast timeout (200ms) */
00154                         __P((void));
00155         void    (*pr_slowtimo)          /* slow timeout (500ms) */
00156                         __P((void));
00157         void    (*pr_drain)             /* flush any excess space possible */
00158                         __P((void));
00159         struct  pr_usrreqs *pr_usrreqs; /* supersedes pr_usrreq() */
00160         struct  pfil_head       pr_pfh;
00161 };
00162
00163 #ifdef _KERNEL
00164 extern struct ip6protosw inet6sw[];
00165 #endif
00166
00167 #endif /* !_NETINET6_IP6PROTOSW_H_ */
Generated on Wed Jan 25 15:42:33 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/netinet6/IPCOMP.H Source File

inc/netinet6/IPCOMP.H

Go to the documentation of this file.
00001
00005 /*      $FreeBSD: src/sys/netinet6/ipcomp.h,v 1.4 2002/04/19 04:46:23 suz Exp $ */
00006 /*      $KAME: ipcomp.h,v 1.11 2001/09/04 08:43:19 itojun Exp $ */
00007
00008 /*
00009  * Copyright (C) 1999 WIDE Project.
00010  * All rights reserved.
00011  *
00012  * Redistribution and use in source and binary forms, with or without
00013  * modification, are permitted provided that the following conditions
00014  * are met:
00015  * 1. Redistributions of source code must retain the above copyright
00016  *    notice, this list of conditions and the following disclaimer.
00017  * 2. Redistributions in binary form must reproduce the above copyright
00018  *    notice, this list of conditions and the following disclaimer in the
00019  *    documentation and/or other materials provided with the distribution.
00020  * 3. Neither the name of the project nor the names of its contributors
00021  *    may be used to endorse or promote products derived from this software
00022  *    without specific prior written permission.
00023  *
00024  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
00025  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00026  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00027  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
00028  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00029  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00030  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00031  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00032  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00033  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00034  * SUCH DAMAGE.
00035  */
00036
00037 /*
00038  * RFC2393 IP payload compression protocol (IPComp).
00039  */
00040
00041 #ifndef _NETINET6_IPCOMP_H_
00042 #define _NETINET6_IPCOMP_H_
00043
00044 #if defined(_KERNEL) && !defined(_LKM)
00045 #include "opt_inet.h"
00046 #endif
00047
00048 struct ipcomp {
00049         u_int8_t comp_nxt;      /* Next Header */
00050         u_int8_t comp_flags;    /* reserved, must be zero */
00051         u_int16_t comp_cpi;     /* Compression parameter index */
00052 };
00053
00054 /* well-known algorithm number (in CPI), from RFC2409 */
00055 #define IPCOMP_OUI      1       /* vendor specific */
00056 #define IPCOMP_DEFLATE  2       /* RFC2394 */
00057 #define IPCOMP_LZS      3       /* RFC2395 */
00058 #define IPCOMP_MAX      4
00059
00060 #define IPCOMP_CPI_NEGOTIATE_MIN        256
00061
00062 #ifdef _KERNEL
00063 struct ipcomp_algorithm {
00064         int (*compress) __P((struct mbuf *, struct mbuf *, size_t *));
00065         int (*decompress) __P((struct mbuf *, struct mbuf *, size_t *));
00066         size_t minplen;         /* minimum required length for compression */
00067 };
00068
00069 struct ipsecrequest;
00070 extern const struct ipcomp_algorithm *ipcomp_algorithm_lookup __P((int));
00071 extern void ipcomp4_input __P((struct mbuf *, int));
00072 extern int ipcomp4_output __P((struct mbuf *, struct ipsecrequest *));
00073 #endif /* KERNEL */
00074
00075 #endif /* _NETINET6_IPCOMP_H_ */
Generated on Wed Jan 25 15:42:33 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/netinet6/IPCOMP6.H Source File

inc/netinet6/IPCOMP6.H

Go to the documentation of this file.
00001
00005 /*      $FreeBSD: src/sys/netinet6/ipcomp6.h,v 1.2 2001/06/11 12:39:06 ume Exp $        */
00006 /*      $KAME: ipcomp.h,v 1.8 2000/09/26 07:55:14 itojun Exp $  */
00007
00008 /*
00009  * Copyright (C) 1999 WIDE Project.
00010  * All rights reserved.
00011  *
00012  * Redistribution and use in source and binary forms, with or without
00013  * modification, are permitted provided that the following conditions
00014  * are met:
00015  * 1. Redistributions of source code must retain the above copyright
00016  *    notice, this list of conditions and the following disclaimer.
00017  * 2. Redistributions in binary form must reproduce the above copyright
00018  *    notice, this list of conditions and the following disclaimer in the
00019  *    documentation and/or other materials provided with the distribution.
00020  * 3. Neither the name of the project nor the names of its contributors
00021  *    may be used to endorse or promote products derived from this software
00022  *    without specific prior written permission.
00023  *
00024  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
00025  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00026  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00027  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
00028  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00029  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00030  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00031  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00032  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00033  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00034  * SUCH DAMAGE.
00035  */
00036
00037 /*
00038  * RFC2393 IP payload compression protocol (IPComp).
00039  */
00040
00041 #ifndef _NETINET6_IPCOMP6_H_
00042 #define _NETINET6_IPCOMP6_H_
00043
00044 #ifdef _KERNEL
00045 extern int ipcomp6_input __P((struct mbuf **, int *, int));
00046 extern int ipcomp6_output __P((struct mbuf *, u_char *, struct mbuf *,
00047         struct ipsecrequest *));
00048 #endif /*KERNEL*/
00049
00050 #endif /*_NETINET6_IPCOMP6_H_*/
Generated on Wed Jan 25 15:42:33 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/netinet6/IPSEC.H Source File

inc/netinet6/IPSEC.H

Go to the documentation of this file.
00001
00005 /*      $FreeBSD: src/sys/netinet6/ipsec.h,v 1.9 2002/04/19 04:46:23 suz Exp $  */
00006 /*      $KAME: ipsec.h,v 1.53 2001/11/20 08:32:38 itojun Exp $  */
00007
00008 /*
00009  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
00010  * All rights reserved.
00011  *
00012  * Redistribution and use in source and binary forms, with or without
00013  * modification, are permitted provided that the following conditions
00014  * are met:
00015  * 1. Redistributions of source code must retain the above copyright
00016  *    notice, this list of conditions and the following disclaimer.
00017  * 2. Redistributions in binary form must reproduce the above copyright
00018  *    notice, this list of conditions and the following disclaimer in the
00019  *    documentation and/or other materials provided with the distribution.
00020  * 3. Neither the name of the project nor the names of its contributors
00021  *    may be used to endorse or promote products derived from this software
00022  *    without specific prior written permission.
00023  *
00024  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
00025  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00026  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00027  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
00028  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00029  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00030  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00031  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00032  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00033  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00034  * SUCH DAMAGE.
00035  */
00036
00037 /*
00038  * IPsec controller part.
00039  */
00040
00041 #ifndef _NETINET6_IPSEC_H_
00042 #define _NETINET6_IPSEC_H_
00043
00044 #if defined(_KERNEL) && !defined(_LKM) && !defined(KLD_MODULE)
00045 #include "opt_inet.h"
00046 #include "opt_ipsec.h"
00047 #endif
00048
00049 #include <net/pfkeyv2.h>
00050 #include <netkey/keydb.h>
00051
00052 #ifdef _KERNEL
00053
00054 /*
00055  * Security Policy Index
00056  * Ensure that both address families in the "src" and "dst" are same.
00057  * When the value of the ul_proto is ICMPv6, the port field in "src"
00058  * specifies ICMPv6 type, and the port field in "dst" specifies ICMPv6 code.
00059  */
00060 struct secpolicyindex {
00061         u_int8_t dir;                   /* direction of packet flow, see blow */
00062         struct sockaddr_storage src;    /* IP src address for SP */
00063         struct sockaddr_storage dst;    /* IP dst address for SP */
00064         u_int8_t prefs;                 /* prefix length in bits for src */
00065         u_int8_t prefd;                 /* prefix length in bits for dst */
00066         u_int16_t ul_proto;             /* upper layer Protocol */
00067 #ifdef notyet
00068         uid_t uids;
00069         uid_t uidd;
00070         gid_t gids;
00071         gid_t gidd;
00072 #endif
00073 };
00074
00075 /* Security Policy Data Base */
00076 struct secpolicy {
00077         LIST_ENTRY(secpolicy) chain;
00078
00079         int refcnt;                     /* reference count */
00080         struct secpolicyindex spidx;    /* selector */
00081         u_int32_t id;                   /* It's unique number on the system. */
00082         u_int state;                    /* 0: dead, others: alive */
00083 #define IPSEC_SPSTATE_DEAD      0
00084 #define IPSEC_SPSTATE_ALIVE     1
00085
00086         u_int policy;           /* DISCARD, NONE or IPSEC, see keyv2.h */
00087         struct ipsecrequest *req;
00088                                 /* pointer to the ipsec request tree, */
00089                                 /* if policy == IPSEC else this value == NULL.*/
00090
00091         /*
00092          * lifetime handler.
00093          * the policy can be used without limitiation if both lifetime and
00094          * validtime are zero.
00095          * "lifetime" is passed by sadb_lifetime.sadb_lifetime_addtime.
00096          * "validtime" is passed by sadb_lifetime.sadb_lifetime_usetime.
00097          */
00098         long created;           /* time created the policy */
00099         long lastused;          /* updated every when kernel sends a packet */
00100         long lifetime;          /* duration of the lifetime of this policy */
00101         long validtime;         /* duration this policy is valid without use */
00102 };
00103
00104 /* Request for IPsec */
00105 struct ipsecrequest {
00106         struct ipsecrequest *next;
00107                                 /* pointer to next structure */
00108                                 /* If NULL, it means the end of chain. */
00109         struct secasindex saidx;/* hint for search proper SA */
00110                                 /* if __ss_len == 0 then no address specified.*/
00111         u_int level;            /* IPsec level defined below. */
00112
00113         struct secasvar *sav;   /* place holder of SA for use */
00114         struct secpolicy *sp;   /* back pointer to SP */
00115 };
00116
00117 /* security policy in PCB */
00118 struct inpcbpolicy {
00119         struct secpolicy *sp_in;
00120         struct secpolicy *sp_out;
00121         int priv;                       /* privileged socket ? */
00122 };
00123
00124 /* SP acquiring list table. */
00125 struct secspacq {
00126         LIST_ENTRY(secspacq) chain;
00127
00128         struct secpolicyindex spidx;
00129
00130         long created;           /* for lifetime */
00131         int count;              /* for lifetime */
00132         /* XXX: here is mbuf place holder to be sent ? */
00133 };
00134 #endif /* _KERNEL */
00135
00136 /* according to IANA assignment, port 0x0000 and proto 0xff are reserved. */
00137 #define IPSEC_PORT_ANY          0
00138 #define IPSEC_ULPROTO_ANY       255
00139 #define IPSEC_PROTO_ANY         255
00140
00141 /* mode of security protocol */
00142 /* NOTE: DON'T use IPSEC_MODE_ANY at SPD.  It's only use in SAD */
00143 #define IPSEC_MODE_ANY          0       /* i.e. wildcard. */
00144 #define IPSEC_MODE_TRANSPORT    1
00145 #define IPSEC_MODE_TUNNEL       2
00146
00147 /*
00148  * Direction of security policy.
00149  * NOTE: Since INVALID is used just as flag.
00150  * The other are used for loop counter too.
00151  */
00152 #define IPSEC_DIR_ANY           0
00153 #define IPSEC_DIR_INBOUND       1
00154 #define IPSEC_DIR_OUTBOUND      2
00155 #define IPSEC_DIR_MAX           3
00156 #define IPSEC_DIR_INVALID       4
00157
00158 /* Policy level */
00159 /*
00160  * IPSEC, ENTRUST and BYPASS are allowed for setsockopt() in PCB,
00161  * DISCARD, IPSEC and NONE are allowed for setkey() in SPD.
00162  * DISCARD and NONE are allowed for system default.
00163  */
00164 #define IPSEC_POLICY_DISCARD    0       /* discarding packet */
00165 #define IPSEC_POLICY_NONE       1       /* through IPsec engine */
00166 #define IPSEC_POLICY_IPSEC      2       /* do IPsec */
00167 #define IPSEC_POLICY_ENTRUST    3       /* consulting SPD if present. */
00168 #define IPSEC_POLICY_BYPASS     4       /* only for privileged socket. */
00169
00170 /* Security protocol level */
00171 #define IPSEC_LEVEL_DEFAULT     0       /* reference to system default */
00172 #define IPSEC_LEVEL_USE         1       /* use SA if present. */
00173 #define IPSEC_LEVEL_REQUIRE     2       /* require SA. */
00174 #define IPSEC_LEVEL_UNIQUE      3       /* unique SA. */
00175
00176 #define IPSEC_MANUAL_REQID_MAX  0x3fff
00177                                 /*
00178                                  * if security policy level == unique, this id
00179                                  * indicate to a relative SA for use, else is
00180                                  * zero.
00181                                  * 1 - 0x3fff are reserved for manual keying.
00182                                  * 0 are reserved for above reason.  Others is
00183                                  * for kernel use.
00184                                  * Note that this id doesn't identify SA
00185                                  * by only itself.
00186                                  */
00187 #define IPSEC_REPLAYWSIZE  32
00188
00189 /* statistics for ipsec processing */
00190 struct ipsecstat {
00191         u_quad_t in_success;  /* succeeded inbound process */
00192         u_quad_t in_polvio;
00193                         /* security policy violation for inbound process */
00194         u_quad_t in_nosa;     /* inbound SA is unavailable */
00195         u_quad_t in_inval;    /* inbound processing failed due to EINVAL */
00196         u_quad_t in_nomem;    /* inbound processing failed due to ENOBUFS */
00197         u_quad_t in_badspi;   /* failed getting a SPI */
00198         u_quad_t in_ahreplay; /* AH replay check failed */
00199         u_quad_t in_espreplay; /* ESP replay check failed */
00200         u_quad_t in_ahauthsucc; /* AH authentication success */
00201         u_quad_t in_ahauthfail; /* AH authentication failure */
00202         u_quad_t in_espauthsucc; /* ESP authentication success */
00203         u_quad_t in_espauthfail; /* ESP authentication failure */
00204         u_quad_t in_esphist[256];
00205         u_quad_t in_ahhist[256];
00206         u_quad_t in_comphist[256];
00207         u_quad_t out_success; /* succeeded outbound process */
00208         u_quad_t out_polvio;
00209                         /* security policy violation for outbound process */
00210         u_quad_t out_nosa;    /* outbound SA is unavailable */
00211         u_quad_t out_inval;   /* outbound process failed due to EINVAL */
00212         u_quad_t out_nomem;    /* inbound processing failed due to ENOBUFS */
00213         u_quad_t out_noroute; /* there is no route */
00214         u_quad_t out_esphist[256];
00215         u_quad_t out_ahhist[256];
00216         u_quad_t out_comphist[256];
00217 };
00218
00219 /*
00220  * Definitions for IPsec & Key sysctl operations.
00221  */
00222 /*
00223  * Names for IPsec & Key sysctl objects
00224  */
00225 #define IPSECCTL_STATS                  1       /* stats */
00226 #define IPSECCTL_DEF_POLICY             2
00227 #define IPSECCTL_DEF_ESP_TRANSLEV       3       /* int; ESP transport mode */
00228 #define IPSECCTL_DEF_ESP_NETLEV         4       /* int; ESP tunnel mode */
00229 #define IPSECCTL_DEF_AH_TRANSLEV        5       /* int; AH transport mode */
00230 #define IPSECCTL_DEF_AH_NETLEV          6       /* int; AH tunnel mode */
00231 #if 0   /* obsolete, do not reuse */
00232 #define IPSECCTL_INBOUND_CALL_IKE       7
00233 #endif
00234 #define IPSECCTL_AH_CLEARTOS            8
00235 #define IPSECCTL_AH_OFFSETMASK          9
00236 #define IPSECCTL_DFBIT                  10
00237 #define IPSECCTL_ECN                    11
00238 #define IPSECCTL_DEBUG                  12
00239 #define IPSECCTL_ESP_RANDPAD            13
00240 #define IPSECCTL_MAXID                  14
00241
00242 #define IPSECCTL_NAMES { \
00243         { 0, 0 }, \
00244         { 0, 0 }, \
00245         { "def_policy", CTLTYPE_INT }, \
00246         { "esp_trans_deflev", CTLTYPE_INT }, \
00247         { "esp_net_deflev", CTLTYPE_INT }, \
00248         { "ah_trans_deflev", CTLTYPE_INT }, \
00249         { "ah_net_deflev", CTLTYPE_INT }, \
00250         { 0, 0 }, \
00251         { "ah_cleartos", CTLTYPE_INT }, \
00252         { "ah_offsetmask", CTLTYPE_INT }, \
00253         { "dfbit", CTLTYPE_INT }, \
00254         { "ecn", CTLTYPE_INT }, \
00255         { "debug", CTLTYPE_INT }, \
00256         { "esp_randpad", CTLTYPE_INT }, \
00257 }
00258
00259 #define IPSEC6CTL_NAMES { \
00260         { 0, 0 }, \
00261         { 0, 0 }, \
00262         { "def_policy", CTLTYPE_INT }, \
00263         { "esp_trans_deflev", CTLTYPE_INT }, \
00264         { "esp_net_deflev", CTLTYPE_INT }, \
00265         { "ah_trans_deflev", CTLTYPE_INT }, \
00266         { "ah_net_deflev", CTLTYPE_INT }, \
00267         { 0, 0 }, \
00268         { 0, 0 }, \
00269         { 0, 0 }, \
00270         { 0, 0 }, \
00271         { "ecn", CTLTYPE_INT }, \
00272         { "debug", CTLTYPE_INT }, \
00273         { "esp_randpad", CTLTYPE_INT }, \
00274 }
00275
00276 #ifdef _KERNEL
00277 struct ipsec_output_state {
00278         struct mbuf *m;
00279         struct route *ro;
00280         struct sockaddr *dst;
00281 };
00282
00283 struct ipsec_history {
00284         int ih_proto;
00285         u_int32_t ih_spi;
00286 };
00287
00288 extern int ipsec_debug;
00289
00290 extern struct ipsecstat ipsecstat;
00291 extern struct secpolicy ip4_def_policy;
00292 extern int ip4_esp_trans_deflev;
00293 extern int ip4_esp_net_deflev;
00294 extern int ip4_ah_trans_deflev;
00295 extern int ip4_ah_net_deflev;
00296 extern int ip4_ah_cleartos;
00297 extern int ip4_ah_offsetmask;
00298 extern int ip4_ipsec_dfbit;
00299 extern int ip4_ipsec_ecn;
00300 extern int ip4_esp_randpad;
00301
00302 #define ipseclog(x)     do { if (ipsec_debug) log x; } while (0)
00303
00304 extern struct secpolicy *ipsec4_getpolicybysock
00305         __P((struct mbuf *, u_int, struct socket *, int *));
00306 extern struct secpolicy *ipsec4_getpolicybyaddr
00307         __P((struct mbuf *, u_int, int, int *));
00308
00309 struct inpcb;
00310 extern int ipsec_init_policy __P((struct socket *so, struct inpcbpolicy **));
00311 extern int ipsec_copy_policy
00312         __P((struct inpcbpolicy *, struct inpcbpolicy *));
00313 extern u_int ipsec_get_reqlevel __P((struct ipsecrequest *));
00314
00315 extern int ipsec4_set_policy __P((struct inpcb *inp, int optname,
00316         caddr_t request, size_t len, int priv));
00317 extern int ipsec4_get_policy __P((struct inpcb *inpcb, caddr_t request,
00318         size_t len, struct mbuf **mp));
00319 extern int ipsec4_delete_pcbpolicy __P((struct inpcb *));
00320 extern int ipsec4_in_reject_so __P((struct mbuf *, struct socket *));
00321 extern int ipsec4_in_reject __P((struct mbuf *, struct inpcb *));
00322
00323 struct secas;
00324 struct tcpcb;
00325 extern int ipsec_chkreplay __P((u_int32_t, struct secasvar *));
00326 extern int ipsec_updatereplay __P((u_int32_t, struct secasvar *));
00327
00328 extern size_t ipsec4_hdrsiz __P((struct mbuf *, u_int, struct inpcb *));
00329 extern size_t ipsec_hdrsiz_tcp __P((struct tcpcb *));
00330
00331 struct ip;
00332 extern const char *ipsec4_logpacketstr __P((struct ip *, u_int32_t));
00333 extern const char *ipsec_logsastr __P((struct secasvar *));
00334
00335 extern void ipsec_dumpmbuf __P((struct mbuf *));
00336
00337 extern int ipsec4_output __P((struct ipsec_output_state *, struct secpolicy *,
00338         int));
00339 extern int ipsec4_tunnel_validate __P((struct mbuf *, int, u_int,
00340         struct secasvar *));
00341 extern struct mbuf *ipsec_copypkt __P((struct mbuf *));
00342 extern void ipsec_delaux __P((struct mbuf *));
00343 extern int ipsec_setsocket __P((struct mbuf *, struct socket *));
00344 extern struct socket *ipsec_getsocket __P((struct mbuf *));
00345 extern int ipsec_addhist __P((struct mbuf *, int, u_int32_t));
00346 extern struct ipsec_history *ipsec_gethist __P((struct mbuf *, int *));
00347 extern void ipsec_clearhist __P((struct mbuf *));
00348 #endif /* _KERNEL */
00349
00350 #ifndef _KERNEL
00351 extern caddr_t ipsec_set_policy __P((char *, int));
00352 extern int ipsec_get_policylen __P((caddr_t));
00353 extern char *ipsec_dump_policy __P((caddr_t, char *));
00354
00355 extern const char *ipsec_strerror __P((void));
00356 #endif /* !_KERNEL */
00357
00358 #endif /* _NETINET6_IPSEC_H_ */
Generated on Wed Jan 25 15:42:33 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/netinet6/IPSEC6.H Source File

inc/netinet6/IPSEC6.H

Go to the documentation of this file.
00001
00005 /*      $FreeBSD: src/sys/netinet6/ipsec6.h,v 1.5 2001/06/11 12:39:06 ume Exp $ */
00006 /*      $KAME: ipsec.h,v 1.44 2001/03/23 08:08:47 itojun Exp $  */
00007
00008 /*
00009  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
00010  * All rights reserved.
00011  *
00012  * Redistribution and use in source and binary forms, with or without
00013  * modification, are permitted provided that the following conditions
00014  * are met:
00015  * 1. Redistributions of source code must retain the above copyright
00016  *    notice, this list of conditions and the following disclaimer.
00017  * 2. Redistributions in binary form must reproduce the above copyright
00018  *    notice, this list of conditions and the following disclaimer in the
00019  *    documentation and/or other materials provided with the distribution.
00020  * 3. Neither the name of the project nor the names of its contributors
00021  *    may be used to endorse or promote products derived from this software
00022  *    without specific prior written permission.
00023  *
00024  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
00025  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00026  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00027  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
00028  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00029  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00030  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00031  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00032  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00033  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00034  * SUCH DAMAGE.
00035  */
00036
00037 /*
00038  * IPsec controller part.
00039  */
00040
00041 #ifndef _NETINET6_IPSEC6_H_
00042 #define _NETINET6_IPSEC6_H_
00043
00044 #include <net/pfkeyv2.h>
00045 #include <netkey/keydb.h>
00046
00047 #ifdef _KERNEL
00048 extern struct ipsecstat ipsec6stat;
00049 extern struct secpolicy ip6_def_policy;
00050 extern int ip6_esp_trans_deflev;
00051 extern int ip6_esp_net_deflev;
00052 extern int ip6_ah_trans_deflev;
00053 extern int ip6_ah_net_deflev;
00054 extern int ip6_ipsec_ecn;
00055 extern int ip6_esp_randpad;
00056
00057 extern struct secpolicy *ipsec6_getpolicybysock
00058         __P((struct mbuf *, u_int, struct socket *, int *));
00059 extern struct secpolicy *ipsec6_getpolicybyaddr
00060         __P((struct mbuf *, u_int, int, int *));
00061
00062 struct inpcb;
00063
00064 extern int ipsec6_in_reject_so __P((struct mbuf *, struct socket *));
00065 extern int ipsec6_delete_pcbpolicy __P((struct inpcb *));
00066 extern int ipsec6_set_policy __P((struct inpcb *inp, int optname,
00067         caddr_t request, size_t len, int priv));
00068 extern int ipsec6_get_policy
00069         __P((struct inpcb *inp, caddr_t request, size_t len, struct mbuf **mp));
00070 extern int ipsec6_in_reject __P((struct mbuf *, struct inpcb *));
00071
00072 struct tcp6cb;
00073
00074 extern size_t ipsec6_hdrsiz __P((struct mbuf *, u_int, struct inpcb *));
00075
00076 struct ip6_hdr;
00077 extern const char *ipsec6_logpacketstr __P((struct ip6_hdr *, u_int32_t));
00078
00079 extern int ipsec6_output_trans __P((struct ipsec_output_state *, u_char *,
00080         struct mbuf *, struct secpolicy *, int, int *));
00081 extern int ipsec6_output_tunnel __P((struct ipsec_output_state *,
00082         struct secpolicy *, int));
00083 extern int ipsec6_tunnel_validate __P((struct mbuf *, int, u_int,
00084         struct secasvar *));
00085 #endif /*_KERNEL*/
00086
00087 #endif /*_NETINET6_IPSEC6_H_*/
Generated on Wed Jan 25 15:42:33 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/netinet6/MLD6_VAR.H Source File

inc/netinet6/MLD6_VAR.H

Go to the documentation of this file.
00001
00005 /*      $FreeBSD: src/sys/netinet6/mld6_var.h,v 1.2 2000/07/04 16:35:10 itojun Exp $    */
00006 /*      $KAME: mld6_var.h,v 1.4 2000/03/25 07:23:54 sumikawa Exp $      */
00007
00008 /*
00009  * Copyright (C) 1998 WIDE Project.
00010  * All rights reserved.
00011  *
00012  * Redistribution and use in source and binary forms, with or without
00013  * modification, are permitted provided that the following conditions
00014  * are met:
00015  * 1. Redistributions of source code must retain the above copyright
00016  *    notice, this list of conditions and the following disclaimer.
00017  * 2. Redistributions in binary form must reproduce the above copyright
00018  *    notice, this list of conditions and the following disclaimer in the
00019  *    documentation and/or other materials provided with the distribution.
00020  * 3. Neither the name of the project nor the names of its contributors
00021  *    may be used to endorse or promote products derived from this software
00022  *    without specific prior written permission.
00023  *
00024  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
00025  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00026  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00027  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
00028  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00029  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00030  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00031  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00032  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00033  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00034  * SUCH DAMAGE.
00035  */
00036
00037 #ifndef _NETINET6_MLD6_VAR_H_
00038 #define _NETINET6_MLD6_VAR_H_
00039
00040 #ifdef _KERNEL
00041
00042 #define MLD6_RANDOM_DELAY(X) (random() % (X) + 1)
00043
00044 /*
00045  * States for MLD stop-listening processing
00046  */
00047 #define MLD6_OTHERLISTENER                      0
00048 #define MLD6_IREPORTEDLAST                      1
00049
00050 void    mld6_init __P((void));
00051 void    mld6_input __P((struct mbuf *, int));
00052 void    mld6_start_listening __P((struct in6_multi *));
00053 void    mld6_stop_listening __P((struct in6_multi *));
00054 void    mld6_fasttimeo __P((void));
00055 #endif /* _KERNEL */
00056
00057 #endif /* _NETINET6_MLD6_VAR_H_ */
Generated on Wed Jan 25 15:42:33 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/netinet6/ND6.H Source File

inc/netinet6/ND6.H

Go to the documentation of this file.
00001
00005 /*      $FreeBSD: src/sys/netinet6/nd6.h,v 1.10 2002/04/19 04:46:23 suz Exp $   */
00006 /*      $KAME: nd6.h,v 1.76 2001/12/18 02:10:31 itojun Exp $    */
00007
00008 /*
00009  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
00010  * All rights reserved.
00011  *
00012  * Redistribution and use in source and binary forms, with or without
00013  * modification, are permitted provided that the following conditions
00014  * are met:
00015  * 1. Redistributions of source code must retain the above copyright
00016  *    notice, this list of conditions and the following disclaimer.
00017  * 2. Redistributions in binary form must reproduce the above copyright
00018  *    notice, this list of conditions and the following disclaimer in the
00019  *    documentation and/or other materials provided with the distribution.
00020  * 3. Neither the name of the project nor the names of its contributors
00021  *    may be used to endorse or promote products derived from this software
00022  *    without specific prior written permission.
00023  *
00024  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
00025  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00026  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00027  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
00028  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00029  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00030  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00031  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00032  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00033  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00034  * SUCH DAMAGE.
00035  */
00036
00037 #ifndef _NETINET6_ND6_H_
00038 #define _NETINET6_ND6_H_
00039
00040 /* see net/route.h, or net/if_inarp.h */
00041 #ifndef RTF_ANNOUNCE
00042 #define RTF_ANNOUNCE    RTF_PROTO2
00043 #endif
00044
00045 #include <sys/queue.h>
00046 #include <sys/callout.h>
00047
00048 struct  llinfo_nd6 {
00049         struct  llinfo_nd6 *ln_next;
00050         struct  llinfo_nd6 *ln_prev;
00051         struct  rtentry *ln_rt;
00052         struct  mbuf *ln_hold;  /* last packet until resolved/timeout */
00053         long    ln_asked;       /* number of queries already sent for this addr */
00054         u_long  ln_expire;      /* lifetime for NDP state transition */
00055         short   ln_state;       /* reachability state */
00056         short   ln_router;      /* 2^0: ND6 router bit */
00057         int     ln_byhint;      /* # of times we made it reachable by UL hint */
00058 };
00059
00060 #define ND6_LLINFO_NOSTATE      -2
00061 /*
00062  * We don't need the WAITDELETE state any more, but we keep the definition
00063  * in a comment line instead of removing it. This is necessary to avoid
00064  * unintentionally reusing the value for another purpose, which might
00065  * affect backward compatibility with old applications.
00066  * (20000711 jinmei@kame.net)
00067  */
00068 /* #define ND6_LLINFO_WAITDELETE        -1 */
00069 #define ND6_LLINFO_INCOMPLETE   0
00070 #define ND6_LLINFO_REACHABLE    1
00071 #define ND6_LLINFO_STALE        2
00072 #define ND6_LLINFO_DELAY        3
00073 #define ND6_LLINFO_PROBE        4
00074
00075 #define ND6_IS_LLINFO_PROBREACH(n) ((n)->ln_state > ND6_LLINFO_INCOMPLETE)
00076
00077 struct nd_ifinfo {
00078         u_int32_t linkmtu;              /* LinkMTU */
00079         u_int32_t maxmtu;               /* Upper bound of LinkMTU */
00080         u_int32_t basereachable;        /* BaseReachableTime */
00081         u_int32_t reachable;            /* Reachable Time */
00082         u_int32_t retrans;              /* Retrans Timer */
00083         u_int32_t flags;                /* Flags */
00084         int recalctm;                   /* BaseReacable re-calculation timer */
00085         u_int8_t chlim;                 /* CurHopLimit */
00086         u_int8_t receivedra;
00087         /* the following 3 members are for privacy extension for addrconf */
00088         u_int8_t randomseed0[8]; /* upper 64 bits of MD5 digest */
00089         u_int8_t randomseed1[8]; /* lower 64 bits (usually the EUI64 IFID) */
00090         u_int8_t randomid[8];   /* current random ID */
00091 };
00092
00093 #define ND6_IFF_PERFORMNUD      0x1
00094
00095 struct in6_nbrinfo {
00096         char ifname[IFNAMSIZ];  /* if name, e.g. "en0" */
00097         struct in6_addr addr;   /* IPv6 address of the neighbor */
00098         long    asked;          /* number of queries already sent for this addr */
00099         int     isrouter;       /* if it acts as a router */
00100         int     state;          /* reachability state */
00101         int     expire;         /* lifetime for NDP state transition */
00102 };
00103
00104 #define DRLSTSIZ 10
00105 #define PRLSTSIZ 10
00106 struct  in6_drlist {
00107         char ifname[IFNAMSIZ];
00108         struct {
00109                 struct  in6_addr rtaddr;
00110                 u_char  flags;
00111                 u_short rtlifetime;
00112                 u_long  expire;
00113                 u_short if_index;
00114         } defrouter[DRLSTSIZ];
00115 };
00116
00117 struct  in6_defrouter {
00118         struct  sockaddr_in6 rtaddr;
00119         u_char  flags;
00120         u_short rtlifetime;
00121         u_long  expire;
00122         u_short if_index;
00123 };
00124
00125 struct  in6_prlist {
00126         char ifname[IFNAMSIZ];
00127         struct {
00128                 struct  in6_addr prefix;
00129                 struct prf_ra raflags;
00130                 u_char  prefixlen;
00131                 u_char  origin;
00132                 u_int32_t vltime;
00133                 u_int32_t pltime;
00134                 time_t expire;
00135                 u_short if_index;
00136                 u_short advrtrs; /* number of advertisement routers */
00137                 struct  in6_addr advrtr[DRLSTSIZ]; /* XXX: explicit limit */
00138         } prefix[PRLSTSIZ];
00139 };
00140
00141 struct in6_prefix {
00142         struct  sockaddr_in6 prefix;
00143         struct prf_ra raflags;
00144         u_char  prefixlen;
00145         u_char  origin;
00146         u_long  vltime;
00147         u_long  pltime;
00148         u_long  expire;
00149         u_int32_t flags;
00150         int refcnt;
00151         u_short if_index;
00152         u_short advrtrs; /* number of advertisement routers */
00153         /* struct sockaddr_in6 advrtr[] */
00154 };
00155
00156 #ifdef _KERNEL
00157 struct  in6_ondireq {
00158         char ifname[IFNAMSIZ];
00159         struct {
00160                 u_int32_t linkmtu;      /* LinkMTU */
00161                 u_int32_t maxmtu;       /* Upper bound of LinkMTU */
00162                 u_int32_t basereachable; /* BaseReachableTime */
00163                 u_int32_t reachable;    /* Reachable Time */
00164                 u_int32_t retrans;      /* Retrans Timer */
00165                 u_int32_t flags;        /* Flags */
00166                 int recalctm;           /* BaseReacable re-calculation timer */
00167                 u_int8_t chlim;         /* CurHopLimit */
00168                 u_int8_t receivedra;
00169         } ndi;
00170 };
00171 #endif
00172
00173 struct  in6_ndireq {
00174         char ifname[IFNAMSIZ];
00175         struct nd_ifinfo ndi;
00176 };
00177
00178 struct  in6_ndifreq {
00179         char ifname[IFNAMSIZ];
00180         u_long ifindex;
00181 };
00182
00183 /* Prefix status */
00184 #define NDPRF_ONLINK            0x1
00185 #define NDPRF_DETACHED          0x2
00186
00187 /* protocol constants */
00188 #define MAX_RTR_SOLICITATION_DELAY      1       /* 1sec */
00189 #define RTR_SOLICITATION_INTERVAL       4       /* 4sec */
00190 #define MAX_RTR_SOLICITATIONS           3
00191
00192 #define ND6_INFINITE_LIFETIME           0xffffffff
00193
00194 #ifdef _KERNEL
00195 /* node constants */
00196 #define MAX_REACHABLE_TIME              3600000 /* msec */
00197 #define REACHABLE_TIME                  30000   /* msec */
00198 #define RETRANS_TIMER                   1000    /* msec */
00199 #define MIN_RANDOM_FACTOR               512     /* 1024 * 0.5 */
00200 #define MAX_RANDOM_FACTOR               1536    /* 1024 * 1.5 */
00201 #define DEF_TEMP_VALID_LIFETIME         604800  /* 1 week */
00202 #define DEF_TEMP_PREFERRED_LIFETIME     86400   /* 1 day */
00203 #define TEMPADDR_REGEN_ADVANCE          5       /* sec */
00204 #define MAX_TEMP_DESYNC_FACTOR          600     /* 10 min */
00205 #define ND_COMPUTE_RTIME(x) \
00206                 (((MIN_RANDOM_FACTOR * (x >> 10)) + (random() & \
00207                 ((MAX_RANDOM_FACTOR - MIN_RANDOM_FACTOR) * (x >> 10)))) /1000)
00208
00209 TAILQ_HEAD(nd_drhead, nd_defrouter);
00210 struct  nd_defrouter {
00211         TAILQ_ENTRY(nd_defrouter) dr_entry;
00212         struct  in6_addr rtaddr;
00213         u_char  flags;          /* flags on RA message */
00214         u_short rtlifetime;
00215         u_long  expire;
00216         u_long  advint;         /* Mobile IPv6 addition (milliseconds) */
00217         u_long  advint_expire;  /* Mobile IPv6 addition */
00218         int     advints_lost;   /* Mobile IPv6 addition */
00219         struct  ifnet *ifp;
00220 };
00221
00222 struct nd_prefix {
00223         struct ifnet *ndpr_ifp;
00224         LIST_ENTRY(nd_prefix) ndpr_entry;
00225         struct sockaddr_in6 ndpr_prefix;        /* prefix */
00226         struct in6_addr ndpr_mask; /* netmask derived from the prefix */
00227         struct in6_addr ndpr_addr; /* address that is derived from the prefix */
00228         u_int32_t ndpr_vltime;  /* advertised valid lifetime */
00229         u_int32_t ndpr_pltime;  /* advertised preferred lifetime */
00230         time_t ndpr_expire;     /* expiration time of the prefix */
00231         time_t ndpr_preferred;  /* preferred time of the prefix */
00232         struct prf_ra ndpr_flags;
00233         u_int32_t ndpr_stateflags; /* actual state flags */
00234         /* list of routers that advertise the prefix: */
00235         LIST_HEAD(pr_rtrhead, nd_pfxrouter) ndpr_advrtrs;
00236         u_char  ndpr_plen;
00237         int     ndpr_refcnt;    /* reference couter from addresses */
00238 };
00239
00240 #define ndpr_next               ndpr_entry.le_next
00241
00242 #define ndpr_raf                ndpr_flags
00243 #define ndpr_raf_onlink         ndpr_flags.onlink
00244 #define ndpr_raf_auto           ndpr_flags.autonomous
00245
00246 /*
00247  * We keep expired prefix for certain amount of time, for validation purposes.
00248  * 1800s = MaxRtrAdvInterval
00249  */
00250 #define NDPR_KEEP_EXPIRED       (1800 * 2)
00251
00252 /*
00253  * Message format for use in obtaining information about prefixes
00254  * from inet6 sysctl function
00255  */
00256 struct inet6_ndpr_msghdr {
00257         u_short inpm_msglen;    /* to skip over non-understood messages */
00258         u_char  inpm_version;   /* future binary compatibility */
00259         u_char  inpm_type;      /* message type */
00260         struct in6_addr inpm_prefix;
00261         u_long  prm_vltim;
00262         u_long  prm_pltime;
00263         u_long  prm_expire;
00264         u_long  prm_preferred;
00265         struct in6_prflags prm_flags;
00266         u_short prm_index;      /* index for associated ifp */
00267         u_char  prm_plen;       /* length of prefix in bits */
00268 };
00269
00270 #define prm_raf_onlink          prm_flags.prf_ra.onlink
00271 #define prm_raf_auto            prm_flags.prf_ra.autonomous
00272
00273 #define prm_statef_onlink       prm_flags.prf_state.onlink
00274
00275 #define prm_rrf_decrvalid       prm_flags.prf_rr.decrvalid
00276 #define prm_rrf_decrprefd       prm_flags.prf_rr.decrprefd
00277
00278 #define ifpr2ndpr(ifpr) ((struct nd_prefix *)(ifpr))
00279 #define ndpr2ifpr(ndpr) ((struct ifprefix *)(ndpr))
00280
00281 struct nd_pfxrouter {
00282         LIST_ENTRY(nd_pfxrouter) pfr_entry;
00283 #define pfr_next pfr_entry.le_next
00284         struct nd_defrouter *router;
00285 };
00286
00287 LIST_HEAD(nd_prhead, nd_prefix);
00288
00289 /* nd6.c */
00290 extern int nd6_prune;
00291 extern int nd6_delay;
00292 extern int nd6_umaxtries;
00293 extern int nd6_mmaxtries;
00294 extern int nd6_useloopback;
00295 extern int nd6_maxnudhint;
00296 extern int nd6_gctimer;
00297 extern struct llinfo_nd6 llinfo_nd6;
00298 extern struct nd_ifinfo *nd_ifinfo;
00299 extern struct nd_drhead nd_defrouter;
00300 extern struct nd_prhead nd_prefix;
00301 extern int nd6_debug;
00302
00303 #define nd6log(x)       do { if (nd6_debug) log x; } while (0)
00304
00305 extern struct callout nd6_timer_ch;
00306
00307 /* nd6_rtr.c */
00308 extern int nd6_defifindex;
00309 extern int ip6_desync_factor;   /* seconds */
00310 extern u_int32_t ip6_temp_preferred_lifetime; /* seconds */
00311 extern u_int32_t ip6_temp_valid_lifetime; /* seconds */
00312 extern int ip6_temp_regen_advance; /* seconds */
00313
00314 union nd_opts {
00315         struct nd_opt_hdr *nd_opt_array[9];     /* max = home agent info */
00316         struct {
00317                 struct nd_opt_hdr *zero;
00318                 struct nd_opt_hdr *src_lladdr;
00319                 struct nd_opt_hdr *tgt_lladdr;
00320                 struct nd_opt_prefix_info *pi_beg; /* multiple opts, start */
00321                 struct nd_opt_rd_hdr *rh;
00322                 struct nd_opt_mtu *mtu;
00323                 struct nd_opt_hdr *six;
00324                 struct nd_opt_advint *adv;
00325                 struct nd_opt_hai *hai;
00326                 struct nd_opt_hdr *search;      /* multiple opts */
00327                 struct nd_opt_hdr *last;        /* multiple opts */
00328                 int done;
00329                 struct nd_opt_prefix_info *pi_end;/* multiple opts, end */
00330         } nd_opt_each;
00331 };
00332 #define nd_opts_src_lladdr      nd_opt_each.src_lladdr
00333 #define nd_opts_tgt_lladdr      nd_opt_each.tgt_lladdr
00334 #define nd_opts_pi              nd_opt_each.pi_beg
00335 #define nd_opts_pi_end          nd_opt_each.pi_end
00336 #define nd_opts_rh              nd_opt_each.rh
00337 #define nd_opts_mtu             nd_opt_each.mtu
00338 #define nd_opts_adv             nd_opt_each.adv
00339 #define nd_opts_hai             nd_opt_each.hai
00340 #define nd_opts_search          nd_opt_each.search
00341 #define nd_opts_last            nd_opt_each.last
00342 #define nd_opts_done            nd_opt_each.done
00343
00344 /* XXX: need nd6_var.h?? */
00345 /* nd6.c */
00346 void nd6_init __P((void));
00347 void nd6_ifattach __P((struct ifnet *));
00348 int nd6_is_addr_neighbor __P((struct sockaddr_in6 *, struct ifnet *));
00349 void nd6_option_init __P((void *, int, union nd_opts *));
00350 struct nd_opt_hdr *nd6_option __P((union nd_opts *));
00351 int nd6_options __P((union nd_opts *));
00352 struct  rtentry *nd6_lookup __P((struct in6_addr *, int, struct ifnet *));
00353 void nd6_setmtu __P((struct ifnet *));
00354 void nd6_timer __P((void *));
00355 void nd6_purge __P((struct ifnet *));
00356 struct llinfo_nd6 *nd6_free __P((struct rtentry *));
00357 void nd6_nud_hint __P((struct rtentry *, struct in6_addr *, int));
00358 int nd6_resolve __P((struct ifnet *, struct rtentry *,
00359                      struct mbuf *, struct sockaddr *, u_char *));
00360 void nd6_rtrequest __P((int, struct rtentry *, struct rt_addrinfo *));
00361 int nd6_ioctl __P((u_long, caddr_t, struct ifnet *));
00362 struct rtentry *nd6_cache_lladdr __P((struct ifnet *, struct in6_addr *,
00363         char *, int, int, int));
00364 int nd6_output __P((struct ifnet *, struct ifnet *, struct mbuf *,
00365                     struct sockaddr_in6 *, struct rtentry *));
00366 int nd6_storelladdr __P((struct ifnet *, struct rtentry *, struct mbuf *,
00367                          struct sockaddr *, u_char *));
00368 int nd6_need_cache __P((struct ifnet *));
00369
00370 /* nd6_nbr.c */
00371 void nd6_na_input __P((struct mbuf *, int, int));
00372 void nd6_na_output __P((struct ifnet *, const struct in6_addr *,
00373         const struct in6_addr *, u_long, int, struct sockaddr *));
00374 void nd6_ns_input __P((struct mbuf *, int, int));
00375 void nd6_ns_output __P((struct ifnet *, const struct in6_addr *,
00376         const struct in6_addr *, struct llinfo_nd6 *, int));
00377 caddr_t nd6_ifptomac __P((struct ifnet *));
00378 void nd6_dad_start __P((struct ifaddr *, int *));
00379 void nd6_dad_stop __P((struct ifaddr *));
00380 void nd6_dad_duplicated __P((struct ifaddr *));
00381
00382 /* nd6_rtr.c */
00383 void nd6_rs_input __P((struct mbuf *, int, int));
00384 void nd6_ra_input __P((struct mbuf *, int, int));
00385 void prelist_del __P((struct nd_prefix *));
00386 void defrouter_addreq __P((struct nd_defrouter *));
00387 void defrouter_delreq __P((struct nd_defrouter *, int));
00388 void defrouter_select __P((void));
00389 void defrtrlist_del __P((struct nd_defrouter *));
00390 void prelist_remove __P((struct nd_prefix *));
00391 int prelist_update __P((struct nd_prefix *, struct nd_defrouter *,
00392                         struct mbuf *));
00393 int nd6_prelist_add __P((struct nd_prefix *, struct nd_defrouter *,
00394                          struct nd_prefix **));
00395 int nd6_prefix_onlink __P((struct nd_prefix *));
00396 int nd6_prefix_offlink __P((struct nd_prefix *));
00397 void pfxlist_onlink_check __P((void));
00398 struct nd_defrouter *defrouter_lookup __P((struct in6_addr *,
00399                                            struct ifnet *));
00400 struct nd_prefix *nd6_prefix_lookup __P((struct nd_prefix *));
00401 int in6_init_prefix_ltimes __P((struct nd_prefix *ndpr));
00402 void rt6_flush __P((struct in6_addr *, struct ifnet *));
00403 int nd6_setdefaultiface __P((int));
00404 int in6_tmpifadd __P((const struct in6_ifaddr *, int));
00405
00406 #endif /* _KERNEL */
00407
00408 #endif /* _NETINET6_ND6_H_ */
Generated on Wed Jan 25 15:42:33 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/netinet6/PIM6.H Source File

inc/netinet6/PIM6.H

Go to the documentation of this file.
00001
00005 /*      $FreeBSD: src/sys/netinet6/pim6.h,v 1.2 2000/07/04 16:35:10 itojun Exp $        */
00006 /*      $KAME: pim6.h,v 1.3 2000/03/25 07:23:58 sumikawa Exp $  */
00007
00008 /*
00009  * Copyright (C) 1998 WIDE Project.
00010  * All rights reserved.
00011  *
00012  * Redistribution and use in source and binary forms, with or without
00013  * modification, are permitted provided that the following conditions
00014  * are met:
00015  * 1. Redistributions of source code must retain the above copyright
00016  *    notice, this list of conditions and the following disclaimer.
00017  * 2. Redistributions in binary form must reproduce the above copyright
00018  *    notice, this list of conditions and the following disclaimer in the
00019  *    documentation and/or other materials provided with the distribution.
00020  * 3. Neither the name of the project nor the names of its contributors
00021  *    may be used to endorse or promote products derived from this software
00022  *    without specific prior written permission.
00023  *
00024  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
00025  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00026  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00027  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
00028  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00029  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00030  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00031  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00032  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00033  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00034  * SUCH DAMAGE.
00035  */
00036 /*
00037  * Protocol Independent Multicast (PIM) definitions
00038  *
00039  * Written by Ahmed Helmy, SGI, July 1996
00040  *
00041  * MULTICAST
00042  */
00043
00044 /*
00045  * PIM packet header
00046  */
00047 #define PIM_VERSION     2
00048 struct pim {
00049 #if defined(BYTE_ORDER) && (BYTE_ORDER == LITTLE_ENDIAN)
00050         u_char  pim_type:4, /* the PIM message type, currently they are:
00051                              * Hello, Register, Register-Stop, Join/Prune,
00052                              * Bootstrap, Assert, Graft (PIM-DM only),
00053                              * Graft-Ack (PIM-DM only), C-RP-Adv
00054                              */
00055                 pim_ver:4;  /* PIM version number; 2 for PIMv2 */
00056 #else
00057         u_char  pim_ver:4,      /* PIM version */
00058                 pim_type:4;     /* PIM type    */
00059 #endif
00060         u_char  pim_rsv;        /* Reserved */
00061         u_short pim_cksum;      /* IP style check sum */
00062 };
00063
00064 #define PIM_MINLEN      8               /* The header min. length is 8    */
00065 #define PIM6_REG_MINLEN (PIM_MINLEN+40) /* Register message + inner IP6 header */
00066
00067 /*
00068  * Message types
00069  */
00070 #define PIM_REGISTER    1       /* PIM Register type is 1 */
00071
00072 /* second bit in reg_head is the null bit */
00073 #define PIM_NULL_REGISTER 0x40000000
Generated on Wed Jan 25 15:42:33 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/netinet6/PIM6_VAR.H Source File

inc/netinet6/PIM6_VAR.H

Go to the documentation of this file.
00001
00005 /*      $FreeBSD: src/sys/netinet6/pim6_var.h,v 1.3 2000/07/04 16:35:10 itojun Exp $    */
00006 /*      $KAME: pim6_var.h,v 1.8 2000/06/06 08:07:43 jinmei Exp $        */
00007
00008 /*
00009  * Copyright (C) 1998 WIDE Project.
00010  * All rights reserved.
00011  *
00012  * Redistribution and use in source and binary forms, with or without
00013  * modification, are permitted provided that the following conditions
00014  * are met:
00015  * 1. Redistributions of source code must retain the above copyright
00016  *    notice, this list of conditions and the following disclaimer.
00017  * 2. Redistributions in binary form must reproduce the above copyright
00018  *    notice, this list of conditions and the following disclaimer in the
00019  *    documentation and/or other materials provided with the distribution.
00020  * 3. Neither the name of the project nor the names of its contributors
00021  *    may be used to endorse or promote products derived from this software
00022  *    without specific prior written permission.
00023  *
00024  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
00025  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00026  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00027  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
00028  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00029  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00030  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00031  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00032  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00033  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00034  * SUCH DAMAGE.
00035  */
00036
00037 #ifndef _NETINET6_PIM6_VAR_H_
00038 #define _NETINET6_PIM6_VAR_H_
00039
00040 /*
00041  * Protocol Independent Multicast (PIM),
00042  * implementation-specific definitions.
00043  *
00044  * Written by George Edmond Eddy (Rusty), ISI, February 1998
00045  * Modified by Pavlin Ivanov Radoslavov, USC/ISI, May 1998
00046  */
00047
00048 struct pim6stat {
00049         u_quad_t pim6s_rcv_total;       /* total PIM messages received  */
00050         u_quad_t pim6s_rcv_tooshort;    /* received with too few bytes  */
00051         u_quad_t pim6s_rcv_badsum;      /* received with bad checksum   */
00052         u_quad_t pim6s_rcv_badversion;  /* received bad PIM version     */
00053         u_quad_t pim6s_rcv_registers;   /* received registers           */
00054         u_quad_t pim6s_rcv_badregisters; /* received invalid registers  */
00055         u_quad_t pim6s_snd_registers;   /* sent registers               */
00056 };
00057
00058 #if (defined(KERNEL)) || (defined(_KERNEL))
00059 extern struct pim6stat pim6stat;
00060
00061 int pim6_input __P((struct mbuf **, int*, int));
00062 #endif /* KERNEL */
00063
00064 /*
00065  * Names for PIM sysctl objects
00066  */
00067 #define PIM6CTL_STATS           1       /* statistics (read-only) */
00068 #define PIM6CTL_MAXID           2
00069
00070 #define PIM6CTL_NAMES { \
00071         { 0, 0 }, \
00072         { 0, 0 }, \
00073 }
00074 #endif /* _NETINET6_PIM6_VAR_H_ */
Generated on Wed Jan 25 15:42:33 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/netinet6/RAW_IP6.H Source File

inc/netinet6/RAW_IP6.H

Go to the documentation of this file.
00001
00005 /*      $FreeBSD: src/sys/netinet6/raw_ip6.h,v 1.1 2001/06/11 12:39:06 ume Exp $        */
00006 /*      $KAME: raw_ip6.h,v 1.2 2001/05/27 13:28:35 itojun Exp $ */
00007
00008 /*
00009  * Copyright (C) 2001 WIDE Project.
00010  * All rights reserved.
00011  *
00012  * Redistribution and use in source and binary forms, with or without
00013  * modification, are permitted provided that the following conditions
00014  * are met:
00015  * 1. Redistributions of source code must retain the above copyright
00016  *    notice, this list of conditions and the following disclaimer.
00017  * 2. Redistributions in binary form must reproduce the above copyright
00018  *    notice, this list of conditions and the following disclaimer in the
00019  *    documentation and/or other materials provided with the distribution.
00020  * 3. Neither the name of the project nor the names of its contributors
00021  *    may be used to endorse or promote products derived from this software
00022  *    without specific prior written permission.
00023  *
00024  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
00025  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00026  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00027  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
00028  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00029  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00030  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00031  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00032  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00033  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00034  * SUCH DAMAGE.
00035  */
00036
00037 #ifndef _NETINET6_RAW_IP6_H_
00038 #define _NETINET6_RAW_IP6_H_
00039
00040 /*
00041  * ICMPv6 stat is counted separately.  see netinet/icmp6.h
00042  */
00043 struct rip6stat {
00044         u_quad_t rip6s_ipackets;        /* total input packets */
00045         u_quad_t rip6s_isum;            /* input checksum computations */
00046         u_quad_t rip6s_badsum;          /* of above, checksum error */
00047         u_quad_t rip6s_nosock;          /* no matching socket */
00048         u_quad_t rip6s_nosockmcast;     /* of above, arrived as multicast */
00049         u_quad_t rip6s_fullsock;        /* not delivered, input socket full */
00050
00051         u_quad_t rip6s_opackets;        /* total output packets */
00052 };
00053
00054 #ifdef _KERNEL
00055 extern struct rip6stat rip6stat;
00056 #endif
00057
00058 #endif
Generated on Wed Jan 25 15:42:33 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/netinet6/SCOPE6_V.H Source File

inc/netinet6/SCOPE6_V.H

Go to the documentation of this file.
00001
00005 /*      $FreeBSD: src/sys/netinet6/scope6_var.h,v 1.1 2000/07/04 16:35:10 itojun Exp $  */
00006 /*      $KAME: scope6_var.h,v 1.4 2000/05/18 15:03:27 jinmei Exp $      */
00007
00008 /*
00009  * Copyright (C) 2000 WIDE Project.
00010  * All rights reserved.
00011  *
00012  * Redistribution and use in source and binary forms, with or without
00013  * modification, are permitted provided that the following conditions
00014  * are met:
00015  * 1. Redistributions of source code must retain the above copyright
00016  *    notice, this list of conditions and the following disclaimer.
00017  * 2. Redistributions in binary form must reproduce the above copyright
00018  *    notice, this list of conditions and the following disclaimer in the
00019  *    documentation and/or other materials provided with the distribution.
00020  * 3. Neither the name of the project nor the names of its contributors
00021  *    may be used to endorse or promote products derived from this software
00022  *    without specific prior written permission.
00023  *
00024  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
00025  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00026  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00027  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
00028  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00029  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00030  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00031  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00032  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00033  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00034  * SUCH DAMAGE.
00035  */
00036
00037 #ifndef _NETINET6_SCOPE6_VAR_H_
00038 #define _NETINET6_SCOPE6_VAR_H_
00039
00040 #ifdef _KERNEL
00041 void    scope6_ifattach __P((struct ifnet *));
00042 int     scope6_set __P((struct ifnet *, u_int32_t *));
00043 int     scope6_get __P((struct ifnet *, u_int32_t *));
00044 void    scope6_setdefault __P((struct ifnet *));
00045 int     scope6_get_default __P((u_int32_t *));
00046 u_int32_t scope6_in6_addrscope __P((struct in6_addr *));
00047 u_int32_t scope6_addr2default __P((struct in6_addr *));
00048 #endif /* _KERNEL */
00049
00050 #endif /* _NETINET6_SCOPE6_VAR_H_ */
Generated on Wed Jan 25 15:42:33 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/netinet6/TCP6_VAR.H Source File

inc/netinet6/TCP6_VAR.H

Go to the documentation of this file.
00001
00004 /*
00005  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
00006  * All rights reserved.
00007  *
00008  * Redistribution and use in source and binary forms, with or without
00009  * modification, are permitted provided that the following conditions
00010  * are met:
00011  * 1. Redistributions of source code must retain the above copyright
00012  *    notice, this list of conditions and the following disclaimer.
00013  * 2. Redistributions in binary form must reproduce the above copyright
00014  *    notice, this list of conditions and the following disclaimer in the
00015  *    documentation and/or other materials provided with the distribution.
00016  * 3. Neither the name of the project nor the names of its contributors
00017  *    may be used to endorse or promote products derived from this software
00018  *    without specific prior written permission.
00019  *
00020  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
00021  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00022  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00023  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
00024  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00025  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00026  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00027  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00028  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00029  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00030  * SUCH DAMAGE.
00031  *
00032  * $FreeBSD: src/sys/netinet6/tcp6_var.h,v 1.5 2001/11/22 04:50:44 jlemon Exp $
00033  */
00034
00035 /*
00036  * Copyright (c) 1982, 1986, 1993, 1994, 1995
00037  *      The Regents of the University of California.  All rights reserved.
00038  *
00039  * Redistribution and use in source and binary forms, with or without
00040  * modification, are permitted provided that the following conditions
00041  * are met:
00042  * 1. Redistributions of source code must retain the above copyright
00043  *    notice, this list of conditions and the following disclaimer.
00044  * 2. Redistributions in binary form must reproduce the above copyright
00045  *    notice, this list of conditions and the following disclaimer in the
00046  *    documentation and/or other materials provided with the distribution.
00047  * 3. All advertising materials mentioning features or use of this software
00048  *    must display the following acknowledgement:
00049  *      This product includes software developed by the University of
00050  *      California, Berkeley and its contributors.
00051  * 4. Neither the name of the University nor the names of its contributors
00052  *    may be used to endorse or promote products derived from this software
00053  *    without specific prior written permission.
00054  *
00055  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
00056  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00057  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00058  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
00059  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00060  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00061  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00062  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00063  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00064  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00065  * SUCH DAMAGE.
00066  *
00067  *      @(#)tcp_var.h   8.4 (Berkeley) 5/24/95
00068  * $FreeBSD: src/sys/netinet6/tcp6_var.h,v 1.5 2001/11/22 04:50:44 jlemon Exp $
00069  */
00070
00071 #ifndef _NETINET_TCP6_VAR_H_
00072 #define _NETINET_TCP6_VAR_H_
00073
00074 #ifdef _KERNEL
00075 #ifdef SYSCTL_DECL
00076 SYSCTL_DECL(_net_inet6_tcp6);
00077 #endif
00078
00079 extern  int tcp_v6mssdflt;      /* XXX */
00080
00081 struct  ip6_hdr;
00082 void    tcp6_ctlinput __P((int, struct sockaddr *, void *));
00083 void    tcp6_init __P((void));
00084 int     tcp6_input __P((struct mbuf **, int *, int));
00085 struct  rtentry *tcp_rtlookup6(struct in_conninfo *);
00086
00087 extern struct   pr_usrreqs tcp6_usrreqs;
00088
00089 #endif /* _KERNEL */
00090
00091 #endif /* _NETINET_TCP6_VAR_H_ */
Generated on Wed Jan 25 15:42:33 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/netinet6/UDP6_VAR.H Source File

inc/netinet6/UDP6_VAR.H

Go to the documentation of this file.
00001
00005 /*
00006  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
00007  * All rights reserved.
00008  *
00009  * Redistribution and use in source and binary forms, with or without
00010  * modification, are permitted provided that the following conditions
00011  * are met:
00012  * 1. Redistributions of source code must retain the above copyright
00013  *    notice, this list of conditions and the following disclaimer.
00014  * 2. Redistributions in binary form must reproduce the above copyright
00015  *    notice, this list of conditions and the following disclaimer in the
00016  *    documentation and/or other materials provided with the distribution.
00017  * 3. Neither the name of the project nor the names of its contributors
00018  *    may be used to endorse or promote products derived from this software
00019  *    without specific prior written permission.
00020  *
00021  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
00022  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00023  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00024  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
00025  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00026  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00027  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00028  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00029  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00030  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00031  * SUCH DAMAGE.
00032  *
00033  * $FreeBSD: src/sys/netinet6/udp6_var.h,v 1.5 2001/09/12 08:37:55 julian Exp $
00034  */
00035
00036 /*
00037  * Copyright (c) 1982, 1986, 1989, 1993
00038  *      The Regents of the University of California.  All rights reserved.
00039  *
00040  * Redistribution and use in source and binary forms, with or without
00041  * modification, are permitted provided that the following conditions
00042  * are met:
00043  * 1. Redistributions of source code must retain the above copyright
00044  *    notice, this list of conditions and the following disclaimer.
00045  * 2. Redistributions in binary form must reproduce the above copyright
00046  *    notice, this list of conditions and the following disclaimer in the
00047  *    documentation and/or other materials provided with the distribution.
00048  * 3. All advertising materials mentioning features or use of this software
00049  *    must display the following acknowledgement:
00050  *      This product includes software developed by the University of
00051  *      California, Berkeley and its contributors.
00052  * 4. Neither the name of the University nor the names of its contributors
00053  *    may be used to endorse or promote products derived from this software
00054  *    without specific prior written permission.
00055  *
00056  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
00057  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00058  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00059  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
00060  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00061  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00062  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00063  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00064  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00065  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00066  * SUCH DAMAGE.
00067  *
00068  *      @(#)udp_var.h   8.1 (Berkeley) 6/10/93
00069  */
00070
00071 #ifndef _NETINET6_UDP6_VAR_H_
00072 #define _NETINET6_UDP6_VAR_H_
00073
00074 #ifdef _KERNEL
00075 SYSCTL_DECL(_net_inet6_udp6);
00076
00077 extern struct   pr_usrreqs udp6_usrreqs;
00078
00079 void    udp6_ctlinput __P((int, struct sockaddr *, void *));
00080 int     udp6_input __P((struct mbuf **, int *, int));
00081 int     udp6_output __P((struct inpcb *inp, struct mbuf *m,
00082                         struct sockaddr *addr, struct mbuf *control,
00083                         struct thread *td));
00084 #endif
00085
00086 #endif /*_NETINET6_UDP6_VAR_H_*/
Generated on Wed Jan 25 15:42:33 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/protocol/DUMPREST.H Source File

inc/protocol/DUMPREST.H

Go to the documentation of this file.
00001
00005 /*      $NetBSD: dumprestore.h,v 1.7 1996/11/30 18:01:52 cgd Exp $      */
00006
00007 /*
00008  * Copyright (c) 1980, 1993
00009  *      The Regents of the University of California.  All rights reserved.
00010  * (c) UNIX System Laboratories, Inc.
00011  * All or some portions of this file are derived from material licensed
00012  * to the University of California by American Telephone and Telegraph
00013  * Co. or Unix System Laboratories, Inc. and are reproduced herein with
00014  * the permission of UNIX System Laboratories, Inc.
00015  *
00016  * Redistribution and use in source and binary forms, with or without
00017  * modification, are permitted provided that the following conditions
00018  * are met:
00019  * 1. Redistributions of source code must retain the above copyright
00020  *    notice, this list of conditions and the following disclaimer.
00021  * 2. Redistributions in binary form must reproduce the above copyright
00022  *    notice, this list of conditions and the following disclaimer in the
00023  *    documentation and/or other materials provided with the distribution.
00024  * 3. All advertising materials mentioning features or use of this software
00025  *    must display the following acknowledgement:
00026  *      This product includes software developed by the University of
00027  *      California, Berkeley and its contributors.
00028  * 4. Neither the name of the University nor the names of its contributors
00029  *    may be used to endorse or promote products derived from this software
00030  *    without specific prior written permission.
00031  *
00032  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
00033  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00034  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00035  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
00036  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00037  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00038  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00039  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00040  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00041  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00042  * SUCH DAMAGE.
00043  *
00044  *      @(#)dumprestore.h       8.2 (Berkeley) 1/21/94
00045  */
00046
00047 #ifndef __PROTOCOL_DUMPRESTORE_H
00048 #define __PROTOCOL_DUMPRESTORE_H
00049
00050 /*
00051  * TP_BSIZE is the size of file blocks on the dump tapes.
00052  * Note that TP_BSIZE must be a multiple of DEV_BSIZE.
00053  *
00054  * NTREC is the number of TP_BSIZE blocks that are written
00055  * in each tape record. HIGHDENSITYTREC is the number of
00056  * TP_BSIZE blocks that are written in each tape record on
00057  * 6250 BPI or higher density tapes.
00058  *
00059  * TP_NINDIR is the number of indirect pointers in a TS_INODE
00060  * or TS_ADDR record. Note that it must be a power of two.
00061  */
00062 #define TP_BSIZE        1024
00063 #define NTREC           10
00064 #define HIGHDENSITYTREC 32
00065 #define TP_NINDIR       (TP_BSIZE/2)
00066 #define LBLSIZE         16
00067 #define NAMELEN         64
00068
00069 #define OFS_MAGIC       (int)60011
00070 #define NFS_MAGIC       (int)60012
00071 #define CHECKSUM        (int)84446
00072
00073 #include <sys/packon.h>
00074
00075 union u_spcl {
00076         char dummy[TP_BSIZE];
00077         struct  s_spcl {
00078                 int32_t c_type;             /* record type (see below) */
00079                 time_t  c_date;             /* date of this dump */
00080                 time_t  c_ddate;            /* date of previous dump */
00081                 int32_t c_volume;           /* dump volume number */
00082                 daddr_t c_tapea;            /* logical block of this record */
00083                 ino_t   c_inumber;          /* number of inode */
00084                 int32_t c_magic;            /* magic number (see above) */
00085                 int32_t c_checksum;         /* record checksum */
00086                 struct  dinode  c_dinode;   /* ownership and mode of inode */
00087                 int32_t c_count;            /* number of valid c_addr entries */
00088                 char    c_addr[TP_NINDIR];  /* 1 => data; 0 => hole in inode */
00089                 char    c_label[LBLSIZE];   /* dump label */
00090                 int32_t c_level;            /* level of this dump */
00091                 char    c_filesys[NAMELEN]; /* name of dumpped file system */
00092                 char    c_dev[NAMELEN];     /* name of dumpped device */
00093                 char    c_host[NAMELEN];    /* name of dumpped host */
00094                 int32_t c_flags;            /* additional information */
00095                 int32_t c_firstrec;         /* first record on volume */
00096                 int32_t c_spare[32];        /* reserved for future uses */
00097         } s_spcl;
00098 } u_spcl;
00099
00100 #include <sys/packoff.h>
00101
00102 #define spcl u_spcl.s_spcl
00103 /*
00104  * special record types
00105  */
00106 #define TS_TAPE         1       /* dump tape header */
00107 #define TS_INODE        2       /* beginning of file record */
00108 #define TS_ADDR         4       /* continuation of file record */
00109 #define TS_BITS         3       /* map of inodes on tape */
00110 #define TS_CLRI         6       /* map of inodes deleted since last dump */
00111 #define TS_END          5       /* end of volume marker */
00112
00113 /*
00114  * flag values
00115  */
00116 #define DR_NEWHEADER    0x0001  /* new format tape header */
00117 #define DR_NEWINODEFMT  0x0002  /* new format inodes on tape */
00118
00119 #define DUMPOUTFMT      "%-16s %c %s"           /* for printf */
00120                                                 /* name, level, ctime(date) */
00121 #define DUMPINFMT       "%16s %c %[^\n]\n"      /* inverse for scanf */
00122
00123 #endif
Generated on Wed Jan 25 15:42:33 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/protocol/ROUTED.H Source File

inc/protocol/ROUTED.H

Go to the documentation of this file.
00001
00005 /*      $NetBSD: routed.h,v 1.10 1997/02/03 22:20:38 christos Exp $     */
00006
00007 /*-
00008  * Copyright (c) 1983, 1989, 1993
00009  *      The Regents of the University of California.  All rights reserved.
00010  *
00011  * Redistribution and use in source and binary forms, with or without
00012  * modification, are permitted provided that the following conditions
00013  * are met:
00014  * 1. Redistributions of source code must retain the above copyright
00015  *    notice, this list of conditions and the following disclaimer.
00016  * 2. Redistributions in binary form must reproduce the above copyright
00017  *    notice, this list of conditions and the following disclaimer in the
00018  *    documentation and/or other materials provided with the distribution.
00019  * 3. All advertising materials mentioning features or use of this software
00020  *    must display the following acknowledgement:
00021  *      This product includes software developed by the University of
00022  *      California, Berkeley and its contributors.
00023  * 4. Neither the name of the University nor the names of its contributors
00024  *    may be used to endorse or promote products derived from this software
00025  *    without specific prior written permission.
00026  *
00027  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
00028  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00029  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00030  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
00031  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00032  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00033  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00034  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00035  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00036  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00037  * SUCH DAMAGE.
00038  *
00039  *      @(#)routed.h    8.1 (Berkeley) 6/2/93
00040  */
00041
00042 #ifndef __PROTOCOL_ROUTED_H
00043 #define __PROTOCOL_ROUTED_H
00044
00045 /*
00046  * Routing Information Protocol
00047  *
00048  * Derived from Xerox NS Routing Information Protocol
00049  * by changing 32-bit net numbers to sockaddr's and
00050  * padding stuff to 32-bit boundaries.
00051  */
00052
00053 #define RIP_VERSION_0   0
00054 #define RIP_VERSION_1   1
00055 #define RIP_VERSION_2   2
00056
00057 #define RIPv1           RIP_VERSION_1
00058 #define RIPv2           RIP_VERSION_2
00059 #ifndef RIPVERSION
00060 #define RIPVERSION      RIPv1
00061 #endif
00062
00063 #define RIP_PORT        520
00064
00065 #include <sys/packon.h>
00066
00067 #if RIPVERSION == 1
00068 /* We include the V2 fields to get the right size */
00069 struct netinfo {
00070         u_int16_t   rip_family;
00071         u_int16_t   rip_tag;
00072         u_int32_t   rip_dst;            /* destination net/host */
00073         u_int32_t   rip_dst_mask;       /* destination mask (V2 only) */
00074         u_int32_t   rip_router;         /* next host (V2 only) */
00075         u_int32_t   rip_metric;         /* cost of route */
00076 };
00077 #else
00078 struct netinfo {
00079         u_int16_t   n_family;
00080 #define     RIP_AF_INET     htons(AF_INET)
00081 #define     RIP_AF_UNSPEC   0
00082 #define     RIP_AF_AUTH     0xffff
00083         u_int16_t   n_tag;              /* optional in RIPv2 */
00084         u_int32_t   n_dst;              /* destination net or host */
00085 #define     RIP_DEFAULT     0
00086         u_int32_t   n_mask;             /* netmask in RIPv2 */
00087         u_int32_t   n_nhop;             /* optional next hop in RIPv2 */
00088         u_int32_t   n_metric;           /* cost of route */
00089 };
00090 #endif
00091
00092 /* RIPv2 authentication */
00093 struct netauth {
00094         u_int16_t   a_family;           /* always RIP_AF_AUTH */
00095         u_int16_t   a_type;
00096 #define     RIP_AUTH_NONE   0
00097 #define     RIP_AUTH_PW     htons(2)    /* password type */
00098 #define     RIP_AUTH_MD5    htons(3)    /* Keyed MD5 */
00099         union {
00100 #define     RIP_AUTH_PW_LEN 16
00101             u_int8_t    au_pw[RIP_AUTH_PW_LEN];
00102             struct a_md5 {
00103                 int16_t md5_pkt_len;    /* RIP-II packet length */
00104                 int8_t  md5_keyid;      /* key ID and auth data len */
00105                 int8_t  md5_auth_len;   /* 16 */
00106                 u_int32_t md5_seqno;    /* sequence number */
00107                 u_int32_t rsvd[2];      /* must be 0 */
00108 #define     RIP_AUTH_MD5_LEN RIP_AUTH_PW_LEN
00109             } a_md5;
00110         } au;
00111 };
00112
00113 struct rip {
00114         u_int8_t    rip_cmd;            /* request/response */
00115         u_int8_t    rip_vers;           /* protocol version # */
00116         u_int16_t   rip_res1;           /* pad to 32-bit boundary */
00117         union {                         /* variable length... */
00118             struct netinfo ru_nets[1];
00119             int8_t    ru_tracefile[1];
00120             struct netauth ru_auth[1];
00121         } ripun;
00122 #define rip_nets        ripun.ru_nets
00123 #define rip_auths       ripun.ru_auth
00124 #define rip_tracefile   ripun.ru_tracefile
00125 };
00126
00127 #include <sys/packoff.h>
00128
00129 /* Packet types.
00130  */
00131 #define RIPCMD_REQUEST          1       /* want info */
00132 #define RIPCMD_RESPONSE         2       /* responding to request */
00133 #define RIPCMD_TRACEON          3       /* turn tracing on */
00134 #define RIPCMD_TRACEOFF         4       /* turn it off */
00135
00136 /* Gated extended RIP to include a "poll" command instead of using
00137  * RIPCMD_REQUEST with (RIP_AF_UNSPEC, RIP_DEFAULT).  RFC 1058 says
00138  * command 5 is used by Sun Microsystems for its own purposes.
00139  */
00140 #define RIPCMD_POLL             5
00141
00142 #define RIPCMD_MAX              6
00143
00144 #ifdef RIPCMDS
00145 char *ripcmds[RIPCMD_MAX] = {
00146         "#0", "REQUEST", "RESPONSE", "TRACEON", "TRACEOFF"
00147 };
00148 #endif
00149
00150 #define HOPCNT_INFINITY  16
00151 #define MAXPACKETSIZE    512     /* max broadcast size */
00152 #define NETS_LEN         ((MAXPACKETSIZE-sizeof(struct rip))    \
00153                           / sizeof(struct netinfo) +1)
00154
00155 #define INADDR_RIP_GROUP (u_int32_t)0xe0000009  /* 224.0.0.9 */
00156
00157
00158 /* Timer values used in managing the routing table.
00159  *
00160  * Complete tables are broadcast every SUPPLY_INTERVAL seconds.
00161  * If changes occur between updates, dynamic updates containing only changes
00162  * may be sent.  When these are sent, a timer is set for a random value
00163  * between MIN_WAITTIME and MAX_WAITTIME, and no additional dynamic updates
00164  * are sent until the timer expires.
00165  *
00166  * Every update of a routing entry forces an entry's timer to be reset.
00167  * After EXPIRE_TIME without updates, the entry is marked invalid,
00168  * but held onto until GARBAGE_TIME so that others may see it, to
00169  * "poison" the bad route.
00170  */
00171 #define SUPPLY_INTERVAL         30      /* time to supply tables */
00172 #define MIN_WAITTIME            2       /* min sec until next flash updates */
00173 #define MAX_WAITTIME            5       /* max sec until flash update */
00174
00175 #define STALE_TIME              90      /* switch to a new gateway */
00176 #define EXPIRE_TIME             180     /* time to mark entry invalid */
00177 #define GARBAGE_TIME            240     /* time to garbage collect */
00178
00179 #endif
Generated on Wed Jan 25 15:42:33 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/protocol/RWHOD.H Source File

inc/protocol/RWHOD.H

Go to the documentation of this file.
00001
00005 /*      $NetBSD: rwhod.h,v 1.4 1996/09/23 05:01:08 mycroft Exp $        */
00006
00007 /*
00008  * Copyright (c) 1983 The Regents of the University of California.
00009  * All rights reserved.
00010  *
00011  * Redistribution and use in source and binary forms, with or without
00012  * modification, are permitted provided that the following conditions
00013  * are met:
00014  * 1. Redistributions of source code must retain the above copyright
00015  *    notice, this list of conditions and the following disclaimer.
00016  * 2. Redistributions in binary form must reproduce the above copyright
00017  *    notice, this list of conditions and the following disclaimer in the
00018  *    documentation and/or other materials provided with the distribution.
00019  * 3. All advertising materials mentioning features or use of this software
00020  *    must display the following acknowledgement:
00021  *      This product includes software developed by the University of
00022  *      California, Berkeley and its contributors.
00023  * 4. Neither the name of the University nor the names of its contributors
00024  *    may be used to endorse or promote products derived from this software
00025  *    without specific prior written permission.
00026  *
00027  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
00028  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00029  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00030  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
00031  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00032  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00033  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00034  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00035  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00036  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00037  * SUCH DAMAGE.
00038  *
00039  *      @(#)rwhod.h     5.6 (Berkeley) 4/3/91
00040  */
00041
00042 #ifndef __PROTOCOL_RWHOD_H
00043 #define __PROTOCOL_RWHOD_H
00044
00045 #include <sys/packon.h>
00046
00047 /*
00048  * rwho protocol packet format.
00049  */
00050 struct  outmp {
00051         char    out_line[8];            /* tty name */
00052         char    out_name[8];            /* user id */
00053         int32_t out_time;               /* time on */
00054 };
00055
00056 struct  whod {
00057         char    wd_vers;                /* protocol version # */
00058         char    wd_type;                /* packet type, see below */
00059         char    wd_pad[2];
00060         int32_t wd_sendtime;            /* time stamp by sender */
00061         int32_t wd_recvtime;            /* time stamp applied by receiver */
00062         char    wd_hostname[32];        /* hosts's name */
00063         int32_t wd_loadav[3];           /* load average as in uptime */
00064         int32_t wd_boottime;            /* time system booted */
00065         struct  whoent {
00066                 struct  outmp we_utmp;  /* active tty info */
00067                 int32_t we_idle;        /* tty idle time */
00068         } wd_we[1024 / sizeof (struct whoent)];
00069 };
00070
00071 #include <sys/packoff.h>
00072
00073 #define WHODVERSION     1
00074 #define WHODTYPE_STATUS 1               /* host status */
00075
00076 #define _PATH_RWHODIR   "/var/rwho"
00077
00078 #endif
Generated on Wed Jan 25 15:42:33 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/protocol/TALKD.H Source File

inc/protocol/TALKD.H

Go to the documentation of this file.
00001
00005 /*      $NetBSD: talkd.h,v 1.5 1995/03/04 07:59:30 cgd Exp $    */
00006
00007 /*
00008  * Copyright (c) 1983 Regents of the University of California.
00009  * All rights reserved.
00010  *
00011  * Redistribution and use in source and binary forms, with or without
00012  * modification, are permitted provided that the following conditions
00013  * are met:
00014  * 1. Redistributions of source code must retain the above copyright
00015  *    notice, this list of conditions and the following disclaimer.
00016  * 2. Redistributions in binary form must reproduce the above copyright
00017  *    notice, this list of conditions and the following disclaimer in the
00018  *    documentation and/or other materials provided with the distribution.
00019  * 3. All advertising materials mentioning features or use of this software
00020  *    must display the following acknowledgement:
00021  *      This product includes software developed by the University of
00022  *      California, Berkeley and its contributors.
00023  * 4. Neither the name of the University nor the names of its contributors
00024  *    may be used to endorse or promote products derived from this software
00025  *    without specific prior written permission.
00026  *
00027  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
00028  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00029  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00030  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
00031  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00032  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00033  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00034  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00035  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00036  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00037  * SUCH DAMAGE.
00038  *
00039  *      @(#)talkd.h     5.7 (Berkeley) 4/3/91
00040  */
00041
00042 #ifndef __PROTOCOL_TALKD_H
00043 #define __PROTOCOL_TALKD_H
00044
00045 /*
00046  * This describes the protocol used by the talk server and clients.
00047  *
00048  * The talk server acts a repository of invitations, responding to
00049  * requests by clients wishing to rendezvous for the purpose of
00050  * holding a conversation.  In normal operation, a client, the caller,
00051  * initiates a rendezvous by sending a CTL_MSG to the server of
00052  * type LOOK_UP.  This causes the server to search its invitation
00053  * tables to check if an invitation currently exists for the caller
00054  * (to speak to the callee specified in the message).  If the lookup
00055  * fails, the caller then sends an ANNOUNCE message causing the server
00056  * to broadcast an announcement on the callee's login ports requesting
00057  * contact.  When the callee responds, the local server uses the
00058  * recorded invitation to respond with the appropriate rendezvous
00059  * address and the caller and callee client programs establish a
00060  * stream connection through which the conversation takes place.
00061  */
00062
00063 #include <sys/packon.h>
00064
00065 /*
00066  * Client->server request message format.
00067  */
00068 typedef struct {
00069         u_char    vers;                 /* protocol version */
00070         u_char    type;                 /* request type, see below */
00071         u_char    answer;               /* not used */
00072         u_char    pad;
00073         u_int32_t id_num;               /* message id */
00074         struct    osockaddr addr;       /* old (4.3) style */
00075         struct    osockaddr ctl_addr;   /* old (4.3) style */
00076         int32_t   pid;                  /* caller's process id */
00077 #define NAME_SIZE       12
00078         char      l_name[NAME_SIZE];    /* caller's name */
00079         char      r_name[NAME_SIZE];    /* callee's name */
00080 #define TTY_SIZE        16
00081         char      r_tty[TTY_SIZE];      /* callee's tty name */
00082 } CTL_MSG;
00083
00084 /*
00085  * Server->client response message format.
00086  */
00087 typedef struct {
00088         u_char    vers;         /* protocol version */
00089         u_char    type;         /* type of request message, see below */
00090         u_char    answer;       /* respose to request message, see below */
00091         u_char    pad;
00092         u_int32_t id_num;       /* message id */
00093         struct    osockaddr addr; /* address for establishing conversation */
00094 } CTL_RESPONSE;
00095
00096 #include <sys/packoff.h>
00097
00098 #define TALK_VERSION    1               /* protocol version */
00099
00100 /* message type values */
00101 #define LEAVE_INVITE    0       /* leave invitation with server */
00102 #define LOOK_UP         1       /* check for invitation by callee */
00103 #define DELETE          2       /* delete invitation by caller */
00104 #define ANNOUNCE        3       /* announce invitation by caller */
00105
00106 /* answer values */
00107 #define SUCCESS         0       /* operation completed properly */
00108 #define NOT_HERE        1       /* callee not logged in */
00109 #define FAILED          2       /* operation failed for unexplained reason */
00110 #define MACHINE_UNKNOWN 3       /* caller's machine name unknown */
00111 #define PERMISSION_DENIED 4     /* callee's tty doesn't permit announce */
00112 #define UNKNOWN_REQUEST 5       /* request has invalid type value */
00113 #define BADVERSION      6       /* request has invalid protocol version */
00114 #define BADADDR         7       /* request has invalid addr value */
00115 #define BADCTLADDR      8       /* request has invalid ctl_addr value */
00116
00117 /*
00118  * Operational parameters.
00119  */
00120 #define MAX_LIFE        60      /* max time daemon saves invitations */
00121 /* RING_WAIT should be 10's of seconds less than MAX_LIFE */
00122 #define RING_WAIT       30      /* time to wait before resending invitation */
00123
00124 #endif
Generated on Wed Jan 25 15:42:33 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/protocol/TIMED.H Source File

inc/protocol/TIMED.H

Go to the documentation of this file.
00001
00005 /*      $NetBSD: timed.h,v 1.5 1996/04/09 20:40:32 cgd Exp $    */
00006
00007 /*
00008  * Copyright (c) 1983 Regents of the University of California.
00009  * All rights reserved.
00010  *
00011  * Redistribution and use in source and binary forms, with or without
00012  * modification, are permitted provided that the following conditions
00013  * are met:
00014  * 1. Redistributions of source code must retain the above copyright
00015  *    notice, this list of conditions and the following disclaimer.
00016  * 2. Redistributions in binary form must reproduce the above copyright
00017  *    notice, this list of conditions and the following disclaimer in the
00018  *    documentation and/or other materials provided with the distribution.
00019  * 3. All advertising materials mentioning features or use of this software
00020  *    must display the following acknowledgement:
00021  *      This product includes software developed by the University of
00022  *      California, Berkeley and its contributors.
00023  * 4. Neither the name of the University nor the names of its contributors
00024  *    may be used to endorse or promote products derived from this software
00025  *    without specific prior written permission.
00026  *
00027  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
00028  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00029  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00030  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
00031  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00032  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00033  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00034  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00035  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00036  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00037  * SUCH DAMAGE.
00038  *
00039  *      @(#)timed.h     1.10 (Berkeley) 4/3/91
00040  */
00041
00042 #ifndef __PROTOCOL_TIMED_H
00043 #define __PROTOCOL_TIMED_H
00044
00045 /*
00046  * Time Synchronization Protocol
00047  */
00048
00049 #define TSPVERSION      1
00050 #define ANYADDR         NULL
00051
00052 #include <sys/packon.h>
00053
00054 struct tsp {
00055         u_int8_t tsp_type;
00056         u_int8_t tsp_vers;
00057         u_int16_t tsp_seq;
00058         union {
00059                 struct {
00060                         int32_t tv_sec;
00061                         int32_t tv_usec;
00062                 } tspu_time;
00063                 char tspu_hopcnt;
00064         } tsp_u;
00065         char tsp_name[MAXHOSTNAMELEN];
00066 };
00067
00068 #include <sys/packoff.h>
00069
00070 #define tsp_time        tsp_u.tspu_time
00071 #define tsp_hopcnt      tsp_u.tspu_hopcnt
00072
00073 /*
00074  * Command types.
00075  */
00076 #define TSP_ANY                 0       /* match any types */
00077 #define TSP_ADJTIME             1       /* send adjtime */
00078 #define TSP_ACK                 2       /* generic acknowledgement */
00079 #define TSP_MASTERREQ           3       /* ask for master's name */
00080 #define TSP_MASTERACK           4       /* acknowledge master request */
00081 #define TSP_SETTIME             5       /* send network time */
00082 #define TSP_MASTERUP            6       /* inform slaves that master is up */
00083 #define TSP_SLAVEUP             7       /* slave is up but not polled */
00084 #define TSP_ELECTION            8       /* advance candidature for master */
00085 #define TSP_ACCEPT              9       /* support candidature of master */
00086 #define TSP_REFUSE              10      /* reject candidature of master */
00087 #define TSP_CONFLICT            11      /* two or more masters present */
00088 #define TSP_RESOLVE             12      /* masters' conflict resolution */
00089 #define TSP_QUIT                13      /* reject candidature if master is up */
00090 #define TSP_DATE                14      /* reset the time (date command) */
00091 #define TSP_DATEREQ             15      /* remote request to reset the time */
00092 #define TSP_DATEACK             16      /* acknowledge time setting  */
00093 #define TSP_TRACEON             17      /* turn tracing on */
00094 #define TSP_TRACEOFF            18      /* turn tracing off */
00095 #define TSP_MSITE               19      /* find out master's site */
00096 #define TSP_MSITEREQ            20      /* remote master's site request */
00097 #define TSP_TEST                21      /* for testing election algo */
00098 #define TSP_SETDATE             22      /* New from date command */
00099 #define TSP_SETDATEREQ          23      /* New remote for above */
00100 #define TSP_LOOP                24      /* loop detection packet */
00101
00102 #define TSPTYPENUMBER           25
00103
00104 #ifdef TSPTYPES
00105 char *tsptype[TSPTYPENUMBER] = {
00106      "ANY", "ADJTIME", "ACK", "MASTERREQ", "MASTERACK", "SETTIME", "MASTERUP",
00107      "SLAVEUP", "ELECTION", "ACCEPT", "REFUSE", "CONFLICT", "RESOLVE", "QUIT",
00108      "DATE", "DATEREQ", "DATEACK", "TRACEON", "TRACEOFF", "MSITE", "MSITEREQ",
00109      "TEST", "SETDATE", "SETDATEREQ", "LOOP"
00110    };
00111 #endif
00112
00113 #endif
Generated on Wed Jan 25 15:42:33 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/rpc/AUTH.H Source File

inc/rpc/AUTH.H

Go to the documentation of this file.
00001
00005 /*
00006  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
00007  * unrestricted use provided that this legend is included on all tape
00008  * media and as a part of the software program in whole or part.  Users
00009  * may copy or modify Sun RPC without charge, but are not authorized
00010  * to license or distribute it to anyone else except as part of a product or
00011  * program developed by the user.
00012  *
00013  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
00014  * WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00015  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
00016  *
00017  * Sun RPC is provided with no support and without any obligation on the
00018  * part of Sun Microsystems, Inc. to assist in its use, correction,
00019  * modification or enhancement.
00020  *
00021  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
00022  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
00023  * OR ANY PART THEREOF.
00024  *
00025  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
00026  * or profits or other special, indirect and consequential damages, even if
00027  * Sun has been advised of the possibility of such damages.
00028  *
00029  * Sun Microsystems, Inc.
00030  * 2550 Garcia Avenue
00031  * Mountain View, California  94043
00032  *
00033  *      from: @(#)auth.h 1.17 88/02/08 SMI
00034  *      from: @(#)auth.h        2.3 88/08/07 4.0 RPCSRC
00035  *      $Id: auth.h,v 1.5 1996/01/31 08:02:11 hsu Exp $
00036  */
00037
00038 /*
00039  * auth.h, Authentication interface.
00040  *
00041  * Copyright (C) 1984, Sun Microsystems, Inc.
00042  *
00043  * The data structures are completely opaque to the client.  The client
00044  * is required to pass a AUTH * to routines that create rpc
00045  * "sessions".
00046  */
00047
00048 #ifndef __RPC_AUTH_H
00049 #define __RPC_AUTH_H
00050
00051 #ifndef __SYS_CDEFS_H
00052 #include <sys/cdefs.h>
00053 #endif
00054
00055 #ifndef __SYS_SOCKET_H
00056 #include <sys/socket.h>
00057 #endif
00058
00059 #define MAX_AUTH_BYTES  400
00060 #define MAXNETNAMELEN   255     /* maximum length of network user's name */
00061
00062 /*
00063  * Status returned from authentication check
00064  */
00065 enum auth_stat {
00066         AUTH_OK=0,
00067         /*
00068          * failed at remote end
00069          */
00070         AUTH_BADCRED=1,                 /* bogus credentials (seal broken) */
00071         AUTH_REJECTEDCRED=2,            /* client should begin new session */
00072         AUTH_BADVERF=3,                 /* bogus verifier (seal broken) */
00073         AUTH_REJECTEDVERF=4,            /* verifier expired or was replayed */
00074         AUTH_TOOWEAK=5,                 /* rejected due to security reasons */
00075         /*
00076          * failed locally
00077         */
00078         AUTH_INVALIDRESP=6,             /* bogus response verifier */
00079         AUTH_FAILED=7                   /* some unknown reason */
00080 };
00081
00082 union des_block {
00083       struct {
00084         u_long high;
00085         u_long low;
00086       } key;
00087       char c[8];
00088     };
00089
00090 typedef union des_block des_block;
00091
00092 __BEGIN_DECLS
00093
00094 extern bool_t xdr_des_block (XDR *, des_block *);
00095
00096 __END_DECLS
00097
00098 /*
00099  * Authentication info.  Opaque to client.
00100  */
00101 struct opaque_auth {
00102        enum_t  oa_flavor;              /* flavor of auth */
00103        caddr_t oa_base;                /* address of more auth stuff */
00104        u_int   oa_length;              /* not to exceed MAX_AUTH_BYTES */
00105      };
00106
00107 /*
00108  * Auth handle, interface to client side authenticators.
00109  */
00110 typedef struct {
00111         struct  opaque_auth     ah_cred;
00112         struct  opaque_auth     ah_verf;
00113         union   des_block       ah_key;
00114         struct auth_ops {
00115                void    (*ah_nextverf)();
00116                int     (*ah_marshal)();        /* nextverf & serialize */
00117                int     (*ah_validate)();       /* validate verifier */
00118                int     (*ah_refresh)();        /* refresh credentials */
00119                void    (*ah_destroy)();        /* destroy this structure */
00120         } *ah_ops;
00121         caddr_t ah_private;
00122       } AUTH;
00123
00124
00125 /*
00126  * Authentication ops.
00127  * The ops and the auth handle provide the interface to the authenticators.
00128  *
00129  * AUTH *auth;
00130  * XDR  *xdrs;
00131  * struct opaque_auth verf;
00132  */
00133 #define AUTH_NEXTVERF(auth)       ((*((auth)->ah_ops->ah_nextverf))(auth))
00134 #define auth_nextverf(auth)       ((*((auth)->ah_ops->ah_nextverf))(auth))
00135
00136 #define AUTH_MARSHALL(auth,xdrs)  ((*((auth)->ah_ops->ah_marshal))(auth, xdrs))
00137 #define auth_marshall(auth,xdrs)  ((*((auth)->ah_ops->ah_marshal))(auth, xdrs))
00138
00139 #define AUTH_VALIDATE(auth,verfp) ((*((auth)->ah_ops->ah_validate))((auth), verfp))
00140 #define auth_validate(auth,verfp) ((*((auth)->ah_ops->ah_validate))((auth), verfp))
00141
00142 #define AUTH_REFRESH(auth)        ((*((auth)->ah_ops->ah_refresh))(auth))
00143 #define auth_refresh(auth)        ((*((auth)->ah_ops->ah_refresh))(auth))
00144
00145 #define AUTH_DESTROY(auth)        ((*((auth)->ah_ops->ah_destroy))(auth))
00146 #define auth_destroy(auth)        ((*((auth)->ah_ops->ah_destroy))(auth))
00147
00148 extern struct opaque_auth _null_auth;
00149
00150
00151 /*
00152  * These are the various implementations of client side authenticators.
00153  */
00154
00155 /*
00156  * Unix style authentication
00157  * AUTH *authunix_create(machname, uid, gid, len, aup_gids)
00158  *      char *machname;
00159  *      int uid;
00160  *      int gid;
00161  *      int len;
00162  *      int *aup_gids;
00163  */
00164
00165 __BEGIN_DECLS
00166
00167 extern AUTH *authunix_create        (char *, int, int, int, int *);
00168 extern AUTH *authunix_create_default(void);
00169 extern AUTH *authnone_create        (void);
00170 extern AUTH *authdes_create         (char*, u_int, struct sockaddr*, des_block*);
00171
00172 __END_DECLS
00173
00174 #define AUTH_NONE       0               /* no authentication */
00175 #define AUTH_NULL       0               /* backward compatibility */
00176 #define AUTH_UNIX       1               /* unix style (uid, gids) */
00177 #define AUTH_SHORT      2               /* short hand unix style */
00178 #define AUTH_DES        3               /* des style (encrypted timestamps) */
00179
00180 #endif
Generated on Wed Jan 25 15:42:33 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/rpc/AUTH_DES.H Source File

inc/rpc/AUTH_DES.H

Go to the documentation of this file.
00001
00005 /*      @(#)auth_des.h  2.2 88/07/29 4.0 RPCSRC; from 1.3 88/02/08 SMI */
00006 /*
00007  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
00008  * unrestricted use provided that this legend is included on all tape
00009  * media and as a part of the software program in whole or part.  Users
00010  * may copy or modify Sun RPC without charge, but are not authorized
00011  * to license or distribute it to anyone else except as part of a product or
00012  * program developed by the user.
00013  *
00014  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
00015  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
00016  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
00017  *
00018  * Sun RPC is provided with no support and without any obligation on the
00019  * part of Sun Microsystems, Inc. to assist in its use, correction,
00020  * modification or enhancement.
00021  *
00022  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
00023  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
00024  * OR ANY PART THEREOF.
00025  *
00026  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
00027  * or profits or other special, indirect and consequential damages, even if
00028  * Sun has been advised of the possibility of such damages.
00029  *
00030  * Sun Microsystems, Inc.
00031  * 2550 Garcia Avenue
00032  * Mountain View, California  94043
00033  */
00034
00035 /*
00036  * Copyright (c) 1988 by Sun Microsystems, Inc.
00037  */
00038
00039 /*
00040  * auth_des.h, Protocol for DES style authentication for RPC
00041  */
00042
00043 #ifndef __AUTH_DES_H
00044 #define __AUTH_DES_H
00045
00046 /*
00047  * There are two kinds of "names": fullnames and nicknames
00048  */
00049 enum authdes_namekind {
00050         ADN_FULLNAME,
00051         ADN_NICKNAME
00052 };
00053
00054 /*
00055  * A fullname contains the network name of the client,
00056  * a conversation key and the window
00057  */
00058 struct authdes_fullname {
00059         char *name;             /* network name of client, up to MAXNETNAMELEN */
00060         des_block key;          /* conversation key */
00061         u_long window;          /* associated window */
00062 };
00063
00064
00065 /*
00066  * A credential
00067  */
00068 struct authdes_cred {
00069         enum authdes_namekind adc_namekind;
00070         struct authdes_fullname adc_fullname;
00071         u_long adc_nickname;
00072 };
00073
00074
00075
00076 /*
00077  * A des authentication verifier
00078  */
00079 struct authdes_verf {
00080         union {
00081                 struct timeval adv_ctime;       /* clear time */
00082                 des_block adv_xtime;            /* crypt time */
00083         } adv_time_u;
00084         u_long adv_int_u;
00085 };
00086
00087 /*
00088  * des authentication verifier: client variety
00089  *
00090  * adv_timestamp is the current time.
00091  * adv_winverf is the credential window + 1.
00092  * Both are encrypted using the conversation key.
00093  */
00094 #define adv_timestamp   adv_time_u.adv_ctime
00095 #define adv_xtimestamp  adv_time_u.adv_xtime
00096 #define adv_winverf     adv_int_u
00097
00098 /*
00099  * des authentication verifier: server variety
00100  *
00101  * adv_timeverf is the client's timestamp + client's window
00102  * adv_nickname is the server's nickname for the client.
00103  * adv_timeverf is encrypted using the conversation key.
00104  */
00105 #define adv_timeverf    adv_time_u.adv_ctime
00106 #define adv_xtimeverf   adv_time_u.adv_xtime
00107 #define adv_nickname    adv_int_u
00108
00109 #endif /* !__AUTH_DES_H */
Generated on Wed Jan 25 15:42:33 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/rpc/AUTH_UNI.H Source File

inc/rpc/AUTH_UNI.H

Go to the documentation of this file.
00001
00005 /*
00006  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
00007  * unrestricted use provided that this legend is included on all tape
00008  * media and as a part of the software program in whole or part.  Users
00009  * may copy or modify Sun RPC without charge, but are not authorized
00010  * to license or distribute it to anyone else except as part of a product or
00011  * program developed by the user.
00012  *
00013  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
00014  * WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00015  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
00016  *
00017  * Sun RPC is provided with no support and without any obligation on the
00018  * part of Sun Microsystems, Inc. to assist in its use, correction,
00019  * modification or enhancement.
00020  *
00021  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
00022  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
00023  * OR ANY PART THEREOF.
00024  *
00025  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
00026  * or profits or other special, indirect and consequential damages, even if
00027  * Sun has been advised of the possibility of such damages.
00028  *
00029  * Sun Microsystems, Inc.
00030  * 2550 Garcia Avenue
00031  * Mountain View, California  94043
00032  *
00033  *      from: @(#)auth_unix.h 1.8 88/02/08 SMI
00034  *      from: @(#)auth_unix.h   2.2 88/07/29 4.0 RPCSRC
00035  *      $Id: auth_unix.h,v 1.4 1996/01/30 23:31:42 mpp Exp $
00036  */
00037
00038 /*
00039  * auth_unix.h, Protocol for UNIX style authentication parameters for RPC
00040  *
00041  * Copyright (C) 1984, Sun Microsystems, Inc.
00042  */
00043
00044 /*
00045  * The system is very weak.  The client uses no encryption for  it
00046  * credentials and only sends null verifiers.  The server sends backs
00047  * null verifiers or optionally a verifier that suggests a new short hand
00048  * for the credentials.
00049  */
00050
00051 #ifndef __RPC_AUTH_UNIX_H
00052 #define __RPC_AUTH_UNIX_H
00053
00054 #include <sys/cdefs.h>
00055
00056 /* The machine name is part of a credential; it may not exceed 255 bytes */
00057 #define MAX_MACHINE_NAME 255
00058
00059 /* gids compose part of a credential; there may not be more than 16 of them */
00060 #define NGRPS 16
00061
00062 /*
00063  * Unix style credentials.
00064  */
00065 struct authunix_parms {
00066         u_long   aup_time;
00067         char    *aup_machname;
00068         int      aup_uid;
00069         int      aup_gid;
00070         u_int    aup_len;
00071         int     *aup_gids;
00072 };
00073
00074 __BEGIN_DECLS
00075
00076 extern bool_t xdr_authunix_parms (XDR *, struct authunix_parms *);
00077
00078 __END_DECLS
00079
00080 /*
00081  * If a response verifier has flavor AUTH_SHORT,
00082  * then the body of the response verifier encapsulates the following structure;
00083  * again it is serialized in the obvious fashion.
00084  */
00085 struct short_hand_verf {
00086        struct opaque_auth new_cred;
00087 };
00088
00089 #endif
Generated on Wed Jan 25 15:42:33 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/rpc/CLNT.H Source File

inc/rpc/CLNT.H

Go to the documentation of this file.
00001
00005 /*
00006  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
00007  * unrestricted use provided that this legend is included on all tape
00008  * media and as a part of the software program in whole or part.  Users
00009  * may copy or modify Sun RPC without charge, but are not authorized
00010  * to license or distribute it to anyone else except as part of a product or
00011  * program developed by the user.
00012  *
00013  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
00014  * WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00015  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
00016  *
00017  * Sun RPC is provided with no support and without any obligation on the
00018  * part of Sun Microsystems, Inc. to assist in its use, correction,
00019  * modification or enhancement.
00020  *
00021  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
00022  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
00023  * OR ANY PART THEREOF.
00024  *
00025  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
00026  * or profits or other special, indirect and consequential damages, even if
00027  * Sun has been advised of the possibility of such damages.
00028  *
00029  * Sun Microsystems, Inc.
00030  * 2550 Garcia Avenue
00031  * Mountain View, California  94043
00032  *
00033  *      from: @(#)clnt.h 1.31 88/02/08 SMI
00034  *      from: @(#)clnt.h        2.1 88/07/29 4.0 RPCSRC
00035  *      $Id: clnt.h,v 1.4 1996/01/30 23:31:48 mpp Exp $
00036  */
00037
00038 /*
00039  * clnt.h - Client side remote procedure call interface.
00040  *
00041  * Copyright (C) 1984, Sun Microsystems, Inc.
00042  */
00043
00044 #ifndef __RPC_CLIENT_H
00045 #define __RPC_CLIENT_H
00046
00047 #include <sys/cdefs.h>
00048 #include <rpc/types.h>
00049 #include <rpc/xdr.h>
00050
00051 /*
00052  * Rpc calls return an enum clnt_stat.  This should be looked at more,
00053  * since each implementation is required to live with this (implementation
00054  * independent) list of errors.
00055  */
00056 enum clnt_stat {
00057      RPC_SUCCESS=0,                  /* call succeeded */
00058      /*
00059       * local errors
00060       */
00061      RPC_CANTENCODEARGS=1,           /* can't encode arguments */
00062      RPC_CANTDECODERES=2,            /* can't decode results */
00063      RPC_CANTSEND=3,                 /* failure in sending call */
00064      RPC_CANTRECV=4,                 /* failure in receiving result */
00065      RPC_TIMEDOUT=5,                 /* call timed out */
00066      /*
00067       * remote errors
00068       */
00069      RPC_VERSMISMATCH=6,             /* rpc versions not compatible */
00070      RPC_AUTHERROR=7,                /* authentication error */
00071      RPC_PROGUNAVAIL=8,              /* program not available */
00072      RPC_PROGVERSMISMATCH=9,         /* program version mismatched */
00073      RPC_PROCUNAVAIL=10,             /* procedure unavailable */
00074      RPC_CANTDECODEARGS=11,          /* decode arguments error */
00075      RPC_SYSTEMERROR=12,             /* generic "other problem" */
00076
00077      /*
00078       * callrpc & clnt_create errors
00079       */
00080      RPC_UNKNOWNHOST=13,             /* unknown host name */
00081      RPC_UNKNOWNPROTO=17,            /* unkown protocol */
00082
00083      /*
00084       * _ create errors
00085       */
00086      RPC_PMAPFAILURE=14,             /* the pmapper failed in its call */
00087      RPC_PROGNOTREGISTERED=15,       /* remote program is not registered */
00088      /*
00089       * unspecified error
00090       */
00091      RPC_FAILED=16
00092    };
00093
00094
00095 /*
00096  * Error info.
00097  */
00098 struct rpc_err {
00099        enum clnt_stat re_status;
00100        union {
00101          int            RE_errno;  /* related system error */
00102          enum auth_stat RE_why;    /* why the auth error occurred */
00103          struct {
00104            u_long low;             /* lowest verion supported */
00105            u_long high;            /* highest verion supported */
00106          } RE_vers;
00107          struct {                  /* maybe meaningful if RPC_FAILED */
00108            long s1;
00109            long s2;
00110          } RE_lb;                  /* life boot & debugging only */
00111        } ru;
00112 #define re_errno  ru.RE_errno
00113 #define re_why    ru.RE_why
00114 #define re_vers   ru.RE_vers
00115 #define re_lb     ru.RE_lb
00116 };
00117
00118
00119 /*
00120  * Client rpc handle.
00121  * Created by individual implementations, see e.g. rpc_udp.c.
00122  * Client is responsible for initializing auth, see e.g. auth_none.c.
00123  */
00124 typedef struct {
00125         AUTH  *cl_auth;                        /* authenticator */
00126         struct clnt_ops {
00127                 enum clnt_stat(*cl_call)();    /* call remote procedure */
00128                 void          (*cl_abort)();   /* abort a call */
00129                 void          (*cl_geterr)();  /* get specific error code */
00130                 bool_t        (*cl_freeres)(); /* frees results */
00131                 void          (*cl_destroy)(); /* destroy this structure */
00132                 bool_t        (*cl_control)(); /* the ioctl() of rpc */
00133         } *cl_ops;
00134         caddr_t               cl_private;      /* private stuff */
00135 } CLIENT;
00136
00137
00138 /*
00139  * client side rpc interface ops
00140  *
00141  * Parameter types are:
00142  *
00143  */
00144
00145 /*
00146  * enum clnt_stat
00147  * CLNT_CALL(rh, proc, xargs, argsp, xres, resp, timeout)
00148  *      CLIENT *rh;
00149  *      u_long proc;
00150  *      xdrproc_t xargs;
00151  *      caddr_t argsp;
00152  *      xdrproc_t xres;
00153  *      caddr_t resp;
00154  *      struct timeval timeout;
00155  */
00156 #define CLNT_CALL(rh, proc, xargs, argsp, xres, resp, secs)     \
00157         ((*(rh)->cl_ops->cl_call)(rh, proc, xargs, argsp, xres, resp, secs))
00158 #define clnt_call(rh, proc, xargs, argsp, xres, resp, secs)     \
00159         ((*(rh)->cl_ops->cl_call)(rh, proc, xargs, argsp, xres, resp, secs))
00160
00161 /*
00162  * void
00163  * CLNT_ABORT(rh);
00164  *      CLIENT *rh;
00165  */
00166 #define CLNT_ABORT(rh)  ((*(rh)->cl_ops->cl_abort)(rh))
00167 #define clnt_abort(rh)  ((*(rh)->cl_ops->cl_abort)(rh))
00168
00169 /*
00170  * struct rpc_err
00171  * CLNT_GETERR(rh);
00172  *      CLIENT *rh;
00173  */
00174 #define CLNT_GETERR(rh,errp)  ((*(rh)->cl_ops->cl_geterr)(rh, errp))
00175 #define clnt_geterr(rh,errp)  ((*(rh)->cl_ops->cl_geterr)(rh, errp))
00176
00177
00178 /*
00179  * bool_t
00180  * CLNT_FREERES(rh, xres, resp);
00181  *      CLIENT *rh;
00182  *      xdrproc_t xres;
00183  *      caddr_t resp;
00184  */
00185 #define CLNT_FREERES(rh,xres,resp) ((*(rh)->cl_ops->cl_freeres)(rh,xres,resp))
00186 #define clnt_freeres(rh,xres,resp) ((*(rh)->cl_ops->cl_freeres)(rh,xres,resp))
00187
00188 /*
00189  * bool_t
00190  * CLNT_CONTROL(cl, request, info)
00191  *      CLIENT *cl;
00192  *      u_int request;
00193  *      char *info;
00194  */
00195 #define CLNT_CONTROL(cl,rq,in) ((*(cl)->cl_ops->cl_control)(cl,rq,in))
00196 #define clnt_control(cl,rq,in) ((*(cl)->cl_ops->cl_control)(cl,rq,in))
00197
00198 /*
00199  * control operations that apply to both udp and tcp transports
00200  */
00201 #define CLSET_TIMEOUT       1   /* set timeout (timeval) */
00202 #define CLGET_TIMEOUT       2   /* get timeout (timeval) */
00203 #define CLGET_SERVER_ADDR   3   /* get server's address (sockaddr) */
00204 /*
00205  * udp only control operations
00206  */
00207 #define CLSET_RETRY_TIMEOUT 4   /* set retry timeout (timeval) */
00208 #define CLGET_RETRY_TIMEOUT 5   /* get retry timeout (timeval) */
00209
00210 /*
00211  * void
00212  * CLNT_DESTROY(rh);
00213  *      CLIENT *rh;
00214  */
00215 #define CLNT_DESTROY(rh)        ((*(rh)->cl_ops->cl_destroy)(rh))
00216 #define clnt_destroy(rh)        ((*(rh)->cl_ops->cl_destroy)(rh))
00217
00218
00219 /*
00220  * RPCTEST is a test program which is accessible on every rpc
00221  * transport/port.  It is used for testing, performance evaluation,
00222  * and network administration.
00223  */
00224
00225 #define RPCTEST_PROGRAM         ((u_long)1)
00226 #define RPCTEST_VERSION         ((u_long)1)
00227 #define RPCTEST_NULL_PROC       ((u_long)2)
00228 #define RPCTEST_NULL_BATCH_PROC ((u_long)3)
00229
00230 /*
00231  * By convention, procedure 0 takes null arguments and returns them
00232  */
00233
00234 #define NULLPROC ((u_long)0)
00235
00236 __BEGIN_DECLS
00237
00238 /*
00239  * Below are the client handle creation routines for the various
00240  * implementations of client side rpc.  They can return NULL if a
00241  * creation failure occurs.
00242  */
00243
00244 /*
00245  * Memory based rpc (for speed check and testing)
00246  * CLIENT *
00247  * clntraw_create(prog, vers)
00248  *      u_long prog;
00249  *      u_long vers;
00250  */
00251 extern CLIENT *clntraw_create (u_long, u_long);
00252
00253 /*
00254  * Generic client creation routine. Supported protocols are "udp" and "tcp"
00255  * CLIENT *
00256  * clnt_create(host, prog, vers, prot);
00257  *      char *host;     -- hostname
00258  *      u_long prog;    -- program number
00259  *      u_long vers;    -- version number
00260  *      char *prot;     -- protocol
00261  */
00262 extern CLIENT *clnt_create      (char *, u_long, u_long, char *);
00263
00264
00265 /*
00266  * TCP based rpc
00267  * CLIENT *
00268  * clnttcp_create(raddr, prog, vers, sockp, sendsz, recvsz)
00269  *      struct sockaddr_in *raddr;
00270  *      u_long prog;
00271  *      u_long version;
00272  *      register int *sockp;
00273  *      u_int sendsz;
00274  *      u_int recvsz;
00275  */
00276
00277 extern CLIENT *clnttcp_create   (struct sockaddr_in *, u_long, u_long,
00278                                  int *, u_int, u_int);
00279
00280 /*
00281  * UDP based rpc.
00282  * CLIENT *
00283  * clntudp_create(raddr, program, version, wait, sockp)
00284  *      struct sockaddr_in *raddr;
00285  *      u_long program;
00286  *      u_long version;
00287  *      struct timeval wait;
00288  *      int *sockp;
00289  *
00290  * Same as above, but you specify max packet sizes.
00291  * CLIENT *
00292  * clntudp_bufcreate(raddr, program, version, wait, sockp, sendsz, recvsz)
00293  *      struct sockaddr_in *raddr;
00294  *      u_long program;
00295  *      u_long version;
00296  *      struct timeval wait;
00297  *      int *sockp;
00298  *      u_int sendsz;
00299  *      u_int recvsz;
00300  */
00301
00302 extern CLIENT *clntudp_create   (struct sockaddr_in *, u_long, u_long,
00303                                  struct timeval, int *);
00304 extern CLIENT *clntudp_bufcreate(struct sockaddr_in *, u_long, u_long,
00305                                  struct timeval, int *, u_int, u_int);
00306
00307
00308 /*
00309  * Print why creation failed
00310  */
00311
00312 extern void  clnt_pcreateerror  (char *);     /* stderr */
00313 extern char *clnt_spcreateerror (char *);     /* string */
00314
00315 /*
00316  * Like clnt_perror(), but is more verbose in its output
00317  */
00318
00319 extern void clnt_perrno  (enum clnt_stat);    /* stderr */
00320 extern char *clnt_sperrno(enum clnt_stat);    /* string */
00321
00322 /*
00323  * Print an English error message, given the client error code
00324  */
00325
00326 extern void  clnt_perror (CLIENT *, char *);  /* stderr */
00327 extern char *clnt_sperror(CLIENT *, char *);  /* string */
00328
00329 /*
00330  * Call routine on remote host
00331  */
00332
00333 extern int callrpc (char *host, u_long prognum, u_long versnum, u_long procnum,
00334                     xdrproc_t inproc,  char *in,
00335                     xdrproc_t outproc, char *out);
00336
00337 __END_DECLS
00338
00339
00340 /*
00341  * If a creation fails, the following allows the user to figure out why.
00342  */
00343 struct rpc_createerr {
00344        enum clnt_stat cf_stat;
00345        struct rpc_err cf_error; /* useful when cf_stat == RPC_PMAPFAILURE */
00346        const char    *cf_file;  /* failed file + line */
00347        unsigned       cf_line;
00348      };
00349
00350 extern struct rpc_createerr rpc_createerr;
00351
00352
00353 #define UDPMSGSIZE      8800    /* rpc imposed limit on udp msg size */
00354 #define RPCSMALLMSGSIZE 400     /* a more reasonable packet size */
00355
00356 #endif
Generated on Wed Jan 25 15:42:33 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/rpc/KEY_PROT.H Source File

inc/rpc/KEY_PROT.H

Go to the documentation of this file.
00001
00005 /*
00006  * This is a RPCGEN generated file. Do not edit.
00007  *
00008  * Generated: Sun Mar 14 19:22:40 1999
00009  */
00010
00011 #ifndef __KEY_PROT_H
00012 #define __KEY_PROT_H
00013
00014
00015 /*
00016  * Copyright (c) 1988 by Sun Microsystems, Inc.
00017  */
00018 #define PROOT                     3
00019 #define HEXMODULUS                "d4a0ba0250b6fd2ec626e7efd637df76c716e22d0944b88b"
00020 #define HEXKEYBYTES               48
00021 #define KEYSIZE                   192
00022 #define KEYBYTES                  24
00023 #define KEYCHECKSUMSIZE           16
00024
00025 typedef enum keystatus {
00026           KEY_SUCCESS = 0,
00027           KEY_NOSECRET = 1,
00028           KEY_UNKNOWN = 2,
00029           KEY_SYSTEMERR = 3,
00030       } keystatus;
00031 bool_t xdr_keystatus();
00032
00033 #ifndef KERNEL
00034
00035 typedef char keybuf[HEXKEYBYTES];
00036 bool_t xdr_keybuf();
00037
00038 #endif
00039
00040 typedef char *netnamestr;
00041 bool_t xdr_netnamestr();
00042
00043
00044 typedef struct cryptkeyarg {
00045         netnamestr remotename;
00046         des_block deskey;
00047       } cryptkeyarg;
00048 bool_t xdr_cryptkeyarg();
00049
00050
00051 typedef struct cryptkeyres {
00052         keystatus status;
00053   union {
00054     des_block deskey;
00055     } cryptkeyres_u;
00056   } cryptkeyres;
00057 bool_t xdr_cryptkeyres();
00058
00059 #define MAXGIDS                   16
00060
00061 typedef struct unixcred {
00062         long uid;
00063         long gid;
00064         struct {
00065           u_long gids_len;
00066           long *gids_val;
00067         } gids;
00068       } unixcred;
00069 bool_t xdr_unixcred();
00070
00071
00072 typedef struct getcredres {
00073         keystatus status;
00074   union {
00075     unixcred cred;
00076     } getcredres_u;
00077   } getcredres;
00078 bool_t xdr_getcredres();
00079
00080
00081 #define KEY_PROG                  100029UL
00082 #define KEY_VERS                  1UL
00083 #define KEY_SET                   1UL
00084 extern long *key_set_1();
00085
00086 #define KEY_ENCRYPT               2UL
00087 extern cryptkeyres *key_encrypt_1();
00088
00089 #define KEY_DECRYPT               3UL
00090 extern cryptkeyres *key_decrypt_1();
00091
00092 #define KEY_GEN                   4UL
00093 extern des_block *key_gen_1();
00094
00095 #define KEY_GETCRED               5UL
00096 extern getcredres *key_getcred_1();
00097
00098
00099 #endif /* !__KEY_PROT_H */
Generated on Wed Jan 25 15:42:33 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/rpc/PMAP_CLN.H Source File

inc/rpc/PMAP_CLN.H

Go to the documentation of this file.
00001
00005 /*
00006  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
00007  * unrestricted use provided that this legend is included on all tape
00008  * media and as a part of the software program in whole or part.  Users
00009  * may copy or modify Sun RPC without charge, but are not authorized
00010  * to license or distribute it to anyone else except as part of a product or
00011  * program developed by the user.
00012  *
00013  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
00014  * WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00015  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
00016  *
00017  * Sun RPC is provided with no support and without any obligation on the
00018  * part of Sun Microsystems, Inc. to assist in its use, correction,
00019  * modification or enhancement.
00020  *
00021  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
00022  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
00023  * OR ANY PART THEREOF.
00024  *
00025  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
00026  * or profits or other special, indirect and consequential damages, even if
00027  * Sun has been advised of the possibility of such damages.
00028  *
00029  * Sun Microsystems, Inc.
00030  * 2550 Garcia Avenue
00031  * Mountain View, California  94043
00032  *
00033  *      from: @(#)pmap_clnt.h 1.11 88/02/08 SMI
00034  *      from: @(#)pmap_clnt.h   2.1 88/07/29 4.0 RPCSRC
00035  *      $Id: pmap_clnt.h,v 1.4 1996/01/30 23:31:59 mpp Exp $
00036  */
00037
00038 /*
00039  * pmap_clnt.h
00040  * Supplies C routines to get to portmap services.
00041  *
00042  * Copyright (C) 1984, Sun Microsystems, Inc.
00043  */
00044
00045 /*
00046  * Usage:
00047  *      success = pmap_set(program, version, protocol, port);
00048  *      success = pmap_unset(program, version);
00049  *      port = pmap_getport(address, program, version, protocol);
00050  *      head = pmap_getmaps(address);
00051  *      clnt_stat = pmap_rmtcall(address, program, version, procedure,
00052  *              xdrargs, argsp, xdrres, resp, tout, port_ptr)
00053  *              (works for udp only.)
00054  *      clnt_stat = clnt_broadcast(program, version, procedure,
00055  *              xdrargs, argsp, xdrres, resp, eachresult)
00056  *              (like pmap_rmtcall, except the call is broadcasted to all
00057  *              locally connected nets.  For each valid response received,
00058  *              the procedure eachresult is called.  Its form is:
00059  *      done = eachresult(resp, raddr)
00060  *              bool_t done;
00061  *              caddr_t resp;
00062  *              struct sockaddr_in raddr;
00063  *              where resp points to the results of the call and raddr is the
00064  *              address if the responder to the broadcast.
00065  */
00066
00067 #ifndef __RPC_PMAP_CLIENT_H
00068 #define __RPC_PMAP_CLIENT_H
00069
00070 #include <sys/cdefs.h>
00071
00072 __BEGIN_DECLS
00073
00074 extern bool_t           pmap_set      (u_long, u_long, int, int);
00075 extern bool_t           pmap_unset    (u_long, u_long);
00076 extern struct pmaplist *pmap_getmaps  (struct sockaddr_in *);
00077 extern enum clnt_stat   pmap_rmtcall  (struct sockaddr_in *, u_long, u_long,
00078                                        u_long, xdrproc_t, caddr_t, xdrproc_t,
00079                                        caddr_t, struct timeval, u_long *);
00080 extern enum clnt_stat   clnt_broadcast(u_long, u_long, u_long, xdrproc_t,
00081                                        char *, xdrproc_t, char *, bool_t (*)());
00082 extern u_short          pmap_getport  (struct sockaddr_in *, u_long, u_long, u_int);
00083
00084 __END_DECLS
00085
00086 #endif
Generated on Wed Jan 25 15:42:33 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/rpc/PMAP_PRO.H Source File

inc/rpc/PMAP_PRO.H

Go to the documentation of this file.
00001
00005 /*
00006  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
00007  * unrestricted use provided that this legend is included on all tape
00008  * media and as a part of the software program in whole or part.  Users
00009  * may copy or modify Sun RPC without charge, but are not authorized
00010  * to license or distribute it to anyone else except as part of a product or
00011  * program developed by the user.
00012  *
00013  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
00014  * WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00015  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
00016  *
00017  * Sun RPC is provided with no support and without any obligation on the
00018  * part of Sun Microsystems, Inc. to assist in its use, correction,
00019  * modification or enhancement.
00020  *
00021  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
00022  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
00023  * OR ANY PART THEREOF.
00024  *
00025  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
00026  * or profits or other special, indirect and consequential damages, even if
00027  * Sun has been advised of the possibility of such damages.
00028  *
00029  * Sun Microsystems, Inc.
00030  * 2550 Garcia Avenue
00031  * Mountain View, California  94043
00032  *
00033  *      from: @(#)pmap_prot.h 1.14 88/02/08 SMI
00034  *      from: @(#)pmap_prot.h   2.1 88/07/29 4.0 RPCSRC
00035  *      $Id: pmap_prot.h,v 1.4 1996/01/30 23:32:08 mpp Exp $
00036  */
00037
00038 /*
00039  * pmap_prot.h
00040  * Protocol for the local binder service, or pmap.
00041  *
00042  * Copyright (C) 1984, Sun Microsystems, Inc.
00043  *
00044  * The following procedures are supported by the protocol:
00045  *
00046  * PMAPPROC_NULL() returns ()
00047  *      takes nothing, returns nothing
00048  *
00049  * PMAPPROC_SET(struct pmap) returns (bool_t)
00050  *      TRUE is success, FALSE is failure.  Registers the tuple
00051  *      [prog, vers, prot, port].
00052  *
00053  * PMAPPROC_UNSET(struct pmap) returns (bool_t)
00054  *      TRUE is success, FALSE is failure.  Un-registers pair
00055  *      [prog, vers].  prot and port are ignored.
00056  *
00057  * PMAPPROC_GETPORT(struct pmap) returns (long unsigned).
00058  *      0 is failure.  Otherwise returns the port number where the pair
00059  *      [prog, vers] is registered.  It may lie!
00060  *
00061  * PMAPPROC_DUMP() RETURNS (struct pmaplist *)
00062  *
00063  * PMAPPROC_CALLIT(unsigned, unsigned, unsigned, string<>)
00064  *      RETURNS (port, string<>);
00065  * usage: encapsulatedresults = PMAPPROC_CALLIT(prog, vers, proc, encapsulatedargs);
00066  *      Calls the procedure on the local machine.  If it is not registered,
00067  *      this procedure is quite; ie it does not return error information!!!
00068  *      This procedure only is supported on rpc/udp and calls via
00069  *      rpc/udp.  This routine only passes null authentication parameters.
00070  *      This file has no interface to xdr routines for PMAPPROC_CALLIT.
00071  *
00072  * The service supports remote procedure calls on udp/ip or tcp/ip socket 111.
00073  */
00074
00075 #ifndef __RPC_PMAP_PROT_H
00076 #define __RPC_PMAP_PROT_H
00077
00078 #include <sys/cdefs.h>
00079
00080 #define PMAPPORT          ((u_short)111)
00081 #define PMAPPROG          ((u_long)100000)
00082 #define PMAPVERS          ((u_long)2)
00083 #define PMAPVERS_PROTO    ((u_long)2)
00084 #define PMAPVERS_ORIG     ((u_long)1)
00085 #define PMAPPROC_NULL     ((u_long)0)
00086 #define PMAPPROC_SET      ((u_long)1)
00087 #define PMAPPROC_UNSET    ((u_long)2)
00088 #define PMAPPROC_GETPORT  ((u_long)3)
00089 #define PMAPPROC_DUMP     ((u_long)4)
00090 #define PMAPPROC_CALLIT   ((u_long)5)
00091
00092 struct pmap {
00093        long unsigned pm_prog;
00094        long unsigned pm_vers;
00095        long unsigned pm_prot;
00096        long unsigned pm_port;
00097      };
00098
00099 struct pmaplist {
00100        struct pmap      pml_map;
00101        struct pmaplist *pml_next;
00102      };
00103
00104 __BEGIN_DECLS
00105
00106 extern bool_t xdr_pmap    (XDR *, struct pmap *);
00107 extern bool_t xdr_pmaplist(XDR *, struct pmaplist **);
00108
00109 __END_DECLS
00110
00111 #endif
Generated on Wed Jan 25 15:42:33 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/rpc/PMAP_RMT.H Source File

inc/rpc/PMAP_RMT.H

Go to the documentation of this file.
00001
00005 /*
00006  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
00007  * unrestricted use provided that this legend is included on all tape
00008  * media and as a part of the software program in whole or part.  Users
00009  * may copy or modify Sun RPC without charge, but are not authorized
00010  * to license or distribute it to anyone else except as part of a product or
00011  * program developed by the user.
00012  *
00013  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
00014  * WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00015  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
00016  *
00017  * Sun RPC is provided with no support and without any obligation on the
00018  * part of Sun Microsystems, Inc. to assist in its use, correction,
00019  * modification or enhancement.
00020  *
00021  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
00022  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
00023  * OR ANY PART THEREOF.
00024  *
00025  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
00026  * or profits or other special, indirect and consequential damages, even if
00027  * Sun has been advised of the possibility of such damages.
00028  *
00029  * Sun Microsystems, Inc.
00030  * 2550 Garcia Avenue
00031  * Mountain View, California  94043
00032  *
00033  *      from: @(#)pmap_rmt.h 1.2 88/02/08 SMI
00034  *      from: @(#)pmap_rmt.h    2.1 88/07/29 4.0 RPCSRC
00035  *      $Id: pmap_rmt.h,v 1.4 1996/01/30 23:32:12 mpp Exp $
00036  */
00037
00038 /*
00039  * Structures and XDR routines for parameters to and replies from
00040  * the portmapper remote-call-service.
00041  *
00042  * Copyright (C) 1986, Sun Microsystems, Inc.
00043  */
00044
00045 #ifndef __RPC_PMAP_REMOTE_H
00046 #define __RPC_PMAP_REMOTE_H
00047
00048 #include <sys/cdefs.h>
00049
00050 struct rmtcallargs {
00051        u_long    prog, vers, proc, arglen;
00052        caddr_t   args_ptr;
00053        xdrproc_t xdr_args;
00054      };
00055
00056 struct rmtcallres {
00057        u_long   *port_ptr;
00058        u_long    resultslen;
00059        caddr_t   results_ptr;
00060        xdrproc_t xdr_results;
00061      };
00062
00063 __BEGIN_DECLS
00064
00065 extern bool_t xdr_rmtcall_args (XDR *, struct rmtcallargs *);
00066 extern bool_t xdr_rmtcallres   (XDR *, struct rmtcallres *);
00067
00068 __END_DECLS
00069
00070 #endif
Generated on Wed Jan 25 15:42:33 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/rpc/RPC.H Source File

inc/rpc/RPC.H

Go to the documentation of this file.
00001
00005 /*
00006  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
00007  * unrestricted use provided that this legend is included on all tape
00008  * media and as a part of the software program in whole or part.  Users
00009  * may copy or modify Sun RPC without charge, but are not authorized
00010  * to license or distribute it to anyone else except as part of a product or
00011  * program developed by the user.
00012  *
00013  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
00014  * WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00015  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
00016  *
00017  * Sun RPC is provided with no support and without any obligation on the
00018  * part of Sun Microsystems, Inc. to assist in its use, correction,
00019  * modification or enhancement.
00020  *
00021  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
00022  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
00023  * OR ANY PART THEREOF.
00024  *
00025  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
00026  * or profits or other special, indirect and consequential damages, even if
00027  * Sun has been advised of the possibility of such damages.
00028  *
00029  * Sun Microsystems, Inc.
00030  * 2550 Garcia Avenue
00031  * Mountain View, California  94043
00032  *
00033  *      from: @(#)rpc.h 1.9 88/02/08 SMI
00034  *      from: @(#)rpc.h 2.4 89/07/11 4.0 RPCSRC
00035  *      $Id: rpc.h,v 1.5 1996/01/30 23:32:20 mpp Exp $
00036  */
00037
00038 /*
00039  * rpc.h, Just includes the billions of rpc header files necessary to
00040  * do remote procedure calling.
00041  *
00042  * Copyright (C) 1984, Sun Microsystems, Inc.
00043  */
00044 #ifndef __RPC_RPC_H
00045 #define __RPC_RPC_H
00046
00047 #include <rpc/types.h>          /* some typedefs */
00048
00049 /* external data representation interfaces */
00050 #include <rpc/xdr.h>            /* generic (de)serializer */
00051
00052 /* Client side only authentication */
00053 #include <rpc/auth.h>           /* generic authenticator (client side) */
00054
00055 /* Client side (mostly) remote procedure call */
00056 #include <rpc/clnt.h>           /* generic rpc stuff */
00057
00058 /* semi-private protocol headers */
00059 #include <rpc/rpc_msg.h>        /* protocol for rpc messages */
00060 #include <rpc/auth_uni.h>      /* protocol for unix style cred */
00061
00062 /*
00063  *  Uncomment-out the next line if you are building the rpc library with
00064  *  DES Authentication (see the README file in the secure_rpc/ directory).
00065  */
00066 #if 1
00067 #include <rpc/auth_des.h>       /* protocol for des style cred */
00068 #endif
00069
00070 /* Server side only remote procedure callee */
00071 #include <rpc/svc.h>            /* service manager and multiplexer */
00072 #include <rpc/svc_auth.h>       /* service side authenticator */
00073
00074 /*
00075  * COMMENT OUT THE NEXT INCLUDE (or add to the #ifndef) IF RUNNING ON
00076  * A VERSION OF UNIX THAT USES SUN'S NFS SOURCE.  These systems will
00077  * already have the structures defined by <rpc/netdb.h> included in <netdb.h>.
00078  */
00079 /* routines for parsing /etc/rpc */
00080
00081 struct rpcent {
00082       char    *r_name;        /* name of server for this rpc program */
00083       char    **r_aliases;    /* alias list */
00084       long    r_number;       /* rpc program number. */
00085 };                            /* Must be 32-bit for small/large model */
00086
00087 __BEGIN_DECLS
00088
00089 extern struct rpcent *getrpcbyname  (char *);
00090 extern struct rpcent *getrpcbynumber(long);
00091 extern struct rpcent *getrpcent     (void);
00092 extern void setrpcent (int);
00093 extern void endrpcent (void);
00094
00095 #if defined(__MSDOS__) || defined(__TURBOC__) || defined(__HIGHC__) || \
00096     defined(__DJGPP__) || defined(__WATCOMC__)
00097
00098   /* from RPC-DOS v0.1Alpha by Mike Durkin <mdurkin@tsoft.net> */
00099   /*                       updated by G.Vanem <giva@bgnett.no> */
00100
00101   extern void   rpc_init     (void);
00102   extern void   set_user_id  (u_long uid);
00103   extern void   set_group_id (u_long gid);
00104
00105   extern u_long __geteuid    (void);
00106   extern u_long __getegid    (void);
00107 #endif
00108
00109 __END_DECLS
00110
00111 #endif
Generated on Wed Jan 25 15:42:33 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/rpc/RPC_MSG.H Source File

inc/rpc/RPC_MSG.H

Go to the documentation of this file.
00001
00005 /*
00006  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
00007  * unrestricted use provided that this legend is included on all tape
00008  * media and as a part of the software program in whole or part.  Users
00009  * may copy or modify Sun RPC without charge, but are not authorized
00010  * to license or distribute it to anyone else except as part of a product or
00011  * program developed by the user.
00012  *
00013  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
00014  * WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00015  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
00016  *
00017  * Sun RPC is provided with no support and without any obligation on the
00018  * part of Sun Microsystems, Inc. to assist in its use, correction,
00019  * modification or enhancement.
00020  *
00021  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
00022  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
00023  * OR ANY PART THEREOF.
00024  *
00025  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
00026  * or profits or other special, indirect and consequential damages, even if
00027  * Sun has been advised of the possibility of such damages.
00028  *
00029  * Sun Microsystems, Inc.
00030  * 2550 Garcia Avenue
00031  * Mountain View, California  94043
00032  *
00033  *      from: @(#)rpc_msg.h 1.7 86/07/16 SMI
00034  *      from: @(#)rpc_msg.h     2.1 88/07/29 4.0 RPCSRC
00035  *      $Id: rpc_msg.h,v 1.5 1996/01/30 23:32:24 mpp Exp $
00036  */
00037
00038 /*
00039  * rpc_msg.h
00040  * rpc message definition
00041  *
00042  * Copyright (C) 1984, Sun Microsystems, Inc.
00043  */
00044
00045 #ifndef __RPC_RPC_MSG_H
00046 #define __RPC_RPCM_SG_H
00047
00048 #include <sys/cdefs.h>
00049
00050 #define RPC_MSG_VERSION    ((u_long) 2)
00051 #define RPC_SERVICE_PORT   ((u_short) 2048)
00052
00053 /*
00054  * Bottom up definition of an rpc message.
00055  * NOTE: call and reply use the same overall stuct but
00056  * different parts of unions within it.
00057  */
00058
00059 enum msg_type {
00060         CALL=0,
00061         REPLY=1
00062 };
00063
00064 enum reply_stat {
00065         MSG_ACCEPTED=0,
00066         MSG_DENIED=1
00067 };
00068
00069 enum accept_stat {
00070         SUCCESS=0,
00071         PROG_UNAVAIL=1,
00072         PROG_MISMATCH=2,
00073         PROC_UNAVAIL=3,
00074         GARBAGE_ARGS=4,
00075         SYSTEM_ERR=5
00076 };
00077
00078 enum reject_stat {
00079         RPC_MISMATCH=0,
00080         AUTH_ERROR=1
00081 };
00082
00083 /*
00084  * Reply part of an rpc exchange
00085  */
00086
00087 #include <sys/packon.h>
00088
00089 /*
00090  * Reply to an rpc request that was accepted by the server.
00091  * Note: there could be an error even though the request was
00092  * accepted.
00093  */
00094 struct accepted_reply {
00095         struct opaque_auth      ar_verf;
00096         enum accept_stat        ar_stat;
00097         union {
00098                 struct {
00099                         u_long  low;
00100                         u_long  high;
00101                 } AR_versions;
00102                 struct {
00103                         caddr_t where;
00104                         xdrproc_t proc;
00105                 } AR_results;
00106                 /* and many other null cases */
00107         } ru;
00108 #define ar_results      ru.AR_results
00109 #define ar_vers         ru.AR_versions
00110 };
00111
00112 /*
00113  * Reply to an rpc request that was rejected by the server.
00114  */
00115 struct rejected_reply {
00116         enum reject_stat rj_stat;
00117         union {
00118                 struct {
00119                         u_long low;
00120                         u_long high;
00121                 } RJ_versions;
00122                 enum auth_stat RJ_why;  /* why authentication did not work */
00123         } ru;
00124 #define rj_vers ru.RJ_versions
00125 #define rj_why  ru.RJ_why
00126 };
00127
00128 /*
00129  * Body of a reply to an rpc request.
00130  */
00131 struct reply_body {
00132         enum reply_stat rp_stat;
00133         union {
00134                 struct accepted_reply RP_ar;
00135                 struct rejected_reply RP_dr;
00136         } ru;
00137 #define rp_acpt ru.RP_ar
00138 #define rp_rjct ru.RP_dr
00139 };
00140
00141 /*
00142  * Body of an rpc request call.
00143  */
00144 struct call_body {
00145         u_long cb_rpcvers;      /* must be equal to two */
00146         u_long cb_prog;
00147         u_long cb_vers;
00148         u_long cb_proc;
00149         struct opaque_auth cb_cred;
00150         struct opaque_auth cb_verf; /* protocol specific - provided by client */
00151 };
00152
00153 /*
00154  * The rpc message
00155  */
00156 struct rpc_msg {
00157         u_long                  rm_xid;
00158         enum msg_type           rm_direction;
00159         union {
00160                 struct call_body RM_cmb;
00161                 struct reply_body RM_rmb;
00162         } ru;
00163 #define rm_call         ru.RM_cmb
00164 #define rm_reply        ru.RM_rmb
00165 };
00166 #define acpted_rply     ru.RM_rmb.ru.RP_ar
00167 #define rjcted_rply     ru.RM_rmb.ru.RP_dr
00168
00169 #include <sys/packoff.h>
00170
00171 __BEGIN_DECLS
00172
00173 /*
00174  * XDR routine to handle a rpc message.
00175  * xdr_callmsg(xdrs, cmsg)
00176  *      XDR *xdrs;
00177  *      struct rpc_msg *cmsg;
00178  */
00179 extern bool_t xdr_callmsg (XDR *, struct rpc_msg *);
00180
00181 /*
00182  * XDR routine to pre-serialize the static part of a rpc message.
00183  * xdr_callhdr(xdrs, cmsg)
00184  *      XDR *xdrs;
00185  *      struct rpc_msg *cmsg;
00186  */
00187 extern bool_t xdr_callhdr (XDR *, struct rpc_msg *);
00188
00189 /*
00190  * XDR routine to handle a rpc reply.
00191  * xdr_replymsg(xdrs, rmsg)
00192  *      XDR *xdrs;
00193  *      struct rpc_msg *rmsg;
00194  */
00195 extern bool_t xdr_replymsg (XDR *, struct rpc_msg *);
00196
00197 /*
00198  * Fills in the error part of a reply message.
00199  * _seterr_reply(msg, error)
00200  *      struct rpc_msg *msg;
00201  *      struct rpc_err *error;
00202  */
00203 struct rpc_err;
00204 extern void _seterr_reply (struct rpc_msg *, struct rpc_err *);
00205
00206 __END_DECLS
00207
00208 #endif
Generated on Wed Jan 25 15:42:33 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/rpc/SVC.H Source File

inc/rpc/SVC.H

Go to the documentation of this file.
00001
00005 /*
00006  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
00007  * unrestricted use provided that this legend is included on all tape
00008  * media and as a part of the software program in whole or part.  Users
00009  * may copy or modify Sun RPC without charge, but are not authorized
00010  * to license or distribute it to anyone else except as part of a product or
00011  * program developed by the user.
00012  *
00013  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
00014  * WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00015  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
00016  *
00017  * Sun RPC is provided with no support and without any obligation on the
00018  * part of Sun Microsystems, Inc. to assist in its use, correction,
00019  * modification or enhancement.
00020  *
00021  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
00022  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
00023  * OR ANY PART THEREOF.
00024  *
00025  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
00026  * or profits or other special, indirect and consequential damages, even if
00027  * Sun has been advised of the possibility of such damages.
00028  *
00029  * Sun Microsystems, Inc.
00030  * 2550 Garcia Avenue
00031  * Mountain View, California  94043
00032  *
00033  *      from: @(#)svc.h 1.20 88/02/08 SMI
00034  *      from: @(#)svc.h 2.2 88/07/29 4.0 RPCSRC
00035  *      $Id: svc.h,v 1.5 1996/01/30 23:32:29 mpp Exp $
00036  */
00037
00038 /*
00039  * svc.h, Server-side remote procedure call interface.
00040  *
00041  * Copyright (C) 1984, Sun Microsystems, Inc.
00042  */
00043
00044 #ifndef __RPC_SVC_H
00045 #define __RPC_SVC_H
00046
00047 #ifndef __SYS_CDEFS_H
00048 #include <sys/cdefs.h>
00049 #endif
00050
00051 /*
00052  * This interface must manage two items concerning remote procedure calling:
00053  *
00054  * 1) An arbitrary number of transport connections upon which rpc requests
00055  * are received.  The two most notable transports are TCP and UDP;  they are
00056  * created and registered by routines in svc_tcp.c and svc_udp.c, respectively;
00057  * they in turn call xprt_register and xprt_unregister.
00058  *
00059  * 2) An arbitrary number of locally registered services.  Services are
00060  * described by the following four data: program number, version number,
00061  * "service dispatch" function, a transport handle, and a boolean that
00062  * indicates whether or not the exported program should be registered with a
00063  * local binder service;  if true the program's number and version and the
00064  * port number from the transport handle are registered with the binder.
00065  * These data are registered with the rpc svc system via svc_register.
00066  *
00067  * A service's dispatch function is called whenever an rpc request comes in
00068  * on a transport.  The request's program and version numbers must match
00069  * those of the registered service.  The dispatch function is passed two
00070  * parameters, struct svc_req * and SVCXPRT *, defined below.
00071  */
00072
00073 enum xprt_stat {
00074         XPRT_DIED,
00075         XPRT_MOREREQS,
00076         XPRT_IDLE
00077 };
00078
00079 /*
00080  * Server side transport handle
00081  */
00082 typedef struct {
00083         int             xp_sock;
00084         u_short         xp_port;         /* associated port number */
00085         struct xp_ops {
00086             bool_t      (*xp_recv)();    /* receive incoming requests */
00087             enum xprt_stat (*xp_stat)(); /* get transport status */
00088             bool_t      (*xp_getargs)(); /* get arguments */
00089             bool_t      (*xp_reply)();   /* send reply */
00090             bool_t      (*xp_freeargs)();/* free mem allocated for args */
00091             void        (*xp_destroy)(); /* destroy this struct */
00092         } *xp_ops;
00093         int             xp_addrlen;      /* length of remote address */
00094         struct sockaddr_in xp_raddr;     /* remote address */
00095         struct opaque_auth xp_verf;      /* raw response verifier */
00096         caddr_t         xp_p1;           /* private */
00097         caddr_t         xp_p2;           /* private */
00098 } SVCXPRT;
00099
00100 /*
00101  *  Approved way of getting address of caller
00102  */
00103 #define svc_getcaller(x) (&(x)->xp_raddr)
00104
00105 /*
00106  * Operations defined on an SVCXPRT handle
00107  *
00108  * SVCXPRT              *xprt;
00109  * struct rpc_msg       *msg;
00110  * xdrproc_t             xargs;
00111  * caddr_t               argsp;
00112  */
00113 #define SVC_RECV(xprt, msg)                             \
00114         (*(xprt)->xp_ops->xp_recv)((xprt), (msg))
00115 #define svc_recv(xprt, msg)                             \
00116         (*(xprt)->xp_ops->xp_recv)((xprt), (msg))
00117
00118 #define SVC_STAT(xprt)                                  \
00119         (*(xprt)->xp_ops->xp_stat)(xprt)
00120 #define svc_stat(xprt)                                  \
00121         (*(xprt)->xp_ops->xp_stat)(xprt)
00122
00123 #define SVC_GETARGS(xprt, xargs, argsp)                 \
00124         (*(xprt)->xp_ops->xp_getargs)((xprt), (xargs), (argsp))
00125 #define svc_getargs(xprt, xargs, argsp)                 \
00126         (*(xprt)->xp_ops->xp_getargs)((xprt), (xargs), (argsp))
00127
00128 #define SVC_REPLY(xprt, msg)                            \
00129         (*(xprt)->xp_ops->xp_reply) ((xprt), (msg))
00130 #define svc_reply(xprt, msg)                            \
00131         (*(xprt)->xp_ops->xp_reply) ((xprt), (msg))
00132
00133 #define SVC_FREEARGS(xprt, xargs, argsp)                \
00134         (*(xprt)->xp_ops->xp_freeargs)((xprt), (xargs), (argsp))
00135 #define svc_freeargs(xprt, xargs, argsp)                \
00136         (*(xprt)->xp_ops->xp_freeargs)((xprt), (xargs), (argsp))
00137
00138 #define SVC_DESTROY(xprt)                               \
00139         (*(xprt)->xp_ops->xp_destroy)(xprt)
00140 #define svc_destroy(xprt)                               \
00141         (*(xprt)->xp_ops->xp_destroy)(xprt)
00142
00143
00144 /*
00145  * Service request
00146  */
00147 struct svc_req {
00148         u_long          rq_prog;        /* service program number */
00149         u_long          rq_vers;        /* service protocol version */
00150         u_long          rq_proc;        /* the desired procedure */
00151         struct opaque_auth rq_cred;     /* raw creds from the wire */
00152         caddr_t         rq_clntcred;    /* read only cooked cred */
00153         SVCXPRT *rq_xprt;               /* associated transport */
00154 };
00155
00156 __BEGIN_DECLS
00157
00158 /*
00159  * Service registration
00160  *
00161  * svc_register(xprt, prog, vers, dispatch, protocol)
00162  *      SVCXPRT *xprt;
00163  *      u_long prog;
00164  *      u_long vers;
00165  *      void (*dispatch)();
00166  *      int protocol;        // like TCP or UDP, zero means do not register
00167  */
00168 extern bool_t  svc_register (SVCXPRT *, u_long, u_long, void (*)(), int);
00169
00170 /*
00171  * Service un-registration
00172  *
00173  * svc_unregister(prog, vers)
00174  *      u_long prog;
00175  *      u_long vers;
00176  */
00177 extern void svc_unregister (u_long, u_long);
00178
00179 /*
00180  * Transport registration.
00181  *
00182  * xprt_register(xprt)
00183  *      SVCXPRT *xprt;
00184  */
00185 extern void xprt_register (SVCXPRT *);
00186
00187 /*
00188  * Transport un-register
00189  *
00190  * xprt_unregister(xprt)
00191  *      SVCXPRT *xprt;
00192  */
00193 extern void xprt_unregister (SVCXPRT *);
00194
00195
00196
00197 /*
00198  * When the service routine is called, it must first check to see if it
00199  * knows about the procedure;  if not, it should call svcerr_noproc
00200  * and return.  If so, it should deserialize its arguments via
00201  * SVC_GETARGS (defined above).  If the deserialization does not work,
00202  * svcerr_decode should be called followed by a return.  Successful
00203  * decoding of the arguments should be followed the execution of the
00204  * procedure's code and a call to svc_sendreply.
00205  *
00206  * Also, if the service refuses to execute the procedure due to too-
00207  * weak authentication parameters, svcerr_weakauth should be called.
00208  * Note: do not confuse access-control failure with weak authentication!
00209  *
00210  * NB: In pure implementations of rpc, the caller always waits for a reply
00211  * msg.  This message is sent when svc_sendreply is called.
00212  * Therefore pure service implementations should always call
00213  * svc_sendreply even if the function logically returns void;  use
00214  * xdr.h - xdr_void for the xdr routine.  HOWEVER, tcp based rpc allows
00215  * for the abuse of pure rpc via batched calling or pipelining.  In the
00216  * case of a batched call, svc_sendreply should NOT be called since
00217  * this would send a return message, which is what batching tries to avoid.
00218  * It is the service/protocol writer's responsibility to know which calls are
00219  * batched and which are not.  Warning: responding to batch calls may
00220  * deadlock the caller and server processes!
00221  */
00222
00223 extern bool_t svc_sendreply   (SVCXPRT *, xdrproc_t, char *);
00224 extern void   svcerr_decode   (SVCXPRT *);
00225 extern void   svcerr_weakauth (SVCXPRT *);
00226 extern void   svcerr_noproc   (SVCXPRT *);
00227 extern void   svcerr_progvers (SVCXPRT *, u_long, u_long);
00228 extern void   svcerr_auth     (SVCXPRT *, enum auth_stat);
00229 extern void   svcerr_noprog   (SVCXPRT *);
00230 extern void   svcerr_systemerr(SVCXPRT *);
00231
00232 /*
00233  * Lowest level dispatching -OR- who owns this process anyway.
00234  * Somebody has to wait for incoming requests and then call the correct
00235  * service routine.  The routine svc_run does infinite waiting; i.e.,
00236  * svc_run never returns.
00237  * Since another (co-existant) package may wish to selectively wait for
00238  * incoming calls or other events outside of the rpc architecture, the
00239  * routine svc_getreq is provided.  It must be passed readfds, the
00240  * "in-place" results of a select system call (see select, section 2).
00241  */
00242
00243 /*
00244  * Global keeper of rpc service descriptors in use
00245  * dynamic; must be inspected before each call to select
00246  */
00247 #ifdef FD_SETSIZE
00248   extern void   svc_getreqset (fd_set *);
00249   extern fd_set svc_fdset;
00250   #define svc_fds svc_fdset.fds_bits[0]   /* compatibility */
00251 #else
00252   extern int svc_fds;
00253 #endif
00254
00255 /*
00256  * a small program implemented by the svc_rpc implementation itself;
00257  * also see clnt.h for protocol numbers.
00258  */
00259 extern void rpctest_service();
00260 extern void svc_getreq  (int);
00261 extern void svc_run     (void);
00262
00263 /*
00264  * Socket to use on svcxxx_create call to get default socket
00265  */
00266 #define RPC_ANYSOCK     -1
00267
00268 /*
00269  * These are the existing service side transport implementations
00270  */
00271
00272 /*
00273  * Memory based rpc for testing and timing.
00274  */
00275 extern SVCXPRT *svcraw_create (void);
00276
00277
00278 /*
00279  * Udp based rpc.
00280  */
00281 extern SVCXPRT *svcudp_create (int);
00282 extern SVCXPRT *svcudp_bufcreate (int, u_int, u_int);
00283
00284 /*
00285  * Tcp based rpc.
00286  */
00287 extern SVCXPRT *svctcp_create (int, u_int, u_int);
00288
00289 __END_DECLS
00290
00291 #endif
Generated on Wed Jan 25 15:42:33 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/rpc/SVC_AUTH.H Source File

inc/rpc/SVC_AUTH.H

Go to the documentation of this file.
00001
00005 /*
00006  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
00007  * unrestricted use provided that this legend is included on all tape
00008  * media and as a part of the software program in whole or part.  Users
00009  * may copy or modify Sun RPC without charge, but are not authorized
00010  * to license or distribute it to anyone else except as part of a product or
00011  * program developed by the user.
00012  *
00013  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
00014  * WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00015  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
00016  *
00017  * Sun RPC is provided with no support and without any obligation on the
00018  * part of Sun Microsystems, Inc. to assist in its use, correction,
00019  * modification or enhancement.
00020  *
00021  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
00022  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
00023  * OR ANY PART THEREOF.
00024  *
00025  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
00026  * or profits or other special, indirect and consequential damages, even if
00027  * Sun has been advised of the possibility of such damages.
00028  *
00029  * Sun Microsystems, Inc.
00030  * 2550 Garcia Avenue
00031  * Mountain View, California  94043
00032  *
00033  *      from: @(#)svc_auth.h 1.6 86/07/16 SMI
00034  *      from: @(#)svc_auth.h    2.1 88/07/29 4.0 RPCSRC
00035  *      $Id: svc_auth.h,v 1.4 1996/01/30 23:32:36 mpp Exp $
00036  */
00037
00038 /*
00039  * svc_auth.h, Service side of rpc authentication.
00040  *
00041  * Copyright (C) 1984, Sun Microsystems, Inc.
00042  */
00043
00044 #ifndef __RPC_SVC_AUTH_H
00045 #define __RPC_SVC_AUTH_H
00046
00047 /*
00048  * Server side authenticator
00049  */
00050 __BEGIN_DECLS
00051
00052 extern enum auth_stat _authenticate (struct svc_req *, struct rpc_msg *);
00053
00054 __END_DECLS
00055
00056 #endif
Generated on Wed Jan 25 15:42:33 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/rpc/TYPES.H Source File

inc/rpc/TYPES.H

Go to the documentation of this file.
00001
00005 /*
00006  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
00007  * unrestricted use provided that this legend is included on all tape
00008  * media and as a part of the software program in whole or part.  Users
00009  * may copy or modify Sun RPC without charge, but are not authorized
00010  * to license or distribute it to anyone else except as part of a product or
00011  * program developed by the user.
00012  *
00013  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
00014  * WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00015  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
00016  *
00017  * Sun RPC is provided with no support and without any obligation on the
00018  * part of Sun Microsystems, Inc. to assist in its use, correction,
00019  * modification or enhancement.
00020  *
00021  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
00022  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
00023  * OR ANY PART THEREOF.
00024  *
00025  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
00026  * or profits or other special, indirect and consequential damages, even if
00027  * Sun has been advised of the possibility of such damages.
00028  *
00029  * Sun Microsystems, Inc.
00030  * 2550 Garcia Avenue
00031  * Mountain View, California  94043
00032  *
00033  *      from: @(#)types.h 1.18 87/07/24 SMI
00034  *      from: @(#)types.h       2.3 88/08/15 4.0 RPCSRC
00035  *      $Id: types.h,v 1.4 1996/01/30 23:32:39 mpp Exp $
00036  */
00037
00038 /*
00039  * Rpc additions to <sys/wtypes.h>
00040  */
00041 #ifndef __RPC_TYPES_H
00042 #define __RPC_TYPES_H
00043
00044 #define bool_t  int
00045 #define enum_t  int
00046 #define __dontcare__    -1
00047
00048 #ifndef FALSE
00049 #       define FALSE    (0)
00050 #endif
00051 #ifndef TRUE
00052 #       define TRUE     (1)
00053 #endif
00054
00055 #define mem_alloc(bsize)        malloc(bsize)
00056 #define mem_free(ptr, bsize)    free(ptr)
00057
00058 #include <sys/wtypes.h>
00059 #include <sys/wtime.h>
00060 #include <netinet/in.h>
00061
00062 #ifndef INADDR_LOOPBACK
00063 #define INADDR_LOOPBACK         (u_long)0x7F000001
00064 #endif
00065
00066 #ifndef MAXHOSTNAMELEN
00067 #define MAXHOSTNAMELEN          64
00068 #endif
00069
00070 #endif
Generated on Wed Jan 25 15:42:33 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/rpc/XDR.H Source File

inc/rpc/XDR.H

Go to the documentation of this file.
00001
00005 /*
00006  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
00007  * unrestricted use provided that this legend is included on all tape
00008  * media and as a part of the software program in whole or part.  Users
00009  * may copy or modify Sun RPC without charge, but are not authorized
00010  * to license or distribute it to anyone else except as part of a product or
00011  * program developed by the user.
00012  *
00013  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
00014  * WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00015  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
00016  *
00017  * Sun RPC is provided with no support and without any obligation on the
00018  * part of Sun Microsystems, Inc. to assist in its use, correction,
00019  * modification or enhancement.
00020  *
00021  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
00022  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
00023  * OR ANY PART THEREOF.
00024  *
00025  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
00026  * or profits or other special, indirect and consequential damages, even if
00027  * Sun has been advised of the possibility of such damages.
00028  *
00029  * Sun Microsystems, Inc.
00030  * 2550 Garcia Avenue
00031  * Mountain View, California  94043
00032  *
00033  *      from: @(#)xdr.h 1.19 87/04/22 SMI
00034  *      from: @(#)xdr.h 2.2 88/07/29 4.0 RPCSRC
00035  *      $Id: xdr.h,v 1.4 1996/01/30 23:32:45 mpp Exp $
00036  */
00037
00038 /*
00039  * xdr.h, External Data Representation Serialization Routines.
00040  *
00041  * Copyright (C) 1984, Sun Microsystems, Inc.
00042  */
00043
00044 #ifndef __RPC_XDR_H
00045 #define __RPC_XDR_H
00046
00047 #ifndef __SYS_CDEFS_H
00048 #include <sys/cdefs.h>
00049 #endif
00050
00051 /*
00052  * XDR provides a conventional way for converting between C data
00053  * types and an external bit-string representation.  Library supplied
00054  * routines provide for the conversion on built-in C data types.  These
00055  * routines and utility routines defined here are used to help implement
00056  * a type encode/decode routine for each user-defined type.
00057  *
00058  * Each data type provides a single procedure which takes two arguments:
00059  *
00060  *      bool_t
00061  *      xdrproc(xdrs, argresp)
00062  *              XDR *xdrs;
00063  *              <type> *argresp;
00064  *
00065  * xdrs is an instance of a XDR handle, to which or from which the data
00066  * type is to be converted.  argresp is a pointer to the structure to be
00067  * converted.  The XDR handle contains an operation field which indicates
00068  * which of the operations (ENCODE, DECODE * or FREE) is to be performed.
00069  *
00070  * XDR_DECODE may allocate space if the pointer argresp is null.  This
00071  * data can be freed with the XDR_FREE operation.
00072  *
00073  * We write only one procedure per data type to make it easy
00074  * to keep the encode and decode procedures for a data type consistent.
00075  * In many cases the same code performs all operations on a user defined type,
00076  * because all the hard work is done in the component type routines.
00077  * decode as a series of calls on the nested data types.
00078  */
00079
00080 /*
00081  * Xdr operations.  XDR_ENCODE causes the type to be encoded into the
00082  * stream.  XDR_DECODE causes the type to be extracted from the stream.
00083  * XDR_FREE can be used to release the space allocated by an XDR_DECODE
00084  * request.
00085  */
00086 enum xdr_op {
00087      XDR_ENCODE = 0,
00088      XDR_DECODE = 1,
00089      XDR_FREE   = 2
00090    };
00091
00092 /*
00093  * This is the number of bytes per unit of external data.
00094  */
00095 #define BYTES_PER_XDR_UNIT      (4)
00096 #define RNDUP(x)  ((((x) + BYTES_PER_XDR_UNIT - 1) / BYTES_PER_XDR_UNIT) \
00097                     * BYTES_PER_XDR_UNIT)
00098
00099 /*
00100  * A xdrproc_t exists for each data type which is to be encoded or decoded.
00101  *
00102  * The second argument to the xdrproc_t is a pointer to an opaque pointer.
00103  * The opaque pointer generally points to a structure of the data type
00104  * to be decoded.  If this pointer is 0, then the type routines should
00105  * allocate dynamic storage of the appropriate size and return it.
00106  * bool_t       (*xdrproc_t)(XDR *, caddr_t *);
00107  */
00108 typedef bool_t (*xdrproc_t)();
00109
00110 /*
00111  * The XDR handle.
00112  * Contains operation which is being applied to the stream,
00113  * an operations vector for the particular implementation (e.g. see xdr_mem.c),
00114  * and two private fields for the use of the particular implementation.
00115  */
00116 typedef struct {
00117         enum xdr_op     x_op;           /* operation; fast additional param */
00118         struct xdr_ops {
00119                 bool_t  (*x_getlong)(); /* get a long from underlying stream */
00120                 bool_t  (*x_putlong)(); /* put a long to " */
00121                 bool_t  (*x_getbytes)();/* get some bytes from " */
00122                 bool_t  (*x_putbytes)();/* put some bytes to " */
00123                 u_int   (*x_getpostn)();/* returns bytes off from beginning */
00124                 bool_t  (*x_setpostn)();/* lets you reposition the stream */
00125                 long *  (*x_inline)();  /* buf quick ptr to buffered data */
00126                 void    (*x_destroy)(); /* free privates of this xdr_stream */
00127         } *x_ops;
00128         caddr_t         x_public;       /* users' data */
00129         caddr_t         x_private;      /* pointer to private data */
00130         caddr_t         x_base;         /* private used for position info */
00131         int             x_handy;        /* extra private word */
00132 } XDR;
00133
00134 /*
00135  * Operations defined on a XDR handle
00136  *
00137  * XDR          *xdrs;
00138  * long         *longp;
00139  * caddr_t       addr;
00140  * u_int         len;
00141  * u_int         pos;
00142  */
00143 #define XDR_GETLONG(xdrs, longp)                        \
00144         (*(xdrs)->x_ops->x_getlong)(xdrs, longp)
00145 #define xdr_getlong(xdrs, longp)                        \
00146         (*(xdrs)->x_ops->x_getlong)(xdrs, longp)
00147
00148 #define XDR_PUTLONG(xdrs, longp)                        \
00149         (*(xdrs)->x_ops->x_putlong)(xdrs, longp)
00150 #define xdr_putlong(xdrs, longp)                        \
00151         (*(xdrs)->x_ops->x_putlong)(xdrs, longp)
00152
00153 #define XDR_GETBYTES(xdrs, addr, len)                   \
00154         (*(xdrs)->x_ops->x_getbytes)(xdrs, addr, len)
00155 #define xdr_getbytes(xdrs, addr, len)                   \
00156         (*(xdrs)->x_ops->x_getbytes)(xdrs, addr, len)
00157
00158 #define XDR_PUTBYTES(xdrs, addr, len)                   \
00159         (*(xdrs)->x_ops->x_putbytes)(xdrs, addr, len)
00160 #define xdr_putbytes(xdrs, addr, len)                   \
00161         (*(xdrs)->x_ops->x_putbytes)(xdrs, addr, len)
00162
00163 #define XDR_GETPOS(xdrs)                                \
00164         (*(xdrs)->x_ops->x_getpostn)(xdrs)
00165 #define xdr_getpos(xdrs)                                \
00166         (*(xdrs)->x_ops->x_getpostn)(xdrs)
00167
00168 #define XDR_SETPOS(xdrs, pos)                           \
00169         (*(xdrs)->x_ops->x_setpostn)(xdrs, pos)
00170 #define xdr_setpos(xdrs, pos)                           \
00171         (*(xdrs)->x_ops->x_setpostn)(xdrs, pos)
00172
00173 #define XDR_INLINE(xdrs, len)                           \
00174         (*(xdrs)->x_ops->x_inline)(xdrs, len)
00175 #define xdr_inline(xdrs, len)                           \
00176         (*(xdrs)->x_ops->x_inline)(xdrs, len)
00177
00178 #define XDR_DESTROY(xdrs)                               \
00179         if ((xdrs)->x_ops->x_destroy)                   \
00180                 (*(xdrs)->x_ops->x_destroy)(xdrs)
00181 #define xdr_destroy(xdrs)                               \
00182         if ((xdrs)->x_ops->x_destroy)                   \
00183                 (*(xdrs)->x_ops->x_destroy)(xdrs)
00184
00185 /*
00186  * Support struct for discriminated unions.
00187  * You create an array of xdrdiscrim structures, terminated with
00188  * a entry with a null procedure pointer.  The xdr_union routine gets
00189  * the discriminant value and then searches the array of structures
00190  * for a matching value.  If a match is found the associated xdr routine
00191  * is called to handle that part of the union.  If there is
00192  * no match, then a default routine may be called.
00193  * If there is no match and no default routine it is an error.
00194  */
00195 #define NULL_xdrproc_t ((xdrproc_t)0L)
00196 struct xdr_discrim {
00197         int     value;
00198         xdrproc_t proc;
00199 };
00200
00201 /*
00202  * In-line routines for fast encode/decode of primitive data types.
00203  * Caveat emptor: these use single memory cycles to get the
00204  * data from the underlying buffer, and will fail to operate
00205  * properly if the data is not aligned.  The standard way to use these
00206  * is to say:
00207  *      if ((buf = XDR_INLINE(xdrs, count)) == NULL)
00208  *              return (FALSE);
00209  *      <<< macro calls >>>
00210  * where ``count'' is the number of bytes of data occupied
00211  * by the primitive data types.
00212  *
00213  * N.B. and frozen for all time: each data type here uses 4 bytes
00214  * of external representation.
00215  */
00216 #define IXDR_GET_LONG(buf)         ((long)ntohl((u_long)*(buf)++))
00217 #define IXDR_PUT_LONG(buf, v)      (*(buf)++ = (long)htonl((u_long)v))
00218
00219 #define IXDR_GET_BOOL(buf)         ((bool_t)IXDR_GET_LONG(buf))
00220 #define IXDR_GET_ENUM(buf, t)      ((t)IXDR_GET_LONG(buf))
00221 #define IXDR_GET_U_LONG(buf)       ((u_long)IXDR_GET_LONG(buf))
00222 #define IXDR_GET_SHORT(buf)        ((short)IXDR_GET_LONG(buf))
00223 #define IXDR_GET_U_SHORT(buf)      ((u_short)IXDR_GET_LONG(buf))
00224
00225 #define IXDR_PUT_BOOL(buf, v)      IXDR_PUT_LONG((buf), ((long)(v)))
00226 #define IXDR_PUT_ENUM(buf, v)      IXDR_PUT_LONG((buf), ((long)(v)))
00227 #define IXDR_PUT_U_LONG(buf, v)    IXDR_PUT_LONG((buf), ((long)(v)))
00228 #define IXDR_PUT_SHORT(buf, v)     IXDR_PUT_LONG((buf), ((long)(v)))
00229 #define IXDR_PUT_U_SHORT(buf, v)   IXDR_PUT_LONG((buf), ((long)(v)))
00230
00231 /*
00232  * These are the "generic" xdr routines.
00233  */
00234
00235 __BEGIN_DECLS
00236
00237 extern bool_t   xdr_void       (XDR *, caddr_t);
00238 extern bool_t   xdr_int        (XDR *, int *);
00239 extern bool_t   xdr_u_int      (XDR *, u_int *);
00240 extern bool_t   xdr_long       (XDR *, long *);
00241 extern bool_t   xdr_u_long     (XDR *, u_long *);
00242 extern bool_t   xdr_short      (XDR *, short *);
00243 extern bool_t   xdr_u_short    (XDR *, u_short *);
00244 extern bool_t   xdr_bool       (XDR *, bool_t *);
00245 extern bool_t   xdr_enum       (XDR *, enum_t *);
00246 extern bool_t   xdr_array      (XDR *, char **, u_int *, u_int, u_int, xdrproc_t);
00247 extern bool_t   xdr_bytes      (XDR *, char **, u_int *, u_int);
00248 extern bool_t __xdr_opaque     (XDR *, caddr_t, u_int);
00249 extern bool_t   xdr_string     (XDR *, char **, u_int);
00250 extern bool_t   xdr_union      (XDR *, enum_t *, char *, struct xdr_discrim *, xdrproc_t);
00251 extern bool_t   xdr_char       (XDR *, char *);
00252 extern bool_t   xdr_u_char     (XDR *, char *);
00253 extern bool_t   xdr_vector     (XDR *, char *, u_int, u_int, xdrproc_t);
00254 extern bool_t   xdr_float      (XDR *, float *);
00255 extern bool_t   xdr_double     (XDR *, double *);
00256 extern bool_t   xdr_reference  (XDR *, caddr_t *, u_int, xdrproc_t);
00257 extern bool_t   xdr_pointer    (XDR *, caddr_t *, u_int, xdrproc_t);
00258 extern bool_t   xdr_wrapstring (XDR *, char **);
00259 extern void     xdr_free       (xdrproc_t, char *);
00260
00261 /*
00262  * Hack to avoid missing typecast from rpcgen when
00263  * producing xdr_opaque()
00264  */
00265 #define xdr_opaque(xdr,obj,size) __xdr_opaque(xdr,(caddr_t)obj,size)
00266
00267 __END_DECLS
00268
00269 /*
00270  * Common opaque bytes objects used by many rpc protocols;
00271  * declared here due to commonality.
00272  */
00273 #define MAX_NETOBJ_SZ 1024
00274 struct netobj {
00275         u_int   n_len;
00276         char    *n_bytes;
00277 };
00278 typedef struct netobj netobj;
00279
00280 /*
00281  * These are the public routines for the various implementations of
00282  * xdr streams.
00283  */
00284
00285 __BEGIN_DECLS
00286
00287 extern bool_t xdr_netobj (XDR *, struct netobj *);
00288
00289 /* XDR using memory buffers */
00290 extern void xdrmem_create (XDR *, char *, u_int, enum xdr_op);
00291
00292 #if defined(__STDIO_H) || defined(_STDIO_H) || defined(__dj_include_stdio_h_)
00293 /* XDR using stdio library */
00294 extern void xdrstdio_create (XDR *, FILE *, enum xdr_op);
00295 #endif
00296
00297 /* XDR pseudo records for tcp */
00298 extern void xdrrec_create (XDR *, u_int, u_int, char *, int (*)(), int (*)());
00299
00300 /* make end of xdr record */
00301 extern bool_t xdrrec_endofrecord (XDR *, int);
00302
00303 /* move to beginning of next record */
00304 extern bool_t xdrrec_skiprecord (XDR *);
00305
00306 /* true if no more input */
00307 extern bool_t xdrrec_eof (XDR *);
00308
00309 __END_DECLS
00310
00311 #endif
Generated on Wed Jan 25 15:42:33 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/rpcsvc/YP_PROT.H Source File

inc/rpcsvc/YP_PROT.H

Go to the documentation of this file.
00001
00005 /*
00006  * Copyright (c) 1992/3 Theo de Raadt <deraadt@fsa.ca>
00007  * All rights reserved.
00008  *
00009  * Redistribution and use in source and binary forms, with or without
00010  * modification, are permitted provided that the following conditions
00011  * are met:
00012  * 1. Redistributions of source code must retain the above copyright
00013  *    notice, this list of conditions and the following disclaimer.
00014  * 2. Redistributions in binary form must reproduce the above copyright
00015  *    notice, this list of conditions and the following disclaimer in the
00016  *    documentation and/or other materials provided with the distribution.
00017  * 3. The name of the author may not be used to endorse or promote
00018  *    products derived from this software without specific prior written
00019  *    permission.
00020  *
00021  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
00022  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00023  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00024  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
00025  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00026  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00027  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00028  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00029  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00030  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00031  * SUCH DAMAGE.
00032  *
00033  *      $Id: yp_prot.h,v 1.3 1996/01/30 23:33:04 mpp Exp $
00034  */
00035
00036 #ifndef __RPCSVC_YP_PROT_H
00037 #define __RPCSVC_YP_PROT_H
00038
00039 /*
00040  * YPSERV PROTOCOL:
00041  *
00042  * ypserv supports the following procedures:
00043  *
00044  * YPPROC_NULL          takes (void), returns (void).
00045  *                      called to check if server is alive.
00046  * YPPROC_DOMAIN        takes (char *), returns (bool_t).
00047  *                      true if ypserv serves the named domain.
00048  * YPPROC_DOMAIN_NOACK  takes (char *), returns (bool_t).
00049  *                      true if ypserv serves the named domain.
00050  *                      used for broadcasts, does not ack if ypserv
00051  *                      doesn't handle named domain.
00052  * YPPROC_MATCH         takes (struct ypreq_key), returns (struct ypresp_val)
00053  *                      does a lookup.
00054  * YPPROC_FIRST         takes (struct ypreq_nokey) returns (ypresp_key_val).
00055  *                      gets the first key/datum from the map.
00056  * YPPROC_NEXT          takes (struct ypreq_key) returns (ypresp_key_val).
00057  *                      gets the next key/datum from the map.
00058  * YPPROC_XFR           takes (struct ypreq_xfr), returns (void).
00059  *                      tells ypserv to check if there is a new version of
00060  *                      the map.
00061  * YPPROC_CLEAR         takes (void), returns (void).
00062  *                      tells ypserv to flush it's file cache, so that
00063  *                      newly transferred files will get read.
00064  * YPPROC_ALL           takes (struct ypreq_nokey), returns (bool_t and
00065  *                      struct ypresp_key_val).
00066  *                      returns an array of data, with the bool_t being
00067  *                      false on the last datum. read the source, it's
00068  *                      convoluted.
00069  * YPPROC_MASTER        takes (struct ypreq_nokey), returns (ypresp_master).
00070  * YPPROC_ORDER         takes (struct ypreq_nokey), returns (ypresp_order).
00071  * YPPROC_MAPLIST       takes (char *), returns (struct ypmaplist *).
00072  */
00073
00074 #ifndef BOOL_DEFINED
00075 typedef u_int bool;
00076 #define BOOL_DEFINED
00077 #endif
00078
00079 bool_t  xdr_datum();
00080 bool_t  xdr_ypdomain_wrap_string();
00081 bool_t  xdr_ypmap_wrap_string();
00082 bool_t  xdr_ypreq_key();
00083 bool_t  xdr_ypreq_nokey();
00084 bool_t  xdr_ypreq_xfr();
00085 bool_t  xdr_ypresp_val();
00086 bool_t  xdr_ypresp_key_val();
00087 bool_t  xdr_ypbind_resp();
00088 bool_t  xdr_ypbind_setdom();
00089 bool_t  xdr_yp_inaddr();
00090 bool_t  xdr_ypmap_parms();
00091 bool_t  xdr_ypowner_wrap_string();
00092 bool_t  xdr_yppushresp_xfr();
00093 bool_t  xdr_ypresp_order();
00094 bool_t  xdr_ypresp_master();
00095 bool_t  xdr_ypall();
00096 bool_t  xdr_ypresp_maplist();
00097
00098 /* Program and version symbols, magic numbers */
00099
00100 #define YPPROG          ((u_long)100004)
00101 #define YPVERS          ((u_long)2)
00102 #define YPVERS_ORIG     ((u_long)1)
00103 #define YPMAXRECORD     ((u_long)1024)
00104 #define YPMAXDOMAIN     ((u_long)64)
00105 #define YPMAXMAP        ((u_long)64)
00106 #define YPMAXPEER       ((u_long)256)
00107
00108 /*
00109  * I don't know if anything of sun's depends on this, or if they
00110  * simply defined it so that their own code wouldn't try to send
00111  * packets over the ethernet MTU. This YP code doesn't use it.
00112  */
00113 #define YPMSGSZ         1600
00114
00115 #ifndef DATUM
00116 typedef struct {
00117         char    *dptr;
00118         int     dsize;
00119 } datum;
00120 #define DATUM
00121 #endif
00122
00123 struct ypmap_parms {
00124         char *domain;
00125         char *map;
00126         u_long ordernum;
00127         char *owner;
00128 };
00129
00130 struct ypreq_key {
00131         char *domain;
00132         char *map;
00133         datum keydat;
00134 };
00135
00136 struct ypreq_nokey {
00137         char *domain;
00138         char *map;
00139 };
00140
00141 struct ypreq_xfr {
00142         struct ypmap_parms map_parms;
00143         u_long transid;
00144         u_long proto;
00145         u_short port;
00146 };
00147 #define ypxfr_domain    map_parms.domain
00148 #define ypxfr_map       map_parms.map
00149 #define ypxfr_ordernum  map_parms.ordernum
00150 #define ypxfr_owner     map_parms.owner
00151
00152 struct ypresp_val {
00153         u_long status;
00154         datum valdat;
00155 };
00156
00157 struct ypresp_key_val {
00158         u_long status;
00159         datum keydat;
00160         datum valdat;
00161 };
00162
00163 struct ypresp_master {
00164         u_long status;
00165         char *master;
00166 };
00167
00168 struct ypresp_order {
00169         u_long status;
00170         u_long ordernum;
00171 };
00172
00173 struct ypmaplist {
00174         char ypml_name[YPMAXMAP + 1];
00175         struct ypmaplist *ypml_next;
00176 };
00177
00178 struct ypresp_maplist {
00179         u_long status;
00180         struct ypmaplist *list;
00181 };
00182
00183 /* ypserv procedure numbers */
00184 #define YPPROC_NULL             ((u_long)0)
00185 #define YPPROC_DOMAIN           ((u_long)1)
00186 #define YPPROC_DOMAIN_NONACK    ((u_long)2)
00187 #define YPPROC_MATCH            ((u_long)3)
00188 #define YPPROC_FIRST            ((u_long)4)
00189 #define YPPROC_NEXT             ((u_long)5)
00190 #define YPPROC_XFR              ((u_long)6)
00191 #define YPPROC_CLEAR            ((u_long)7)
00192 #define YPPROC_ALL              ((u_long)8)
00193 #define YPPROC_MASTER           ((u_long)9)
00194 #define YPPROC_ORDER            ((u_long)10)
00195 #define YPPROC_MAPLIST          ((u_long)11)
00196
00197 /* ypserv procedure return status values */
00198 #define YP_TRUE         ((long)1)       /* general purpose success code */
00199 #define YP_NOMORE       ((long)2)       /* no more entries in map */
00200 #define YP_FALSE        ((long)0)       /* general purpose failure code */
00201 #define YP_NOMAP        ((long)-1)      /* no such map in domain */
00202 #define YP_NODOM        ((long)-2)      /* domain not supported */
00203 #define YP_NOKEY        ((long)-3)      /* no such key in map */
00204 #define YP_BADOP        ((long)-4)      /* invalid operation */
00205 #define YP_BADDB        ((long)-5)      /* server data base is bad */
00206 #define YP_YPERR        ((long)-6)      /* YP server error */
00207 #define YP_BADARGS      ((long)-7)      /* request arguments bad */
00208 #define YP_VERS         ((long)-8)      /* YP server version mismatch */
00209
00210 /*
00211  * Sun's header file says:
00212  * "Domain binding data structure, used by ypclnt package and ypserv modules.
00213  * Users of the ypclnt package (or of this protocol) don't HAVE to know about
00214  * it, but it must be available to users because _yp_dobind is a public
00215  * interface."
00216  *
00217  * This is totally bogus! Nowhere else does Sun state that _yp_dobind() is
00218  * a public interface, and I don't know any reason anyone would want to call
00219  * it. But, just in case anyone does actually expect it to be available..
00220  * we provide this.. exactly as Sun wants it.
00221  */
00222 struct dom_binding {
00223        struct dom_binding *dom_pnext;
00224        char                dom_domain[YPMAXDOMAIN + 1];
00225        struct sockaddr_in  dom_server_addr;
00226        u_short             dom_server_port;
00227        int                 dom_socket;
00228        CLIENT             *dom_client;
00229        u_short             dom_local_port;
00230        long                dom_vers;
00231 };
00232
00233 /*
00234  * YPBIND PROTOCOL:
00235  *
00236  * ypbind supports the following procedures:
00237  *
00238  * YPBINDPROC_NULL      takes (void), returns (void).
00239  *                      to check if ypbind is running.
00240  * YPBINDPROC_DOMAIN    takes (char *), returns (struct ypbind_resp).
00241  *                      requests that ypbind start to serve the
00242  *                      named domain (if it doesn't already)
00243  * YPBINDPROC_SETDOM    takes (struct ypbind_setdom), returns (void).
00244  *                      used by ypset.
00245  */
00246
00247 #define YPBINDPROG              ((u_long)100007)
00248 #define YPBINDVERS              ((u_long)2)
00249 #define YPBINDVERS_ORIG         ((u_long)1)
00250
00251 /* ypbind procedure numbers */
00252 #define YPBINDPROC_NULL         ((u_long)0)
00253 #define YPBINDPROC_DOMAIN       ((u_long)1)
00254 #define YPBINDPROC_SETDOM       ((u_long)2)
00255
00256 /* error code in ypbind_resp.ypbind_status */
00257 enum ypbind_resptype {
00258         YPBIND_SUCC_VAL = 1,
00259         YPBIND_FAIL_VAL = 2
00260 };
00261
00262 /* network order, of course */
00263 struct ypbind_binding {
00264        struct in_addr  ypbind_binding_addr;
00265        u_short         ypbind_binding_port;
00266      };
00267
00268 struct ypbind_resp {
00269        enum ypbind_resptype    ypbind_status;
00270        union {
00271          u_long                ypbind_error;
00272          struct ypbind_binding ypbind_bindinfo;
00273        } ypbind_respbody;
00274      };
00275
00276 /* error code in ypbind_resp.ypbind_respbody.ypbind_error */
00277 #define YPBIND_ERR_ERR          1       /* internal error */
00278 #define YPBIND_ERR_NOSERV       2       /* no bound server for passed domain */
00279 #define YPBIND_ERR_RESC         3       /* system resource allocation failure */
00280
00281 /*
00282  * Request data structure for ypbind "Set domain" procedure.
00283  */
00284 struct ypbind_setdom {
00285         char ypsetdom_domain[YPMAXDOMAIN + 1];
00286         struct ypbind_binding ypsetdom_binding;
00287         u_short ypsetdom_vers;
00288 };
00289 #define ypsetdom_addr ypsetdom_binding.ypbind_binding_addr
00290 #define ypsetdom_port ypsetdom_binding.ypbind_binding_port
00291
00292 /*
00293  * YPPUSH PROTOCOL:
00294  *
00295  * Sun says:
00296  * "Protocol between clients (ypxfr, only) and yppush
00297  *  yppush speaks a protocol in the transient range, which
00298  *  is supplied to ypxfr as a command-line parameter when it
00299  *  is activated by ypserv."
00300  *
00301  * This protocol is not implemented, naturally, because this YP
00302  * implementation only does the client side.
00303  */
00304 #define YPPUSHVERS              ((u_long)1)
00305 #define YPPUSHVERS_ORIG         ((u_long)1)
00306
00307 /* yppush procedure numbers */
00308 #define YPPUSHPROC_NULL         ((u_long)0)
00309 #define YPPUSHPROC_XFRRESP      ((u_long)1)
00310
00311 struct yppushresp_xfr {
00312         u_long  transid;
00313         u_long  status;
00314 };
00315
00316 /* yppush status value in yppushresp_xfr.status */
00317 #define YPPUSH_SUCC     ((long)1)       /* Success */
00318 #define YPPUSH_AGE      ((long)2)       /* Master's version not newer */
00319 #define YPPUSH_NOMAP    ((long)-1)      /* Can't find server for map */
00320 #define YPPUSH_NODOM    ((long)-2)      /* Domain not supported */
00321 #define YPPUSH_RSRC     ((long)-3)      /* Local resource alloc failure */
00322 #define YPPUSH_RPC      ((long)-4)      /* RPC failure talking to server */
00323 #define YPPUSH_MADDR    ((long)-5)      /* Can't get master address */
00324 #define YPPUSH_YPERR    ((long)-6)      /* YP server/map db error */
00325 #define YPPUSH_BADARGS  ((long)-7)      /* Request arguments bad */
00326 #define YPPUSH_DBM      ((long)-8)      /* Local dbm operation failed */
00327 #define YPPUSH_FILE     ((long)-9)      /* Local file I/O operation failed */
00328 #define YPPUSH_SKEW     ((long)-10)     /* Map version skew during transfer */
00329 #define YPPUSH_CLEAR    ((long)-11)     /* Can't send "Clear" req to local ypserv */
00330 #define YPPUSH_FORCE    ((long)-12)     /* No local order number in map - use -f */
00331 #define YPPUSH_XFRERR   ((long)-13)     /* ypxfr error */
00332 #define YPPUSH_REFUSED  ((long)-14)     /* Transfer request refused by ypserv */
00333
00334 #endif
Generated on Wed Jan 25 15:42:33 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/rpcsvc/YPCLNT.H Source File

inc/rpcsvc/YPCLNT.H

Go to the documentation of this file.
00001
00005 /*
00006  * Copyright (c) 1992/3 Theo de Raadt <deraadt@fsa.ca>
00007  * All rights reserved.
00008  *
00009  * Redistribution and use in source and binary forms, with or without
00010  * modification, are permitted provided that the following conditions
00011  * are met:
00012  * 1. Redistributions of source code must retain the above copyright
00013  *    notice, this list of conditions and the following disclaimer.
00014  * 2. Redistributions in binary form must reproduce the above copyright
00015  *    notice, this list of conditions and the following disclaimer in the
00016  *    documentation and/or other materials provided with the distribution.
00017  * 3. The name of the author may not be used to endorse or promote
00018  *    products derived from this software without specific prior written
00019  *    permission.
00020  *
00021  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
00022  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00023  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00024  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
00025  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00026  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00027  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00028  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00029  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00030  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00031  * SUCH DAMAGE.
00032  *
00033  *      $Id: ypclnt.h,v 1.3 1995/05/30 04:55:49 rgrimes Exp $
00034  */
00035
00036 #ifndef __RPCSVC_YPCLNT_H
00037 #define __RPCSVC_YPCLNT_H
00038
00039 #define YPERR_BADARGS   1               /* args to function are bad */
00040 #define YPERR_RPC       2               /* RPC failure */
00041 #define YPERR_DOMAIN    3               /* can't bind to a server for domain */
00042 #define YPERR_MAP       4               /* no such map in server's domain */
00043 #define YPERR_KEY       5               /* no such key in map */
00044 #define YPERR_YPERR     6               /* some internal YP server or client error */
00045 #define YPERR_RESRC     7               /* local resource allocation failure */
00046 #define YPERR_NOMORE    8               /* no more records in map database */
00047 #define YPERR_PMAP      9               /* can't communicate with portmapper */
00048 #define YPERR_YPBIND    10              /* can't communicate with ypbind */
00049 #define YPERR_YPSERV    11              /* can't communicate with ypserv */
00050 #define YPERR_NODOM     12              /* local domain name not set */
00051 #define YPERR_BADDB     13              /* YP data base is bad */
00052 #define YPERR_VERS      14              /* YP version mismatch */
00053 #define YPERR_ACCESS    15              /* access violation */
00054 #define YPERR_BUSY      16              /* database is busy */
00055
00056 /*
00057  * Types of update operations
00058  */
00059 #define YPOP_CHANGE     1               /* change, do not add */
00060 #define YPOP_INSERT     2               /* add, do not change */
00061 #define YPOP_DELETE     3               /* delete this entry */
00062 #define YPOP_STORE      4               /* add, or change */
00063
00064 struct ypall_callback {
00065        int (*foreach)();       /* return non-0 to stop getting called */
00066        char *data;             /* opaque pointer for use of callback fn */
00067      };
00068
00069 int   yp_get_default_domain (char **domp);
00070 int   yp_bind         (char *dom);
00071 int  _yp_dobind       (char *dom, struct dom_binding **ypdb);
00072 void  yp_unbind       (char *dom);
00073 int   yp_match        (char *indomain, char *inmap, const char *inkey,
00074                        int inkeylen, char **outval, int *outvallen);
00075 int   yp_first        (char *indomain, char *inmap, char **outkey,
00076                        int *outkeylen, char **outval, int *outvallen);
00077 int   yp_next         (char *indomain, char *inmap, char *inkey, int inkeylen,
00078                        char **outkey, int *outkeylen, char **outval, int *outvallen);
00079 int   yp_master       (char *indomain, char *inmap, char **outname);
00080 int   yp_order        (char *indomain, char *inmap, int *outorder);
00081 int   yp_all          (char *indomain, char *inmap, struct ypall_callback *incallback);
00082 int   yp_invalid_domain (char *dom);
00083 char *yperr_string    (int incode);
00084 char *ypbinderr_string(int incode);
00085 int   ypprot_err      (unsigned int incode);
00086
00087 #endif
00088
Generated on Wed Jan 25 15:42:33 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/sys/CDEFS.H Source File

inc/sys/CDEFS.H

Go to the documentation of this file.
00001
00006 /*
00007  * Copyright (c) 1991, 1993
00008  *      The Regents of the University of California.  All rights reserved.
00009  *
00010  * This code is derived from software contributed to Berkeley by
00011  * Berkeley Software Design, Inc.
00012  *
00013  * Redistribution and use in source and binary forms, with or without
00014  * modification, are permitted provided that the following conditions
00015  * are met:
00016  * 1. Redistributions of source code must retain the above copyright
00017  *    notice, this list of conditions and the following disclaimer.
00018  * 2. Redistributions in binary form must reproduce the above copyright
00019  *    notice, this list of conditions and the following disclaimer in the
00020  *    documentation and/or other materials provided with the distribution.
00021  * 3. All advertising materials mentioning features or use of this software
00022  *    must display the following acknowledgement:
00023  *      This product includes software developed by the University of
00024  *      California, Berkeley and its contributors.
00025  * 4. Neither the name of the University nor the names of its contributors
00026  *    may be used to endorse or promote products derived from this software
00027  *    without specific prior written permission.
00028  *
00029  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
00030  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00031  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00032  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
00033  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00034  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00035  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00036  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00037  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00038  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00039  * SUCH DAMAGE.
00040  *
00041  *      @(#)cdefs.h     8.7 (Berkeley) 1/21/94
00042  */
00043
00044 #ifndef __SYS_CDEFS_H
00045 #define __SYS_CDEFS_H
00046
00047 #if defined(__DJGPP__) && !defined(djgpp_cdefs_incl)
00048   #include "/dev/env/DJDIR/include/sys/cdefs.h"
00049   #define djgpp_cdefs_incl
00050 #endif
00051
00052 #ifdef __cplusplus
00053   #define __BEGIN_DECLS  extern "C" {
00054   #define __END_DECLS    }
00055 #else
00056   #define __BEGIN_DECLS
00057   #define __END_DECLS
00058 #endif
00059
00060 #ifndef W32_NAMESPACE
00061   #define W32_NAMESPACE(x) _w32_ ## x
00062 #endif
00063
00064 #if defined(__CCDL__)
00065   #define cdecl _cdecl
00066
00067 #elif defined(__MINGW32__) && !defined(cdecl)
00068   #define cdecl __attribute__((__cdecl__))
00069
00070 #elif defined(_MSC_VER) || defined(__POCC__)
00071   #undef  cdecl
00072   #if (_MSC_VER <= 600)
00073     #define cdecl _cdecl
00074     #undef  __STDC__
00075     #define __STDC__ 1
00076   #else
00077     #define cdecl __cdecl
00078   #endif
00079   #define NO_ANSI_KEYWORDS
00080
00081 #elif defined(__DMC__)
00082   #define NO_UNDERSCORE __syscall
00083   /* e.g. int NO_UNDERSCORE foo (void); */
00084 #endif
00085
00086 #ifndef cdecl
00087 #define cdecl
00088 #endif
00089
00090 #if defined(_MSC_VER) && !defined(WIN32) && !defined(_WIN32)
00091   /*
00092    * MS's Quick-C/Visual-C (for DOS) insists that signal-handlers, atexit
00093    * functions and var-arg functions must be defined cdecl.
00094    * This is only an issue if a program is using 'fastcall' globally
00095    * (cl option /Gr).
00096    * On Win32 this isn't an issue since WATT-32.DLL cannot be built
00097    * as 'fastcall' anyway.
00098    */
00099   #undef  MS_CDECL
00100   #define MS_CDECL   cdecl
00101 #else
00102   #define MS_CDECL
00103 #endif
00104
00105
00106 struct mbuf {
00107        struct mbuf  *next;    /* Links mbufs belonging to single packets */
00108        struct mbuf  *anext;   /* Links packets on queues */
00109        unsigned      size;    /* Size of associated data buffer */
00110        int           refcnt;  /* Reference count */
00111        struct mbuf  *dup;     /* Pointer to duplicated mbuf */
00112        char         *data;    /* Active working pointers */
00113        unsigned      cnt;
00114      };
00115
00116
00117 /*
00118  * The __CONCAT macro is used to concatenate parts of symbol names, e.g.
00119  * with "#define OLD(foo) __CONCAT(old,foo)", OLD(foo) produces oldfoo.
00120  * The __CONCAT macro is a bit tricky -- make sure you don't put spaces
00121  * in between its arguments.  __CONCAT can also concatenate double-quoted
00122  * strings produced by the __STRING macro, but this only works with ANSI C.
00123  */
00124 #if (defined(__STDC__) && __STDC__) || defined(__cplusplus) || defined(__TURBOC__)
00125   #undef  __P
00126   #define __P(protos)     protos        /* full-blown ANSI C */
00127   #define __CONCAT(x,y)   x ## y
00128   #define __STRING(x)     #x
00129
00130   #define __const         const         /* define reserved names to standard */
00131   #define __signed        signed
00132   #define __volatile      volatile
00133   #if defined(__cplusplus)
00134     #define __inline      inline        /* convert to C++ keyword */
00135   #elif !defined(__GNUC__) && !defined(_MSC_VER) && !defined(__WATCOMC__)
00136     #define __inline                    /* delete GCC/MSC/Watcom keyword */
00137   #endif
00138
00139 #else
00140   #define __P(protos)     ()            /* traditional C preprocessor */
00141   #define __CONCAT(x,y)   xy
00142   #define __STRING(x)     "x"
00143
00144   #if !defined(__GNUC__) && !defined(_MSC_VER) && !defined(__WATCOMC__)
00145     #define __inline
00146   #endif
00147
00148   #if !defined(__GNUC__)
00149     #define __const                     /* delete pseudo-ANSI C keywords */
00150     #define __signed
00151     #define __volatile
00152
00153     /*
00154      * In non-ANSI C environments, new programs will want ANSI-only C keywords
00155      * deleted from the program and old programs will want them left alone.
00156      * When using a compiler other than gcc, programs using the ANSI C keywords
00157      * const, inline etc. as normal identifiers should define -DNO_ANSI_KEYWORDS.
00158      * When using "gcc -traditional", we assume that this is the intent; if
00159      * __GNUC__ is defined but __STDC__ is not, we leave the new keywords alone.
00160      */
00161     #if !defined(NO_ANSI_KEYWORDS)
00162       #define const                     /* delete ANSI C keywords */
00163       #define inline
00164       #define signed
00165       #define volatile
00166     #endif
00167   #endif  /* !__GNUC__ */
00168 #endif  /* !C++ */
00169
00170 /*
00171  * GCC1 and some versions of GCC2 declare dead (non-returning) and
00172  * pure (no side effects) functions using "volatile" and "const";
00173  * unfortunately, these then cause warnings under "-ansi -pedantic".
00174  * GCC2 uses a new, peculiar __attribute__((attrs)) style.  All of
00175  * these work for GNU C++ (modulo a slight glitch in the C++ grammar
00176  * in the distribution version of 2.5.5).
00177  */
00178 #if !defined(__GNUC__) || (__GNUC__ < 2) || ((__GNUC__ == 2) && (__GNUC_MINOR__ < 5))
00179   #undef  __attribute__
00180   #define __attribute__(x)   /* delete __attribute__ if non-gcc or older than gcc 2.5 */
00181   #if defined(__GNUC__) && !defined(__STRICT_ANSI__)
00182     #undef __dead
00183     #undef __pure
00184     #define __dead  __volatile
00185     #define __pure  __const
00186     #undef  __dead2
00187     #define __dead2
00188   #endif
00189 #endif
00190
00191 /*
00192  * Delete pseudo-keywords wherever they are not available or needed.
00193  * This seems to break MingW in mysterious ways, so leave it,
00194  */
00195 #ifndef __dead
00196 #define __dead
00197 #endif
00198
00199 #ifndef __dead2
00200 #define __dead2
00201 #endif
00202
00203 #ifndef __pure
00204 #define __pure
00205 #endif
00206
00207 /*
00208  * min() & max() macros
00209  */
00210 #if defined(__HIGHC__)
00211   #undef  min
00212   #undef  max
00213   #define min(a,b) _min(a,b)  /* intrinsic functions */
00214   #define max(a,b) _max(a,b)
00215 #endif
00216
00217 #ifndef min
00218 #define min(a,b) (((a) < (b)) ? (a) : (b))
00219 #endif
00220
00221 #ifndef max
00222 #define max(a,b) (((a) > (b)) ? (a) : (b))
00223 #endif
00224
00225 /*
00226  * from NetBSD's <sys/cdefs_aout.h>
00227  *
00228  * Written by J.T. Conklin <jtc@wimsey.com> 01/17/95.
00229  * Public domain.
00230  */
00231
00232 /* #define _C_LABEL(x)  __CONCAT(_,x) */
00233
00234 #if defined(__GNUC__)
00235   #define __indr_reference(sym,alias)                \
00236           __asm__(".stabs \"_" #alias "\",11,0,0,0");\
00237           __asm__(".stabs \"_" #sym "\",1,0,0,0");
00238
00239   #define __warn_references(sym,msg)                 \
00240           __asm__(".stabs \"" msg "\",30,0,0,0");    \
00241           __asm__(".stabs \"_" #sym "\",1,0,0,0");
00242
00243   #define __IDSTRING(name,string)  \
00244           static const char name[] __attribute__((__unused__)) = string
00245 #else
00246   #define __indr_reference(sym,alias)
00247   #define __warn_references(sym,msg)
00248   #define __IDSTRING(name,string)  static const char name[] = string
00249 #endif
00250
00251 #define __RCSID(_s)                __IDSTRING(rcsid,_s)
00252 #define __COPYRIGHT(_s)            __IDSTRING(copyright,_s)
00253
00254 #define __KERNEL_RCSID(_n,_s)      __IDSTRING(__CONCAT(rcsid,_n),_s)
00255 #define __KERNEL_COPYRIGHT(_n,_s)  __IDSTRING(__CONCAT(copyright,_n),_s)
00256
00257 #endif
Generated on Wed Jan 25 15:42:33 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/sys/ERRNO.H Source File

inc/sys/ERRNO.H

Go to the documentation of this file.
00001
00006 /*
00007  * The naming <sys/w??.h> is required for those compilers that
00008  * have <sys/??.h> in the usual place but doesn't define stuff
00009  * related to Watt-32's BSD-socket interface.
00010  */
00011
00012 #ifndef __SYS_WERRNO_H
00013 #include <sys/werrno.h>
00014 #endif
00015
Generated on Wed Jan 25 15:42:33 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/sys/IOCTL.H Source File

inc/sys/IOCTL.H

Go to the documentation of this file.
00001
00005 /*-
00006  * Copyright (c) 1982, 1986, 1990 The Regents of the University of California.
00007  * All rights reserved.
00008  *
00009  * Redistribution and use in source and binary forms, with or without
00010  * modification, are permitted provided that the following conditions
00011  * are met:
00012  * 1. Redistributions of source code must retain the above copyright
00013  *    notice, this list of conditions and the following disclaimer.
00014  * 2. Redistributions in binary form must reproduce the above copyright
00015  *    notice, this list of conditions and the following disclaimer in the
00016  *    documentation and/or other materials provided with the distribution.
00017  * 3. All advertising materials mentioning features or use of this software
00018  *    must display the following acknowledgement:
00019  *      This product includes software developed by the University of
00020  *      California, Berkeley and its contributors.
00021  * 4. Neither the name of the University nor the names of its contributors
00022  *    may be used to endorse or promote products derived from this software
00023  *    without specific prior written permission.
00024  *
00025  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
00026  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00027  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00028  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
00029  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00030  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00031  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00032  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00033  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00034  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00035  * SUCH DAMAGE.
00036  *
00037  *      @(#)ioctl.h     7.19 (Berkeley) 6/26/91
00038  */
00039
00040 #ifndef __SYS_IOCTL_H
00041 #define __SYS_IOCTL_H
00042
00043 /*
00044  * Commands for ioctlsocket(),  taken from the BSD file fcntl.h.
00045  *
00046  *
00047  * Ioctl's have the command encoded in the lower word,
00048  * and the size of any in or out parameters in the upper
00049  * word.  The high 2 bits of the upper word are used
00050  * to encode the in/out status of the parameter; for now
00051  * we restrict parameters to at most 128 bytes.
00052  */
00053
00054 #define IOCPARM_MASK 0x7f               /* parameters must be < 128 bytes */
00055
00056 #define IOCPARM_LEN(x)  (((x) >> 16) & IOCPARM_MASK)
00057 #define IOCBASECMD(x)   ((x) & ~IOCPARM_MASK)
00058 #define IOCGROUP(x)     (((x) >> 8) & 0xff)
00059
00060 #define IOCPARM_MAX     4096            /* max size of ioctl */
00061 #define IOC_VOID        0x20000000      /* no parameters */
00062 #define IOC_OUT         0x40000000      /* copy out parameters */
00063 #define IOC_IN          0x80000000      /* copy in parameters */
00064 #define IOC_INOUT       (IOC_IN|IOC_OUT)  /* 0x20000000 distinguishes new &
00065                                              old ioctl's */
00066 #define IOC_DIRMASK     0xe0000000      /* mask for IN/OUT/VOID */
00067
00068 #define _IO(x,y)    (IOC_VOID|(x<<8)|y)
00069 #define _IOR(x,y,t) (IOC_OUT|((sizeof(t)&IOCPARM_MASK)<<16)|(x<<8)|y)
00070 #define _IOW(x,y,t) (IOC_IN|((sizeof(t)&IOCPARM_MASK)<<16)|(x<<8)|y)
00071 /* this should be _IORW, but stdio got there first */
00072 #define _IOWR(x,y,t) (IOC_INOUT|((sizeof(t)&IOCPARM_MASK)<<16)|(x<<8)|y)
00073
00074 /*
00075  * file i/o controls
00076  */
00077 #define FIOCLEX         _IO('f', 1)            /* set close on exec on fd */
00078 #define FIONCLEX        _IO('f', 2)            /* remove close on exec */
00079 #define FIONREAD        _IOR('f', 127, int)    /* get # bytes to read */
00080 #define FIONBIO         _IOW('f', 126, int)    /* set/clear non-blocking i/o */
00081 #define FIOASYNC        _IOW('f', 125, int)    /* set/clear async i/o */
00082 #define FIOSETOWN       _IOW('f', 124, int)    /* set owner (struct Task *) */
00083 #define FIOGETOWN       _IOR('f', 123, int)    /* get owner (struct Task *) */
00084
00085 /*
00086  * socket i/o controls
00087  *
00088  * SIOCSPGRP and SIOCGPGRP are identical to the FIOSETOWN and FIOGETOWN,
00089  * respectively.
00090  */
00091 #define SIOCSPGRP       _IOW('s',  8, int)    /* set process group */
00092 #define SIOCGPGRP       _IOR('s',  9, int)    /* get process group */
00093
00094 /* #ifdef BSD */
00095 #define SIOCADDRT       _IOW('r', 10, struct ortentry) /* add route */
00096 #define SIOCDELRT       _IOW('r', 11, struct ortentry) /* delete route */
00097
00098 #define SIOCSIFADDR     _IOW('I', 12, struct ifreq)    /* set ifnet address */
00099 #define OSIOCGIFADDR    _IOWR('I',13, struct ifreq)    /* get ifnet address */
00100 #define SIOCGIFADDR     _IOWR('I',33, struct ifreq)    /* get ifnet address */
00101 #define SIOCSIFDSTADDR  _IOW('I', 14, struct ifreq)    /* set p-p address */
00102 #define OSIOCGIFDSTADDR _IOWR('I',15, struct ifreq)    /* get p-p address */
00103 #define SIOCGIFDSTADDR  _IOWR('I',34, struct ifreq)    /* get p-p address */
00104 #define SIOCSIFFLAGS    _IOW('I', 16, struct ifreq)    /* set ifnet flags */
00105 #define SIOCGIFFLAGS    _IOWR('I',17, struct ifreq)    /* get ifnet flags */
00106 #define OSIOCGIFBRDADDR _IOWR('I',18, struct ifreq)    /* get broadcast addr */
00107 #define SIOCGIFBRDADDR  _IOWR('I',35, struct ifreq)    /* get broadcast addr */
00108 #define SIOCSIFBRDADDR  _IOW('I',19, struct ifreq)     /* set broadcast addr */
00109 #define OSIOCGIFCONF    _IOWR('I',20, struct ifconf)   /* get ifnet list */
00110 #define SIOCGIFCONF     _IOWR('I',36, struct ifconf)   /* get ifnet list */
00111 #define OSIOCGIFNETMASK _IOWR('I',21, struct ifreq)    /* get net addr mask */
00112 #define SIOCGIFNETMASK  _IOWR('I',37, struct ifreq)    /* get net addr mask */
00113 #define SIOCSIFNETMASK  _IOW('I',22, struct ifreq)     /* set net addr mask */
00114 #define SIOCGIFMETRIC   _IOWR('I',23, struct ifreq)    /* get IF metric */
00115 #define SIOCSIFMETRIC   _IOW('I',24, struct ifreq)     /* set IF metric */
00116 #define SIOCDIFADDR     _IOW('I',25, struct ifreq)     /* delete IF addr */
00117 #define SIOCAIFADDR     _IOW('I',26, struct ifaliasreq) /* add/chg IF alias */
00118 #define SIOCGIFMTU      _IOWR('I',27, struct ifreq)    /* get IF mtu */
00119 #define SIOCGIFHWADDR   _IOWR('I',28, struct ifconf)   /* get hardware addr */
00120 #define OSIOCGIFHWADDR  SIOCGIFHWADDR
00121
00122 #define SIOCSARP        _IOW('I', 30, struct arpreq)   /* set arp entry */
00123 #define OSIOCGARP       _IOWR('I',31, struct arpreq)   /* get arp entry */
00124 #define SIOCGARP        _IOWR('I',38, struct arpreq)   /* get arp entry */
00125 #define SIOCDARP        _IOW('I', 32, struct arpreq)   /* delete arp entry */
00126 /* #endif */ /* BSD */
00127
00128 /* MS-DOS */
00129 #define SIOCSHIWAT  _IOW('s',  0, int)    /* set high watermark */
00130 #define SIOCGHIWAT  _IOR('s',  1, int)    /* get high watermark */
00131 #define SIOCSLOWAT  _IOW('s',  2, int)    /* set low watermark */
00132 #define SIOCGLOWAT  _IOR('s',  3, int)    /* get low watermark */
00133 #define SIOCATMARK  _IOR('s',  7, int)    /* at oob mark? */
00134
00135 /* Since this file shadows the normal djgpp <sys/ioctl.h>, we provide
00136  * this prototype here.
00137  */
00138 #if defined(DJGPP)
00139   int ioctl (int __fd, int __cmd, ...);
00140 #endif
00141
00142 #endif /* !SYS_IOCTL_H */
Generated on Wed Jan 25 15:42:33 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/sys/PACKOFF.H Source File

inc/sys/PACKOFF.H

Go to the documentation of this file.
00001
00006 /*++
00007
00008 Copyright (c) 1990,91  Microsoft Corporation
00009
00010 Module Name:
00011
00012     packoff.h
00013
00014 Abstract:
00015
00016     This file turns packing of structures off.  (That is, it enables
00017     automatic alignment of structure fields.)  An include file is needed
00018     because various compilers do this in different ways.
00019
00020     packoff.h is the complement to packon.h.  An inclusion of packoff.h
00021     MUST ALWAYS be preceded by an inclusion of packon.h, in one-to-one
00022     correspondence.
00023
00024 Author:
00025
00026     Chuck Lenzmeier (chuckl) 4-Mar-1990
00027
00028 Revision History:
00029
00030     15-Apr-1991 JohnRo
00031         Created lint-able variant.
00032
00033     20-Oct-1997 G.Vanem
00034         Added Metaware support
00035
00036     05-Jul-1999 G.Vanem
00037         Added LADsoft support
00038
00039     01-Nov-2000 G. Vanem
00040         Added Visual C/C++ support
00041
00042 --*/
00043
00044 #if defined(__BORLANDC__) && (__BORLANDC__ >= 0x550)
00045   #pragma option push -b -a8 -pc -A- /*P_O_Push*/
00046 #endif
00047
00048 #if !(defined(lint) || defined(_lint))
00049   #if defined(_MSC_VER) && (_MSC_VER >= 800)
00050     #pragma warning(disable:4103)
00051   #endif
00052
00053   #if defined(__CCDL__)
00054     #pragma pack()
00055   #elif defined(__HIGHC__)
00056     #pragma pop_align_members();
00057   #elif defined(__WATCOMC__) && (__WATCOMC__ >= 1000)
00058     #pragma pack(__pop);
00059   #elif (defined(_MSC_VER) && (_MSC_VER > 800)) || \
00060         (defined(__BORLANDC__) && (__BORLANDC__ >= 0x500)) || \
00061          defined(__POCC__) || defined(__LCC__)
00062     #pragma pack(pop)
00063   #else
00064     #pragma pack()
00065   #endif
00066 #endif
00067
00068 #if defined(__BORLANDC__) && (__BORLANDC__ >= 0x550)
00069   #pragma option pop  /*P_O_Pop*/
00070 #endif
Generated on Wed Jan 25 15:42:33 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/sys/PACKON.H Source File

inc/sys/PACKON.H

Go to the documentation of this file.
00001
00006 /*++
00007
00008 Copyright (c) 1990,91  Microsoft Corporation
00009
00010 Module Name:
00011
00012     packon.h
00013
00014 Abstract:
00015
00016     This file turns packing of structures on.  (That is, it disables
00017     automatic alignment of structure fields.)  An include file is needed
00018     because various compilers do this in different ways.
00019
00020     The file packoff.h is the complement to this file.
00021
00022 Author:
00023
00024     Chuck Lenzmeier (chuckl) 4-Mar-1990
00025
00026 Revision History:
00027
00028     15-Apr-1991 JohnRo
00029         Created lint-able variant.
00030
00031     20-Oct-1997 G.Vanem
00032         Added Metaware support
00033
00034     05-Jul-1999 G.Vanem
00035         Added LADsoft support
00036
00037     01-Nov-2000 G. Vanem
00038         Added Visual C/C++ support
00039
00040 --*/
00041
00042 #if defined(__BORLANDC__) && (__BORLANDC__ >= 0x550)
00043   #pragma option push -b -a8 -pc -A- /*P_O_Push*/
00044 #endif
00045
00046 #if !(defined(lint) || defined(_lint))
00047   #if defined(_MSC_VER) && (_MSC_VER >= 800)
00048     #pragma warning(disable:4103)
00049   #endif
00050
00051   #if defined(__HIGHC__)
00052     #pragma push_align_members(1);
00053   #elif defined(__WATCOMC__) && (__WATCOMC__ >= 1000)
00054     #pragma pack(__push,1);
00055   #elif (defined(_MSC_VER) && (_MSC_VER > 800)) || \
00056         (defined(__BORLANDC__) && (__BORLANDC__ >= 0x500)) || \
00057          defined(__POCC__) || defined(__LCC__)
00058     #pragma pack(push,1)
00059   #else
00060     #pragma pack(1)
00061   #endif
00062 #endif
00063
00064 #if defined(__BORLANDC__) && (__BORLANDC__ >= 0x550)
00065   #pragma option pop  /*P_O_Pop*/
00066 #endif
Generated on Wed Jan 25 15:42:33 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/sys/PARAM.H Source File

inc/sys/PARAM.H

Go to the documentation of this file.
00001
00006 /* sys/param.h (wattcp) */
00007
00008 #ifndef __SYS_PARAM_H
00009 #define __SYS_PARAM_H
00010
00011 #ifndef PAGE_SIZE
00012 #define PAGE_SIZE      0x1000
00013 #endif
00014
00015 #ifndef HZ
00016 #define HZ             100
00017 #endif
00018
00019 #ifndef MAXNAMLEN
00020 #define MAXNAMLEN      260
00021 #endif
00022
00023 #ifndef MAXPATHLEN
00024 #define MAXPATHLEN     260
00025 #endif
00026
00027 #ifndef MAXHOSTNAMELEN
00028 #define MAXHOSTNAMELEN 256
00029 #endif
00030
00031 #ifndef __SYS_SWAP_BYTES_H
00032 #include <sys/swap.h>
00033 #endif
00034
00035 #endif
Generated on Wed Jan 25 15:42:33 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/sys/POLL.H Source File

inc/sys/POLL.H

Go to the documentation of this file.
00001
00004 #ifndef __SYS_POLL_H
00005 #define __SYS_POLL_H
00006
00007 #define POLLIN   0x0001
00008 #define POLLPRI  0x0002   /* not used */
00009 #define POLLOUT  0x0004
00010 #define POLLERR  0x0008
00011 #define POLLHUP  0x0010   /* not used */
00012 #define POLLNVAL 0x0020   /* not used */
00013
00014 struct pollfd {
00015        int fd;
00016        int events;     /* in param: what to poll for */
00017        int revents;    /* out param: what events occured */
00018      };
00019
00020 extern int poll (struct pollfd *p, int num, int timeout);
00021
00022 #endif
Generated on Wed Jan 25 15:42:33 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/sys/QUEUE.H Source File

inc/sys/QUEUE.H

Go to the documentation of this file.
00001
00005 /*
00006  * Copyright (c) 1991, 1993
00007  *      The Regents of the University of California.  All rights reserved.
00008  *
00009  * Redistribution and use in source and binary forms, with or without
00010  * modification, are permitted provided that the following conditions
00011  * are met:
00012  * 1. Redistributions of source code must retain the above copyright
00013  *    notice, this list of conditions and the following disclaimer.
00014  * 2. Redistributions in binary form must reproduce the above copyright
00015  *    notice, this list of conditions and the following disclaimer in the
00016  *    documentation and/or other materials provided with the distribution.
00017  * 3. All advertising materials mentioning features or use of this software
00018  *    must display the following acknowledgement:
00019  *      This product includes software developed by the University of
00020  *      California, Berkeley and its contributors.
00021  * 4. Neither the name of the University nor the names of its contributors
00022  *    may be used to endorse or promote products derived from this software
00023  *    without specific prior written permission.
00024  *
00025  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
00026  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00027  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00028  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
00029  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00030  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00031  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00032  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00033  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00034  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00035  * SUCH DAMAGE.
00036  *
00037  *      @(#)queue.h     8.5 (Berkeley) 8/20/94
00038  */
00039
00040 #ifndef __SYS_QUEUE_H
00041 #define __SYS_QUEUE_H
00042
00043 /*
00044  * This file defines three types of data structures: lists, tail queues,
00045  * and circular queues.
00046  *
00047  * A list is headed by a single forward pointer (or an array of forward
00048  * pointers for a hash table header). The elements are doubly linked
00049  * so that an arbitrary element can be removed without a need to
00050  * traverse the list. New elements can be added to the list before
00051  * or after an existing element or at the head of the list. A list
00052  * may only be traversed in the forward direction.
00053  *
00054  * A tail queue is headed by a pair of pointers, one to the head of the
00055  * list and the other to the tail of the list. The elements are doubly
00056  * linked so that an arbitrary element can be removed without a need to
00057  * traverse the list. New elements can be added to the list before or
00058  * after an existing element, at the head of the list, or at the end of
00059  * the list. A tail queue may only be traversed in the forward direction.
00060  *
00061  * A circle queue is headed by a pair of pointers, one to the head of the
00062  * list and the other to the tail of the list. The elements are doubly
00063  * linked so that an arbitrary element can be removed without a need to
00064  * traverse the list. New elements can be added to the list before or after
00065  * an existing element, at the head of the list, or at the end of the list.
00066  * A circle queue may be traversed in either direction, but has a more
00067  * complex end of list detection.
00068  *
00069  * For details on the use of these macros, see the queue(3) manual page.
00070  */
00071
00072 /*
00073  * List definitions.
00074  */
00075 #define LIST_HEAD(name, type)                                           \
00076 struct name {                                                           \
00077         struct type *lh_first;  /* first element */                     \
00078 }
00079
00080 #define LIST_ENTRY(type)                                                \
00081 struct {                                                                \
00082         struct type *le_next;   /* next element */                      \
00083         struct type **le_prev;  /* address of previous next element */  \
00084 }
00085
00086 /*
00087  * List functions.
00088  */
00089 #define LIST_INIT(head) {                                               \
00090         (head)->lh_first = NULL;                                        \
00091 }
00092
00093 #define LIST_INSERT_AFTER(listelm, elm, field) {                        \
00094         if (((elm)->field.le_next = (listelm)->field.le_next) != NULL)  \
00095                 (listelm)->field.le_next->field.le_prev =               \
00096                     &(elm)->field.le_next;                              \
00097         (listelm)->field.le_next = (elm);                               \
00098         (elm)->field.le_prev = &(listelm)->field.le_next;               \
00099 }
00100
00101 #define LIST_INSERT_BEFORE(listelm, elm, field) {                       \
00102         (elm)->field.le_prev = (listelm)->field.le_prev;                \
00103         (elm)->field.le_next = (listelm);                               \
00104         *(listelm)->field.le_prev = (elm);                              \
00105         (listelm)->field.le_prev = &(elm)->field.le_next;               \
00106 }
00107
00108 #define LIST_INSERT_HEAD(head, elm, field) {                            \
00109         if (((elm)->field.le_next = (head)->lh_first) != NULL)          \
00110                 (head)->lh_first->field.le_prev = &(elm)->field.le_next;\
00111         (head)->lh_first = (elm);                                       \
00112         (elm)->field.le_prev = &(head)->lh_first;                       \
00113 }
00114
00115 #define LIST_REMOVE(elm, field) {                                       \
00116         if ((elm)->field.le_next != NULL)                               \
00117                 (elm)->field.le_next->field.le_prev =                   \
00118                     (elm)->field.le_prev;                               \
00119         *(elm)->field.le_prev = (elm)->field.le_next;                   \
00120 }
00121
00122 /*
00123  * Tail queue definitions.
00124  */
00125 #define TAILQ_HEAD(name, type)                                          \
00126 struct name {                                                           \
00127         struct type *tqh_first; /* first element */                     \
00128         struct type **tqh_last; /* addr of last next element */         \
00129 }
00130
00131 #define TAILQ_ENTRY(type)                                               \
00132 struct {                                                                \
00133         struct type *tqe_next;  /* next element */                      \
00134         struct type **tqe_prev; /* address of previous next element */  \
00135 }
00136
00137 /*
00138  * Tail queue functions.
00139  */
00140 #define TAILQ_INIT(head) {                                              \
00141         (head)->tqh_first = NULL;                                       \
00142         (head)->tqh_last = &(head)->tqh_first;                          \
00143 }
00144
00145 #define TAILQ_INSERT_HEAD(head, elm, field) {                           \
00146         if (((elm)->field.tqe_next = (head)->tqh_first) != NULL)        \
00147                 (head)->tqh_first->field.tqe_prev =                     \
00148                     &(elm)->field.tqe_next;                             \
00149         else                                                            \
00150                 (head)->tqh_last = &(elm)->field.tqe_next;              \
00151         (head)->tqh_first = (elm);                                      \
00152         (elm)->field.tqe_prev = &(head)->tqh_first;                     \
00153 }
00154
00155 #define TAILQ_INSERT_TAIL(head, elm, field) {                           \
00156         (elm)->field.tqe_next = NULL;                                   \
00157         (elm)->field.tqe_prev = (head)->tqh_last;                       \
00158         *(head)->tqh_last = (elm);                                      \
00159         (head)->tqh_last = &(elm)->field.tqe_next;                      \
00160 }
00161
00162 #define TAILQ_INSERT_AFTER(head, listelm, elm, field) {                 \
00163         if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\
00164                 (elm)->field.tqe_next->field.tqe_prev =                 \
00165                     &(elm)->field.tqe_next;                             \
00166         else                                                            \
00167                 (head)->tqh_last = &(elm)->field.tqe_next;              \
00168         (listelm)->field.tqe_next = (elm);                              \
00169         (elm)->field.tqe_prev = &(listelm)->field.tqe_next;             \
00170 }
00171
00172 #define TAILQ_INSERT_BEFORE(listelm, elm, field) {                      \
00173         (elm)->field.tqe_prev = (listelm)->field.tqe_prev;              \
00174         (elm)->field.tqe_next = (listelm);                              \
00175         *(listelm)->field.tqe_prev = (elm);                             \
00176         (listelm)->field.tqe_prev = &(elm)->field.tqe_next;             \
00177 }
00178
00179 #define TAILQ_REMOVE(head, elm, field) {                                \
00180         if (((elm)->field.tqe_next) != NULL)                            \
00181                 (elm)->field.tqe_next->field.tqe_prev =                 \
00182                     (elm)->field.tqe_prev;                              \
00183         else                                                            \
00184                 (head)->tqh_last = (elm)->field.tqe_prev;               \
00185         *(elm)->field.tqe_prev = (elm)->field.tqe_next;                 \
00186 }
00187
00188 /*
00189  * Circular queue definitions.
00190  */
00191 #define CIRCLEQ_HEAD(name, type)                                        \
00192 struct name {                                                           \
00193         struct type *cqh_first;         /* first element */             \
00194         struct type *cqh_last;          /* last element */              \
00195 }
00196
00197 #define CIRCLEQ_ENTRY(type)                                             \
00198 struct {                                                                \
00199         struct type *cqe_next;          /* next element */              \
00200         struct type *cqe_prev;          /* previous element */          \
00201 }
00202
00203 /*
00204  * Circular queue functions.
00205  */
00206 #define CIRCLEQ_INIT(head) {                                            \
00207         (head)->cqh_first = (void *)(head);                             \
00208         (head)->cqh_last = (void *)(head);                              \
00209 }
00210
00211 #define CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) {               \
00212         (elm)->field.cqe_next = (listelm)->field.cqe_next;              \
00213         (elm)->field.cqe_prev = (listelm);                              \
00214         if ((listelm)->field.cqe_next == (void *)(head))                \
00215                 (head)->cqh_last = (elm);                               \
00216         else                                                            \
00217                 (listelm)->field.cqe_next->field.cqe_prev = (elm);      \
00218         (listelm)->field.cqe_next = (elm);                              \
00219 }
00220
00221 #define CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) {              \
00222         (elm)->field.cqe_next = (listelm);                              \
00223         (elm)->field.cqe_prev = (listelm)->field.cqe_prev;              \
00224         if ((listelm)->field.cqe_prev == (void *)(head))                \
00225                 (head)->cqh_first = (elm);                              \
00226         else                                                            \
00227                 (listelm)->field.cqe_prev->field.cqe_next = (elm);      \
00228         (listelm)->field.cqe_prev = (elm);                              \
00229 }
00230
00231 #define CIRCLEQ_INSERT_HEAD(head, elm, field) {                         \
00232         (elm)->field.cqe_next = (head)->cqh_first;                      \
00233         (elm)->field.cqe_prev = (void *)(head);                         \
00234         if ((head)->cqh_last == (void *)(head))                         \
00235                 (head)->cqh_last = (elm);                               \
00236         else                                                            \
00237                 (head)->cqh_first->field.cqe_prev = (elm);              \
00238         (head)->cqh_first = (elm);                                      \
00239 }
00240
00241 #define CIRCLEQ_INSERT_TAIL(head, elm, field) {                         \
00242         (elm)->field.cqe_next = (void *)(head);                         \
00243         (elm)->field.cqe_prev = (head)->cqh_last;                       \
00244         if ((head)->cqh_first == (void *)(head))                        \
00245                 (head)->cqh_first = (elm);                              \
00246         else                                                            \
00247                 (head)->cqh_last->field.cqe_next = (elm);               \
00248         (head)->cqh_last = (elm);                                       \
00249 }
00250
00251 #define CIRCLEQ_REMOVE(head, elm, field) {                              \
00252         if ((elm)->field.cqe_next == (void *)(head))                    \
00253                 (head)->cqh_last = (elm)->field.cqe_prev;               \
00254         else                                                            \
00255                 (elm)->field.cqe_next->field.cqe_prev =                 \
00256                     (elm)->field.cqe_prev;                              \
00257         if ((elm)->field.cqe_prev == (void *)(head))                    \
00258                 (head)->cqh_first = (elm)->field.cqe_next;              \
00259         else                                                            \
00260                 (elm)->field.cqe_prev->field.cqe_next =                 \
00261                     (elm)->field.cqe_next;                              \
00262 }
00263 #endif
Generated on Wed Jan 25 15:42:33 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/sys/SELECT.H Source File

inc/sys/SELECT.H

Go to the documentation of this file.
00001
00006 #include <tcp.h>   /* select_s() */
Generated on Wed Jan 25 15:42:33 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/sys/SO_IOCTL.H Source File

inc/sys/SO_IOCTL.H

Go to the documentation of this file.
00001
00006 /* so_ioctl.h derived from BSD's ioctl.h by hv and em 1994
00007  *
00008  * Copyright (c) 1982, 1986, 1990 The Regents of the University of California.
00009  * All rights reserved.
00010  *
00011  * Redistribution and use in source and binary forms, with or without
00012  * modification, are permitted provided that the following conditions
00013  * are met:
00014  * 1. Redistributions of source code must retain the above copyright
00015  *    notice, this list of conditions and the following disclaimer.
00016  * 2. Redistributions in binary form must reproduce the above copyright
00017  *    notice, this list of conditions and the following disclaimer in the
00018  *    documentation and/or other materials provided with the distribution.
00019  * 3. All advertising materials mentioning features or use of this software
00020  *    must display the following acknowledgement:
00021  *      This product includes software developed by the University of
00022  *      California, Berkeley and its contributors.
00023  * 4. Neither the name of the University nor the names of its contributors
00024  *    may be used to endorse or promote products derived from this software
00025  *    without specific prior written permission.
00026  *
00027  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
00028  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00029  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00030  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
00031  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00032  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00033  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00034  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00035  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00036  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00037  * SUCH DAMAGE.
00038  *
00039  *      from: @(#)ioctl.h       7.19 (Berkeley) 6/26/91
00040  */
00041
00042 #ifndef __SYS_SO_IOCTL_H
00043 #define __SYS_SO_IOCTL_H
00044
00045 #undef _IOC
00046 #undef _IOW
00047 #undef _IOR
00048 #undef _IOWR
00049
00050 #define _IOC(a,b) ((a<<8)|b)
00051 #define _IOW(a,b,c) _IOC(a,b)
00052 #define _IOR(a,b,c) _IOC(a,b)
00053 #define _IOWR(a,b,c) _IOC(a,b)
00054
00055 #define _TCPIP_FIONREAD _IOC('f', 127)
00056 #define FIONBIO         _IOC('f', 126)
00057 #define FIOASYNC        _IOC('f', 125)
00058 #define FIOTCPCKSUM     _IOC('f', 128)
00059 #define FIONSTATUS      _IOC('f', 120)
00060 #define FIONURG         _IOC('f', 121)
00061
00062 /* socket i/o controls */
00063 #define SIOCSHIWAT      _IOW('s',  0, int)      /* set high watermark */
00064 #define SIOCGHIWAT      _IOR('s',  1, int)      /* get high watermark */
00065 #define SIOCSLOWAT      _IOW('s',  2, int)      /* set low watermark */
00066 #define SIOCGLOWAT      _IOR('s',  3, int)      /* get low watermark */
00067 #define SIOCATMARK      _IOR('s',  7, int)      /* at oob mark? */
00068 #define SIOCSPGRP       _IOW('s',  8, int)      /* set process group */
00069 #define SIOCGPGRP       _IOR('s',  9, int)      /* get process group */
00070
00071 #define SIOCADDRT       _IOW('r', 10, struct ortentry)  /* add route */
00072 #define SIOCDELRT       _IOW('r', 11, struct ortentry)  /* delete route */
00073
00074 #define SIOCSIFADDR     _IOW('i', 12, struct ifreq)     /* set ifnet address */
00075 #define SIOCGIFADDR     _IOWR('i',13, struct ifreg)     /* get ifnet addres */
00076 #define OSIOCGIFADDR    SIOCGIFADDR
00077 #define SIOCSIFDSTADDR  _IOW('i', 14, struct ifreq)     /* set p-p address */
00078 #define SIOCGIFDSTADDR  _IOWR('i',15, struct ifreq)     /* get p-p address */
00079 #define OSIOCGIFDSTADDR SIOCGIFDSTADDR
00080 #define SIOCSIFFLAGS    _IOW('i', 16, struct ifreq)     /* set ifnet flags */
00081 #define SIOCGIFFLAGS    _IOWR('i',17, struct ifreq)     /* get ifnet flags */
00082 #define SIOCGIFBRDADDR  _IOWR('i',18, struct ifreq)     /* get broadcast addr */
00083 #define OSIOCGIFBRDADDR SIOCGIFBRDADDR
00084 #define SIOCSIFBRDADDR  _IOW('i', 19, struct ifreq)     /* set broadcast addr */
00085 #define SIOCGIFCONF     _IOWR('i',20, struct ifreq)     /* get ifnet list */
00086 #define OSIOCGIFCONF    SIOCGIFCONF
00087 #define SIOCGIFNETMASK  _IOWR('i',21, struct ifreq)     /* get net addr mask */
00088 #define OSIOCGIFNETMASK SIOCGIFNETMASK
00089 #define SIOCSIFNETMASK  _IOW('i', 22, struct ifreq)     /* set net addr mask */
00090 #define SIOCGIFMETRIC   _IOWR('i',23, struct ifreq)     /* get if metric */
00091 #define SIOCSIFMETRIC   _IOW('i', 24, struct ifreq)     /* set if metric */
00092
00093 #define SIOCSARP        _IOW('i', 30, struct arpreq)    /* set arp entry */
00094 #define SIOCGARP        _IOWR('i',31, struct arpreq)    /* get arp entry */
00095 #define OSIOCGARP       SIOCGARP
00096 #define SIOCDARP        _IOW('i', 32, struct arpreq)    /* delete arp entry */
00097
00098 #endif
Generated on Wed Jan 25 15:42:33 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/sys/SOCKET.H Source File

inc/sys/SOCKET.H

Go to the documentation of this file.
00001
00006 /* Modified for emx by hv and em 1994-1995
00007  *
00008  * Copyright (c) 1982,1985,1986,1988 Regents of the University of California.
00009  * All rights reserved.
00010  *
00011  * Redistribution and use in source and binary forms, with or without
00012  * modification, are permitted provided that the following conditions
00013  * are met:
00014  * 1. Redistributions of source code must retain the above copyright
00015  *    notice, this list of conditions and the following disclaimer.
00016  * 2. Redistributions in binary form must reproduce the above copyright
00017  *    notice, this list of conditions and the following disclaimer in the
00018  *    documentation and/or other materials provided with the distribution.
00019  * 3. All advertising materials mentioning features or use of this software
00020  *    must display the following acknowledgement:
00021  *      This product includes software developed by the University of
00022  *      California, Berkeley and its contributors.
00023  * 4. Neither the name of the University nor the names of its contributors
00024  *    may be used to endorse or promote products derived from this software
00025  *    without specific prior written permission.
00026  *
00027  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
00028  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00029  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00030  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
00031  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00032  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00033  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00034  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00035  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00036  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00037  * SUCH DAMAGE.
00038  *
00039  *      from: @(#)socket.h      7.13 (Berkeley) 4/20/91
00040  *      $Id: socket.h,v 1.5 1993/06/27 05:59:06 andrew Exp $
00041  */
00042
00043 #ifndef __SYS_SOCKET_H
00044 #define __SYS_SOCKET_H
00045
00046 #ifndef __SYS_W32API_H
00047 #include <sys/w32api.h>
00048 #endif
00049
00050 #ifndef __SYS_WERRNO_H
00051 #include <sys/werrno.h>
00052 #endif
00053
00054 #ifndef __SYS_CDEFS_H
00055 #include <sys/cdefs.h>
00056 #endif
00057
00058 #ifndef __SYS_WTYPES_H
00059 #include <sys/wtypes.h>
00060 #endif
00061
00062 #ifndef __SYS_WTIME_H
00063 #include <sys/wtime.h>
00064 #endif
00065
00066 #ifndef __NETINET_IN_H
00067 #include <netinet/in.h>
00068 #endif
00069
00070 /*
00071  * Definitions related to sockets: types, address families, options.
00072  */
00073
00074 /*
00075  * This is used instead of -1, since the socket type is signed.
00076  */
00077 #define INVALID_SOCKET  (int)(~0)
00078 #define SOCKET_ERROR    (-1)
00079
00080 /*
00081  * Types
00082  */
00083 #define SOCK_STREAM     1               /* stream socket */
00084 #define SOCK_DGRAM      2               /* datagram socket */
00085 #define SOCK_RAW        3               /* raw-protocol interface */
00086 #define SOCK_RDM        4               /* reliably-delivered message */
00087 #define SOCK_SEQPACKET  5               /* sequenced packet stream */
00088 #define SOCK_PACKET     10              /* linux specific way of        */
00089                                         /* getting packets at the dev   */
00090                                         /* level.  For writing rarp and */
00091                                         /* other similar things on the  */
00092                                         /* user level.                  */
00093
00094 /*
00095  * Option flags per-socket.
00096  */
00097 #define SO_DEBUG        0x0001          /* turn on debugging info recording */
00098 #define SO_ACCEPTCONN   0x0002          /* socket has had listen() */
00099 #define SO_REUSEADDR    0x0004          /* allow local address reuse */
00100 #define SO_KEEPALIVE    0x0008          /* keep connections alive */
00101 #define SO_DONTROUTE    0x0010          /* just use interface addresses */
00102 #define SO_BROADCAST    0x0020          /* permit sending of broadcast msgs */
00103 #define SO_USELOOPBACK  0x0040          /* bypass hardware when possible */
00104 #define SO_LINGER       0x0080          /* linger on close if data present */
00105 #define SO_OOBINLINE    0x0100          /* leave received OOB data in line */
00106
00107 #define SO_DONTLINGER   (int)(~SO_LINGER)
00108
00109 /*
00110  * Additional options, not kept in so_options.
00111  */
00112 #define SO_SNDBUF       0x1001          /* send buffer size */
00113 #define SO_RCVBUF       0x1002          /* receive buffer size */
00114 #define SO_SNDLOWAT     0x1003          /* send low-water mark */
00115 #define SO_RCVLOWAT     0x1004          /* receive low-water mark */
00116 #define SO_SNDTIMEO     0x1005          /* send timeout */
00117 #define SO_RCVTIMEO     0x1006          /* receive timeout */
00118 #define SO_ERROR        0x1007          /* get error status and clear */
00119 #define SO_TYPE         0x1008          /* get socket type */
00120
00121
00122 #include <sys/packon.h>
00123
00124 /*
00125  * Structure used for manipulating linger option.
00126  */
00127 struct linger {
00128        int l_onoff;                /* option on/off */
00129        int l_linger;               /* linger time */
00130      };
00131
00132 /*
00133  * Level number for (get/set)sockopt() to apply to socket itself.
00134  */
00135 #define SOL_SOCKET      0xffff          /* options for socket level */
00136
00137 /*
00138  * Address families.
00139  */
00140 #define AF_UNSPEC       0               /* unspecified */
00141 #define AF_UNIX         1               /* local to host (pipes, portals) */
00142 #define AF_INET         2               /* internetwork: UDP, TCP, etc. */
00143 #define AF_IMPLINK      3               /* arpanet imp addresses */
00144 #define AF_PUP          4               /* pup protocols: e.g. BSP */
00145 #define AF_CHAOS        5               /* mit CHAOS protocols */
00146 #define AF_NS           6               /* XEROX NS protocols */
00147 #define AF_ISO          7               /* ISO protocols */
00148 #define AF_OSI          AF_ISO
00149 #define AF_ECMA         8               /* european computer manufacturers */
00150 #define AF_DATAKIT      9               /* datakit protocols */
00151 #define AF_CCITT        10              /* CCITT protocols, X.25 etc */
00152 #define AF_SNA          11              /* IBM SNA */
00153 #define AF_DECnet       12              /* DECnet */
00154 #define AF_DLI          13              /* DEC Direct data link interface */
00155 #define AF_LAT          14              /* LAT */
00156 #define AF_HYLINK       15              /* NSC Hyperchannel */
00157 #define AF_APPLETALK    16              /* Apple Talk */
00158 #define AF_ROUTE        17              /* Internal Routing Protocol */
00159 #define AF_LINK         18              /* Link layer interface */
00160 #define pseudo_AF_XTP   19              /* eXpress Transfer Protocol (no AF) */
00161 #define AF_INET6        24              /* IPv6 address family */
00162 #define AF_PACKET       25              /* raw packets */
00163 #define AF_MAX          26
00164
00165 /*
00166  * Structure used by kernel to store most
00167  * addresses.
00168  * is called struct osockaddr in 4.4BSD
00169  */
00170 struct sockaddr {
00171        u_short sa_family;              /* address family */
00172        char    sa_data[14];            /* up to 14 bytes of direct address */
00173      };
00174
00175 /*
00176  * Structure used by kernel to pass protocol
00177  * information in raw sockets.
00178  */
00179 struct sockproto {
00180        u_short sp_family;              /* address family */
00181        u_short sp_protocol;            /* protocol */
00182      };
00183
00184 /*
00185  * Protocol families, same as address families for now.
00186  */
00187 #define PF_UNSPEC       AF_UNSPEC
00188 #define PF_UNIX         AF_UNIX
00189 #define PF_INET         AF_INET
00190 #define PF_INET6        AF_INET6
00191 #define PF_IMPLINK      AF_IMPLINK
00192 #define PF_PUP          AF_PUP
00193 #define PF_CHAOS        AF_CHAOS
00194 #define PF_NS           AF_NS
00195 #define PF_ISO          AF_ISO
00196 #define PF_OSI          AF_ISO
00197 #define PF_ECMA         AF_ECMA
00198 #define PF_DATAKIT      AF_DATAKIT
00199 #define PF_CCITT        AF_CCITT
00200 #define PF_SNA          AF_SNA
00201 #define PF_DECnet       AF_DECnet
00202 #define PF_DLI          AF_DLI
00203 #define PF_LAT          AF_LAT
00204 #define PF_HYLINK       AF_HYLINK
00205 #define PF_APPLETALK    AF_APPLETALK
00206 #define PF_ROUTE        AF_ROUTE
00207 #define PF_LINK         AF_LINK
00208 #define PF_PACKET       AF_PACKET
00209 #define PF_XTP          pseudo_AF_XTP   /* really just proto family, no AF */
00210
00211 #define PF_MAX          AF_MAX
00212
00213 /*
00214  * Maximum queue length specifiable by listen.
00215  */
00216 #define SOMAXCONN       32
00217 #define MSG_OOB         0x1             /* process out-of-band data */
00218 #define MSG_PEEK        0x2             /* peek at incoming message */
00219 #define MSG_DONTROUTE   0x4             /* send without using routing tables */
00220 #define MSG_EOR         0x8             /* data completes record */
00221 #define MSG_TRUNC       0x10            /* data discarded before delivery */
00222 #define MSG_CTRUNC      0x20            /* control data lost before delivery */
00223 #define MSG_WAITALL     0x40            /* wait for full request or error */
00224
00225 #define MSG_MAXIOVLEN   16
00226
00227
00228 /*
00229  * Header for ancillary data objects in msg_control buffer.
00230  * Used for additional information with/about a datagram
00231  * not expressible by flags.  The format is a sequence
00232  * of message elements headed by cmsghdr structures.
00233  */
00234 struct cmsghdr {
00235        u_int   cmsg_len;               /* data byte count, including hdr */
00236        int     cmsg_level;             /* originating protocol */
00237        int     cmsg_type;              /* protocol-specific type */
00238        /* followed by  u_char  cmsg_data[]; */
00239      };
00240
00241 struct msghdr {
00242        char         *msg_name;         /* Contains an optional address. */
00243        int           msg_namelen;      /* len of optional address */
00244        struct iovec *msg_iov;          /* scatter/gather array. */
00245        int           msg_iovlen;       /* number of elements in msg_iov */
00246        char         *msg_accrights;    /* does not apply to IP - not changed */
00247        int           msg_accrightslen; /* does not apply to IP */
00248      };
00249
00250 /* CMSG_DATA clashes with <wincrypt.h>
00251  */
00252 #if (defined(WIN32) || defined(_WIN32)) && \
00253     !defined(_WINDOWS_H) && !defined(_INC_WINDOWS) && !defined(__windows_h__)
00254   #error Include <windows.h> before this point.
00255 #endif
00256
00257 /* given pointer to struct adatahdr, return pointer to data */
00258 #undef  CMSG_DATA
00259 #define CMSG_DATA(cmsg)         ((u_char *)((cmsg) + 1))
00260
00261 /* given pointer to struct adatahdr, return pointer to next adatahdr */
00262 #define CMSG_NXTHDR(mhdr, cmsg) \
00263         (((caddr_t)(cmsg) + (cmsg)->cmsg_len + sizeof(struct cmsghdr) > \
00264             (mhdr)->msg_control + (mhdr)->msg_controllen) ? \
00265             (struct cmsghdr *)NULL : \
00266             (struct cmsghdr *)((caddr_t)(cmsg) + ALIGN((cmsg)->cmsg_len)))
00267
00268 #define CMSG_FIRSTHDR(mhdr)     ((struct cmsghdr *)(mhdr)->msg_control)
00269
00270 /* "Socket"-level control message types: */
00271 #define SCM_RIGHTS      0x01            /* access rights (array of int) */
00272
00273 #include <sys/packoff.h>
00274
00275 __BEGIN_DECLS
00276
00277 W32_FUNC int    W32_CALL accept (int, struct sockaddr *, int *);
00278 W32_FUNC int    W32_CALL bind (int, const struct sockaddr *, int);
00279 W32_FUNC int    W32_CALL closesocket (int s);
00280 W32_FUNC int    W32_CALL connect (int, const struct sockaddr *, int);
00281 W32_FUNC int    W32_CALL ioctlsocket (int s, long cmd, char *argp);
00282 W32_FUNC int    MS_CDECL fcntlsocket (int s, int cmd, ...);
00283
00284 W32_FUNC int    W32_CALL getdomainname (char *name, int len);
00285 W32_FUNC int    W32_CALL setdomainname (const char *name, int len);
00286 W32_FUNC int    W32_CALL gethostname (char *name, int len);
00287 W32_FUNC int    W32_CALL sethostname (const char *name, int len);
00288
00289 W32_FUNC u_long W32_CALL gethostid (void);
00290 W32_FUNC u_long W32_CALL sethostid (u_long ip);
00291 W32_FUNC int    W32_CALL getpeername (int, struct sockaddr *, int *);
00292 W32_FUNC int    W32_CALL getsockname (int, struct sockaddr *, int *);
00293 W32_FUNC int    W32_CALL getsockopt (int, int, int, void *, int *);
00294 W32_FUNC int    W32_CALL listen (int, int);
00295 W32_FUNC int    W32_CALL recv (int, void *, int, int);
00296 W32_FUNC int    W32_CALL recvfrom (int, void *, int, int, struct sockaddr *, int *);
00297 W32_FUNC int    W32_CALL send (int, const void *, int, int);
00298 W32_FUNC int    W32_CALL sendto (int, const void *, int, int, const struct sockaddr *, int);
00299 W32_FUNC int    W32_CALL setsockopt (int, int, int, const void *, int);
00300 W32_FUNC int    W32_CALL shutdown (int, int);
00301 W32_FUNC int    W32_CALL socket (int, int, int);
00302
00303 __END_DECLS
00304
00305 #endif
Generated on Wed Jan 25 15:42:39 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/sys/SWAP.H Source File

inc/sys/SWAP.H

Go to the documentation of this file.
00001
00005 #ifndef __SYS_SWAP_BYTES_H
00006 #define __SYS_SWAP_BYTES_H
00007
00008 #ifndef __SYS_W32API_H
00009 #include <sys/w32api.h>
00010 #endif
00011
00012 #ifndef __SYS_CDEFS_H
00013 #include <sys/cdefs.h>
00014 #endif
00015
00016 #ifndef __NETINET_IN_H
00017 #include <netinet/in.h>
00018 #endif
00019
00020 #if defined(__dj_include_netinet_in_h_)
00021 #error "You are using the wrong version of <netinet/in.h>. Ref. point 10 of the INSTALL file"
00022 #endif
00023
00024
00025 __BEGIN_DECLS
00026
00027 #if defined(WIN32) || defined(_WIN32) /* provide some real versions too */
00028   W32_FUNC unsigned short W32_CALL ntohs (unsigned short);
00029   W32_FUNC unsigned short W32_CALL htons (unsigned short);
00030   W32_FUNC unsigned long  W32_CALL ntohl (unsigned long);
00031   W32_FUNC unsigned long  W32_CALL htonl (unsigned long);
00032   W32_FUNC unsigned long  cdecl   _w32_intel   (unsigned long x);
00033   W32_FUNC unsigned short cdecl   _w32_intel16 (unsigned short x);
00034 #endif
00035
00036 #undef  ntohs
00037 #undef  htons
00038 #undef  ntohl
00039 #undef  htonl
00040 #define ntohs(x)  intel16(x)
00041 #define htons(x)  intel16(x)
00042 #define ntohl(x)  intel(x)
00043 #define htonl(x)  intel(x)
00044
00045
00046 /*
00047  * Hard to believe, but someone uses Watt-32 on a
00048  * Motorola/PowerPC embedded target.
00049  */
00050 #if defined(BIG_ENDIAN_MACHINE) || defined(USE_BIGENDIAN)
00051   #define intel(x)    x
00052   #define intel16(x)  x
00053
00054 #elif defined(__GNUC__) && !defined(__NO_INLINE__)  /* -O0 */
00055   #define intel(x)   __ntohl(x)
00056   #define intel16(x) __ntohs(x)
00057
00058   /*
00059    * Ripped (and adapted) from <linux/include/asm-386/byteorder.h>
00060    */
00061   /*@unused@*/ extern __inline__ unsigned long __ntohl (unsigned long x)
00062   {
00063     __asm__ __volatile (
00064              "xchgb %b0, %h0\n\t"   /* swap lower bytes  */
00065              "rorl  $16, %0\n\t"    /* swap words        */
00066              "xchgb %b0, %h0"       /* swap higher bytes */
00067             : "=q" (x) : "0" (x));
00068     return (x);
00069   }
00070
00071   /*@unused@*/ extern __inline__ unsigned short __ntohs (unsigned short x)
00072   {
00073     __asm__ __volatile__ (
00074               "xchgb %b0, %h0"       /* swap bytes */
00075             : "=q" (x) : "0" (x));
00076     return (x);
00077   }
00078
00079 #elif defined(__POCC__)             /* PellesC */
00080   #define intel(x)   __ntohl(x)
00081   #define intel16(x) __ntohs(x)
00082
00083   __declspec(naked) inline unsigned long __fastcall __ntohl (unsigned long x)
00084   {
00085     __asm xchg cl, ch    /* 'x' is in ecx */
00086     __asm ror  ecx, 16
00087     __asm xchg cl, ch
00088     __asm mov  eax, ecx
00089     __asm ret
00090   }
00091
00092   __declspec(naked) inline unsigned short __fastcall __ntohs (unsigned short x)
00093   {
00094     __asm xchg  cl, ch    /* 'x' is in ecx */
00095     __asm movzx eax, cx
00096     __asm ret
00097   }
00098
00099 #elif (defined(_MSC_VER) && (_MSC_VER >= 1200)) &&  /* MSVC 6+ */ \
00100       !defined(__POCC__)           /* "pocc -Ze" sets _MSC_VER */
00101   #define intel(x)   __ntohl(x)
00102   #define intel16(x) __ntohs(x)
00103
00104   __declspec(naked) static unsigned long __ntohl (unsigned long x)
00105   {
00106     __asm mov  eax, [esp+4]
00107     __asm xchg al, ah
00108     __asm ror  eax, 16
00109     __asm xchg al, ah
00110     __asm ret
00111   }
00112
00113   __declspec(naked) static unsigned short __ntohs (unsigned short x)
00114   {
00115     __asm mov  ax, [esp+4]
00116     __asm xchg al, ah
00117     __asm ret
00118   }
00119
00120 #elif defined(__WATCOMC__) && defined(__FLAT__)  /* Watcom 32-bit */
00121   #define intel(x)   __ntohl(x)
00122   #define intel16(x) __ntohs(x)
00123
00124   extern unsigned long __ntohl (unsigned long x);
00125   #pragma aux  __ntohl =     \
00126               "xchg al, ah"  \
00127               "ror  eax, 16" \
00128               "xchg al, ah"  \
00129               parm   [eax]   \
00130               modify [eax];
00131
00132   extern unsigned short __ntohs (unsigned short x);
00133   #pragma aux __ntohs =     \
00134               "xchg al, ah" \
00135               parm   [ax]   \
00136               modify [ax];
00137
00138 #elif defined(__WATCOMC__) && !defined(__FLAT__)  /* Watcom 16-bit */
00139   #define intel(x)   __ntohl(x)
00140   #define intel16(x) __ntohs(x)
00141
00142   extern unsigned long __ntohl (unsigned long x);
00143   #pragma aux  __ntohl =     \
00144               "xchg al, dh"  \
00145               "xchg ah, dl"  \
00146               parm   [dx ax] \
00147               modify [dx ax];
00148
00149   extern unsigned short __ntohs (unsigned short x);
00150   #pragma aux __ntohs =     \
00151               "xchg al, ah" \
00152               parm   [ax]   \
00153               modify [ax];
00154
00155 #elif (defined(__BORLANDC__) && defined(__FLAT__)) || /* bcc32 */ \
00156       (defined(__DMC__) && (__INTSIZE==4))            /* dmc -mx */
00157   #include <dos.h>
00158
00159   #define intel(x)    __ntohl(x)
00160   #define intel16(x)  __ntohs(x)
00161
00162   #define __ntohs(x)  (_AX = x, \
00163                        __emit__(0x86,0xC4),      /* xchg al, ah */ \
00164                        _AX)
00165
00166   #define __ntohl(x)  (_EAX = x, \
00167                        __emit__(0x86,0xC4),      /* xchg al, ah  */ \
00168                        __emit__(0xC1,0xC8,0x10), /* ror  eax, 16 */ \
00169                        __emit__(0x86,0xC4),      /* xchg al, ah  */ \
00170                        _EAX)
00171
00172 #elif defined(__CCDL__) && defined(__386__)      /* LadSoft 386 */
00173   #define intel(x)    __ntohl(x)
00174   #define intel16(x)  __ntohs(x)
00175
00176   static unsigned long __ntohl (unsigned long x)
00177   {
00178     asm { mov  eax, [x]
00179           xchg al, ah
00180           ror  eax, 16
00181           xchg al, ah
00182         }
00183     return (_EAX);
00184   }
00185   static unsigned short __ntohs (unsigned short x)
00186   {
00187     asm { mov  ax, [x]
00188           xchg al, ah
00189         }
00190     return (unsigned short)_EAX;  /* doesn't have _AX */
00191   }
00192
00193   /* This crashes mysteriously if we use _bswap()
00194    */
00195 #elif defined(__LCC__) && 0              /* LCC-Win32 */
00196   #define intel(x)    __ntohl(x)
00197   #define intel16(x)  __ntohs(x)
00198   #if 0
00199     #include <intrinsics.h>
00200     #define W32_LCC_INTRINSICS_INCLUDED  /* header guard is missing */
00201     #define __ntohl(x)   (unsigned long) _bswap(x)
00202     #define __ntohs(x)  ((unsigned short) (_bswap(x) >> 16))
00203   #else
00204     unsigned long inline __declspec(naked) __ntohl (unsigned long x)
00205     {
00206       _asm ("movl (%esp), %eax");
00207       _asm ("xchg %ah, %al");
00208       _asm ("rorl $16, %eax");
00209       _asm ("xchg %ah, %al");
00210     }
00211     unsigned short inline __declspec(naked) __ntohs (unsigned short x)
00212     {
00213       _asm ("movs (%esp), %ax");
00214       _asm ("xchg %ah, %al");
00215     }
00216   #endif
00217
00218 #else  /* no inlining possible (or worth the effort) */
00219   #define intel   W32_NAMESPACE (intel)
00220   #define intel16 W32_NAMESPACE (intel16)
00221   #define WATT_NO_INLINE_INTEL
00222
00223   W32_FUNC unsigned long  cdecl intel   (unsigned long x);
00224   W32_FUNC unsigned short cdecl intel16 (unsigned short x);
00225 #endif
00226
00227 __END_DECLS
00228
00229 #endif /* __SYS_SWAP_BYTES_H */
Generated on Wed Jan 25 15:42:33 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/sys/SYSLOG.H Source File

inc/sys/SYSLOG.H

Go to the documentation of this file.
00001
00005 /*
00006  * Copyright (c) 1982, 1986, 1988, 1993
00007  *      The Regents of the University of California.  All rights reserved.
00008  *
00009  * Redistribution and use in source and binary forms, with or without
00010  * modification, are permitted provided that the following conditions
00011  * are met:
00012  * 1. Redistributions of source code must retain the above copyright
00013  *    notice, this list of conditions and the following disclaimer.
00014  * 2. Redistributions in binary form must reproduce the above copyright
00015  *    notice, this list of conditions and the following disclaimer in the
00016  *    documentation and/or other materials provided with the distribution.
00017  * 3. All advertising materials mentioning features or use of this software
00018  *    must display the following acknowledgement:
00019  *      This product includes software developed by the University of
00020  *      California, Berkeley and its contributors.
00021  * 4. Neither the name of the University nor the names of its contributors
00022  *    may be used to endorse or promote products derived from this software
00023  *    without specific prior written permission.
00024  *
00025  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
00026  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00027  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00028  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
00029  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00030  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00031  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00032  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00033  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00034  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00035  * SUCH DAMAGE.
00036  *
00037  *      @(#)syslog.h    8.1 (Berkeley) 6/2/93
00038  * $Id: syslog.h,v 1.15 1997/10/06 20:37:01 joerg Exp $
00039  */
00040
00041 #ifndef __SYS_SYSLOG_H
00042 #define __SYS_SYSLOG_H
00043
00044 #ifndef _PATH_LOG
00045 #define _PATH_LOG       "/var/run/log"
00046 #endif
00047
00048 #ifndef _PATH_OLDLOG
00049 #define _PATH_OLDLOG    "/dev/log"      /* backward compatibility */
00050 #endif
00051
00052 /*
00053  * priorities/facilities are encoded into a single 32-bit quantity, where the
00054  * bottom 3 bits are the priority (0-7) and the top 28 bits are the facility
00055  * (0-big number).  Both the priorities and the facilities map roughly
00056  * one-to-one to strings in the syslogd(8) source code.  This mapping is
00057  * included in this file.
00058  *
00059  * priorities (these are ordered)
00060  */
00061 #define LOG_EMERG       0       /* system is unusable */
00062 #define LOG_ALERT       1       /* action must be taken immediately */
00063 #define LOG_CRIT        2       /* critical conditions */
00064 #define LOG_ERR         3       /* error conditions */
00065 #define LOG_WARNING     4       /* warning conditions */
00066 #define LOG_NOTICE      5       /* normal but significant condition */
00067 #define LOG_INFO        6       /* informational */
00068 #define LOG_DEBUG       7       /* debug-level messages */
00069
00070 #define LOG_PRIMASK     0x07    /* mask to extract priority part (internal) */
00071                                 /* extract priority */
00072 #define LOG_PRI(p)      ((p) & LOG_PRIMASK)
00073 #define LOG_MAKEPRI(fac, pri)   ((fac) | (pri))
00074
00075 #define INTERNAL_NOPRI  0x10    /* the "no priority" priority */
00076                                 /* mark "facility" */
00077 #define INTERNAL_MARK   LOG_MAKEPRI((LOG_NFACILITIES<<3), 0)
00078
00079 typedef struct _code {
00080         unsigned long c_val;
00081         const char   *c_name;
00082       } CODE;
00083
00084 extern CODE prioritynames[13];
00085
00086 /* facility codes */
00087 #define LOG_KERN        (0<<3)  /* kernel messages */
00088 #define LOG_USER        (1<<3)  /* random user-level messages */
00089 #define LOG_MAIL        (2<<3)  /* mail system */
00090 #define LOG_DAEMON      (3<<3)  /* system daemons */
00091 #define LOG_AUTH        (4<<3)  /* security/authorization messages */
00092 #define LOG_SYSLOG      (5<<3)  /* messages generated internally by syslogd */
00093 #define LOG_LPR         (6<<3)  /* line printer subsystem */
00094 #define LOG_NEWS        (7<<3)  /* network news subsystem */
00095 #define LOG_UUCP        (8<<3)  /* UUCP subsystem */
00096 #define LOG_CRON        (9<<3)  /* clock daemon */
00097 #define LOG_AUTHPRIV    (10<<3) /* security/authorization messages (private) */
00098                                 /* Facility #10 clashes in DEC UNIX, where */
00099                                 /* it's defined as LOG_MEGASAFE for AdvFS  */
00100                                 /* event logging.                          */
00101 #define LOG_FTP         (11<<3) /* ftp daemon */
00102 #define LOG_NTP         (12<<3) /* NTP subsystem */
00103
00104         /* other codes through 15 reserved for system use */
00105 #define LOG_LOCAL0      (16<<3) /* reserved for local use */
00106 #define LOG_LOCAL1      (17<<3) /* reserved for local use */
00107 #define LOG_LOCAL2      (18<<3) /* reserved for local use */
00108 #define LOG_LOCAL3      (19<<3) /* reserved for local use */
00109 #define LOG_LOCAL4      (20<<3) /* reserved for local use */
00110 #define LOG_LOCAL5      (21<<3) /* reserved for local use */
00111 #define LOG_LOCAL6      (22<<3) /* reserved for local use */
00112 #define LOG_LOCAL7      (23<<3) /* reserved for local use */
00113
00114 #define LOG_NFACILITIES 24      /* current number of facilities */
00115 #define LOG_FACMASK     0x03f8  /* mask to extract facility part */
00116                                 /* facility of pri */
00117 #define LOG_FAC(p)      (((p) & LOG_FACMASK) >> 3)
00118
00119 extern CODE facilitynames[24];
00120
00121 /*
00122  * arguments to setlogmask.
00123  */
00124 #define LOG_MASK(pri)   (1 << (pri))            /* mask for one priority */
00125 #define LOG_UPTO(pri)   ((1 << ((pri)+1)) - 1)  /* all priorities through pri */
00126
00127 /*
00128  * Option flags for openlog.
00129  *
00130  * LOG_ODELAY no longer does anything.
00131  * LOG_NDELAY is the inverse of what it used to be.
00132  */
00133 #define LOG_PID         0x01    /* log the pid with each message */
00134 #define LOG_CONS        0x02    /* log on the console if errors in sending */
00135 #define LOG_ODELAY      0x04    /* delay open until first syslog() (default) */
00136 #define LOG_NDELAY      0x08    /* don't delay open */
00137 #define LOG_NOWAIT      0x10    /* don't wait for console forks: DEPRECATED */
00138 #define LOG_PERROR      0x20    /* log to stderr as well */
00139
00140 #include <stdarg.h>
00141
00142 #ifndef __SYS_W32API_H
00143 #include <sys/w32api.h>
00144 #endif
00145
00146 #ifndef __SYS_CDEFS_H
00147 #include <sys/cdefs.h>
00148 #endif
00149
00150 __BEGIN_DECLS
00151
00152 W32_FUNC void  closelog   (void);
00153 W32_FUNC void  openlog    (const char *, int, int);
00154 W32_FUNC int   setlogmask (int);
00155 W32_FUNC void  syslog     (int, const char *, ...);
00156 W32_FUNC void  vsyslog    (int, const char *, va_list);
00157
00158 __END_DECLS
00159
00160 #endif
Generated on Wed Jan 25 15:42:33 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/sys/UIO.H Source File

inc/sys/UIO.H

Go to the documentation of this file.
00001
00005 #ifndef __SYS_UIO_H
00006 #define __SYS_UIO_H
00007
00008 /* This dummy header is required while building e.g. tcpdump
00009  */
00010
00011 #endif
Generated on Wed Jan 25 15:42:33 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/sys/W32API.H Source File

inc/sys/W32API.H

Go to the documentation of this file.
00001
00005 #ifndef __SYS_W32API_H
00006 #define __SYS_W32API_H
00007
00008 #if !defined(_WATT32_FAKE_WINSOCK_H) && (defined(_WINSOCK_H) || defined(_WINSOCKAPI_))
00009   #error Never include the real <winsock.h> in Watt-32 programs.
00010   #error Change your include-path so the fake <winsock.h> gets included first.
00011 #endif
00012
00013 #if !defined(_WATT32_FAKE_WINSOCK2_H) && (defined(_WINSOCK2_H) || defined(_WINSOCK2API_))
00014   #error Never include the real <winsock2.h> in Watt-32 programs.
00015   #error Change your include-path so the fake <winsock2.h> gets included first.
00016 #endif
00017
00018 #if !defined(_WATT32_FAKE_WS2TCPIP_H) && defined(_WS2TCPIP_H)
00019   #error Never include the real <ws2tcpip.h> in Watt-32 programs.
00020   #error Change your include-path so the fake <ws2tcpip.h> gets included first.
00021 #endif
00022
00023 #if defined(WIN32) || defined(_WIN32)
00024   /* Don't include the real <winsock*.h> */
00025   #define _WINSOCKAPI_
00026   #define _WINSOCK2API_
00027   #define _WINSOCK_H
00028   #define _WINSOCK2_H
00029   #ifndef WIN32_LEAN_AND_MEAN
00030   #define WIN32_LEAN_AND_MEAN
00031   #endif
00032   #include <windows.h>
00033 #endif
00034
00035 /*
00036  * For non-Win32 targets the .\util\mkimp program (a small C-preprocessor)
00037  * is meant to search all headers for W32_FUNC/W32_DATA prefixes. All
00038  * functions with a W32_FUNC prefix will produce an export stub function.
00039  * See dj_dxe.mak. Very experimental at the moment.
00040  *
00041  * Note: only a small subset of the Winsock extensions are implemented in
00042  *       watt-32.dll (hardly any WSA*() functions yet).
00043  */
00044 #if (defined(WIN32) || defined(_WIN32)) && !defined(WATT32_STATIC)
00045   #if defined(WATT32_BUILD)
00046     #define W32_FUNC  extern __declspec(dllexport)
00047     #define W32_DATA  extern __declspec(dllexport)
00048   #else
00049     #define W32_FUNC  extern __declspec(dllimport)
00050     #define W32_DATA  extern __declspec(dllimport)
00051   #endif
00052 #else
00053   #define W32_FUNC  extern
00054   #define W32_DATA  extern
00055 #endif
00056
00057 /*
00058  * W32_CALL is *not* defined to `stdcall' due to a bug in MingW's
00059  * linker. This bug prevents a MingW generated WATT-32.DLL from
00060  * being used by e.g. a MSVC program.
00061  * Ref. http://sources.redhat.com/bugzilla/show_bug.cgi?id=351
00062  * (last paragraph)
00063  */
00064 #if (defined(WIN32) || defined(_WIN32)) && 0
00065   #define W32_CALL  __stdcall /* maybe __fastcall instead for MSVC? */
00066 #else
00067   #define W32_CALL
00068 #endif
00069
00070 #endif
00071
Generated on Wed Jan 25 15:42:33 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/sys/WERRNO.H Source File

inc/sys/WERRNO.H

Go to the documentation of this file.
00001
00009 #ifndef __SYS_WERRNO_H
00010 #define __SYS_WERRNO_H
00011
00012 /* When doing "gcc -MM" with gcc 3.0 we must include <sys/version.h>
00013  * (via stdio.h) in order for __DJGPP__ to be defined
00014  */
00015 #include <stdio.h>
00016 #include <errno.h>
00017
00018 #ifndef __SYS_W32API_H
00019 #include <sys/w32api.h>
00020 #endif
00021
00022 /* Hack: fix for compiling with djgpp 2.04, but
00023  *       ./util/dj_err.exe was compiled with 2.03
00024  */
00025 #if defined(MIXING_DJGPP_203_AND_204)
00026 #undef ELOOP
00027 #endif
00028
00029 #if defined(__MINGW32__)
00030   #include <sys/mingw32.err>
00031
00032 #elif defined(__HIGHC__)
00033   #undef EDEADLK
00034   #undef EDEADLOCK
00035   #include <sys/highc.err>
00036
00037 #elif defined(__BORLANDC__)
00038   #ifdef __FLAT__
00039   #undef ENAMETOOLONG  /* bcc32 4.0 */
00040   #endif
00041   #ifdef _WIN32
00042   #undef ENOTEMPTY
00043   #endif
00044   #include <sys/borlandc.err>
00045
00046 #elif defined(__TURBOC__)
00047   #include <sys/turboc.err>
00048
00049 #elif defined(__WATCOMC__)
00050   #include <sys/watcom.err>
00051
00052 #elif defined(__DJGPP__)
00053   #include <sys/djgpp.err>
00054
00055 #elif defined(__DMC__)                        /* Digital Mars Compiler */
00056   #include <sys/digmars.err>
00057
00058 #elif defined(_MSC_VER) && (_MSC_VER <= 800)  /* MSC 8.0 or older */
00059   #include <sys/quickc.err>
00060
00061 #elif defined(_MSC_VER) && (_MSC_VER > 800)   /* Visual C on Windows */
00062   #undef EDEADLOCK
00063   #include <sys/visualc.err>
00064
00065 #elif defined(__CCDL__)                       /* LadSoft's cc386.exe */
00066   #include <sys/ladsoft.err>
00067
00068 #elif defined(__LCC__)
00069   #include <sys/lcc.err>
00070
00071 #elif defined(__POCC__)
00072   #include <sys/pellesc.err>
00073
00074 #else
00075   #error Unknown target in <sys/werrno.h>.
00076 #endif
00077
00078 /*
00079  * Ugly hack ahead. Someone tell me a better way, but
00080  * errno and friends are macros on Windows. Redefine them
00081  * to point to our variables.
00082  *
00083  * On Windows, the usual 'errno' is a macro "(*_errno)()" that
00084  * is problematic to use as a lvalue.
00085  * On other platforms we modify the global 'errno' variable directly.
00086  * (see SOCK_ERRNO() in misc.h). So no need to redefine it in any way.
00087  */
00088
00089 W32_DATA int   _w32_errno;
00090 W32_DATA int   _w32_sys_nerr;
00091 W32_DATA char *_w32_sys_errlist[];
00092
00093 #if 0
00094   #undef  sys_nerr
00095   #define sys_nerr      _w32_sys_nerr
00096
00097   #undef  _sys_nerr
00098   #define _sys_nerr     _w32_sys_nerr
00099
00100   #undef  __sys_nerr
00101   #define __sys_nerr    _w32_sys_nerr
00102
00103   #undef  sys_errlist
00104   #define sys_errlist   _w32_sys_errlist
00105
00106   #undef  _sys_errlist
00107   #define _sys_errlist  _w32_sys_errlist
00108
00109   #undef  __sys_errlist
00110   #define __sys_errlist _w32_sys_errlist
00111 #endif
00112
00113 /*
00114  * Incase you have trouble with duplicate defined symbols,
00115  * make sure the "*_s()" versions are referenced before normal
00116  * perror() and strerror() in your C-library.
00117  */
00118 W32_FUNC void  perror_s   (const char *str);
00119 W32_FUNC char *strerror_s (int errnum);
00120
00121 #if defined(__cplusplus)  /* Damn C++ */
00122   #include <stdlib.h>
00123   #include <string.h>
00124
00125 #elif !defined(_MSC_VER) && !defined(WIN32)
00126   #if !defined(_INC_STDLIB) && !defined(_STDLIB_H_) && !defined(_STDIO_H)
00127   W32_FUNC void perror (const char *str);
00128   #endif
00129
00130   #if !defined(_INC_STRING) && !defined(_STRING_H) && !defined(_STRING_H_)
00131   W32_FUNC char *strerror (int errnum);
00132   #endif
00133 #endif
00134
00135 #if defined(WIN32) || defined(_WIN32)
00136   W32_FUNC int  __stdcall WSAGetLastError (void);
00137   W32_FUNC void __stdcall WSASetLastError (int err);
00138 #endif
00139
00140 #endif  /* __SYS_WERRNO_H */
00141
Generated on Wed Jan 25 15:42:33 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/sys/WTIME.H Source File

inc/sys/WTIME.H

Go to the documentation of this file.
00001
00006 #ifndef __SYS_WTIME_H
00007 #define __SYS_WTIME_H
00008
00009 /*
00010  * The naming <sys/wtime.h> is required for those compilers that
00011  * have <sys/time.h> in the usual place but doesn't define
00012  * the following.
00013  */
00014
00015 #include <time.h>
00016
00017 #ifdef __BORLANDC__
00018 #undef timezone   /* a macro in bcc 5+ */
00019 #endif
00020
00021 #ifndef __SYS_W32API_H
00022 #include <sys/w32api.h>
00023 #endif
00024
00025 #ifndef __SYS_CDEFS_H
00026 #include <sys/cdefs.h>
00027 #endif
00028
00029 #if defined(__DJGPP__)
00030   #include <sys/time.h>
00031   #include <sys/times.h>
00032
00033 #elif defined(__MINGW32__)
00034   #include <sys/time.h>
00035
00036 #else
00037   struct timeval {
00038          time_t tv_sec;
00039          long   tv_usec;
00040        };
00041   #define STRUCT_TIMEVAL_DEFINED
00042 #endif
00043
00044 #if !defined(__DJGPP__)
00045   struct timezone {
00046          int tz_minuteswest;
00047          int tz_dsttime;
00048        };
00049
00050   struct tms {
00051          unsigned long tms_utime;
00052          unsigned long tms_cstime;
00053          unsigned long tms_cutime;
00054          unsigned long tms_stime;
00055        };
00056   #define STRUCT_TIMEZONE_DEFINED
00057   #define STRUCT_TMS_DEFINED
00058
00059   __BEGIN_DECLS
00060
00061   #define ITIMER_REAL  0
00062   #define ITIMER_PROF  1
00063
00064   struct itimerval {
00065          struct timeval it_interval;  /* timer interval */
00066          struct timeval it_value;     /* current value */
00067        };
00068
00069   W32_FUNC int getitimer (int, struct itimerval *);
00070   W32_FUNC int setitimer (int, struct itimerval *, struct itimerval *);
00071
00072   W32_FUNC int gettimeofday (struct timeval *tp, struct timezone *tz);
00073
00074   __END_DECLS
00075
00076 #endif      /* !__DJGPP__ */
00077
00078 #if !defined(_STRUCT_TIMESPEC) && !defined(_pthread_signal_h)
00079   #define _STRUCT_TIMESPEC
00080   struct timespec {
00081          time_t tv_sec;
00082          long   tv_nsec;
00083        };
00084 #endif
00085
00086 #ifndef HZ
00087 #define HZ 18.2F
00088 #endif
00089
00090 __BEGIN_DECLS
00091
00092 W32_FUNC unsigned long net_times (struct tms *buffer);
00093 W32_FUNC int           gettimeofday2 (struct timeval *tv, struct timezone *tz);
00094
00095 __END_DECLS
00096
00097 /*
00098  * Operations on timevals.
00099  *
00100  * NB: timercmp does not work for >= or <=.
00101  */
00102 #ifndef timerisset
00103   #define timerisset(tvp)         ((tvp)->tv_sec || (tvp)->tv_usec)
00104
00105   #define timercmp(tvp, uvp, cmp) ((tvp)->tv_sec cmp (uvp)->tv_sec || \
00106                                    ((tvp)->tv_sec == (uvp)->tv_sec &&  \
00107                                     (tvp)->tv_usec cmp (uvp)->tv_usec))
00108
00109   #define timerclear(tvp)         (tvp)->tv_sec = (tvp)->tv_usec = 0
00110 #endif
00111
00112 #endif  /* !__SYS_WTIME_H */
Generated on Wed Jan 25 15:42:33 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: inc/sys/WTYPES.H Source File

inc/sys/WTYPES.H

Go to the documentation of this file.
00001
00005 /*-
00006  * Copyright (c) 1982, 1986, 1991 The Regents of the University of California.
00007  * All rights reserved.
00008  *
00009  * Redistribution and use in source and binary forms, with or without
00010  * modification, are permitted provided that the following conditions
00011  * are met:
00012  * 1. Redistributions of source code must retain the above copyright
00013  *    notice, this list of conditions and the following disclaimer.
00014  * 2. Redistributions in binary form must reproduce the above copyright
00015  *    notice, this list of conditions and the following disclaimer in the
00016  *    documentation and/or other materials provided with the distribution.
00017  * 3. All advertising materials mentioning features or use of this software
00018  *    must display the following acknowledgement:
00019  *      This product includes software developed by the University of
00020  *      California, Berkeley and its contributors.
00021  * 4. Neither the name of the University nor the names of its contributors
00022  *    may be used to endorse or promote products derived from this software
00023  *    without specific prior written permission.
00024  *
00025  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
00026  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00027  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00028  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
00029  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00030  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00031  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00032  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00033  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00034  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00035  * SUCH DAMAGE.
00036  *
00037  *      @(#)types.h     7.17 (Berkeley) 5/6/91
00038  *      @(#)wtypes.h    Waterloo TCP/IP
00039  */
00040
00041 /*
00042  * the naming <sys/wtypes.h> is required for those compilers that
00043  * have <sys/types.h> in the usual place but doesn't define
00044  * the following types. This file is included from <sys/socket.h>,
00045  * <tcp.h> etc.
00046  */
00047
00048 #ifndef __SYS_WTYPES_H
00049 #define __SYS_WTYPES_H
00050
00051 #if 0                     /* No, that causes trouble */
00052   #undef  FD_SETSIZE
00053   #define FD_SETSIZE 512  /* use same FD_SETSIZE for all targets */
00054 #endif
00055
00056 #if defined(__DJGPP__) || defined(__DMC__) || defined(__MINGW32__) || defined(__POCC__)
00057   #include <sys/types.h>
00058 #endif
00059
00060 #if defined(__DJGPP__)
00061   #include <machine/endian.h>
00062 #endif
00063
00064 #if defined(__MINGW32__) || (defined(__DJGPP__) && DJGPP_MINOR >= 4) || \
00065     (defined(__WATCOMC__) && __WATCOMC__ >= 1230) ||  /* OW 1.3+ */     \
00066     defined(__POCC__)                                 /* PellesC */
00067   #undef  HAVE_STDINT_H
00068   #define HAVE_STDINT_H
00069   #include <stdint.h>   /* doesn't define 'u_char' etc. */
00070 #endif
00071
00072
00073 #if !defined(HAVE_U_INT64_T) && !defined(u_int64_t)
00074   #if defined(__HIGHC__) || defined(__GNUC__)
00075     typedef unsigned long long  u_int64_t;
00076     #define HAVE_U_INT64_T
00077
00078   #elif defined(__DMC__) && (__INTSIZE == 4)
00079     typedef unsigned long long  u_int64_t;
00080     #define HAVE_U_INT64_T
00081
00082   #elif defined(__WATCOMC__) && defined(__WATCOM_INT64__)
00083     typedef unsigned __int64  u_int64_t;
00084     #define HAVE_U_INT64_T
00085
00086   #elif (defined(_MSC_VER) && (_MSC_VER >= 900)) || defined(__POCC__)
00087     typedef unsigned __int64  u_int64_t;
00088     #define HAVE_U_INT64_T
00089   #endif
00090 #endif
00091
00092 #if !defined(__GLIBC__)
00093   #if !defined(HAVE_U_CHAR) && !defined(u_char)
00094     typedef unsigned char  u_char;
00095     #define HAVE_U_CHAR
00096   #endif
00097
00098   #if !defined(HAVE_U_SHORT) && !defined(u_short)
00099     typedef unsigned short  u_short;
00100     #define HAVE_U_SHORT
00101   #endif
00102
00103   #if !defined(HAVE_USHORT) && !defined(ushort)
00104     typedef unsigned short  ushort;   /* SysV compatibility */
00105     #define HAVE_USHORT
00106   #endif
00107
00108   #if !defined(HAVE_U_LONG) && !defined(u_long)
00109     typedef unsigned long  u_long;
00110     #define HAVE_U_LONG
00111   #endif
00112
00113   #if !defined(HAVE_U_INT) && !defined(u_int)
00114     #if defined(__SMALL__) || defined(__LARGE__)
00115       typedef unsigned long u_int;  /* too many headers assumes u_int is >=32-bit */
00116     #else
00117       typedef unsigned int  u_int;
00118     #endif
00119     #define HAVE_U_INT
00120   #endif
00121
00122   #if !defined(HAVE_CADDR_T) && !defined(caddr_t)
00123     typedef unsigned long  caddr_t;
00124     #define HAVE_CADDR_T
00125   #endif
00126 #endif
00127
00128 #if !defined(HAVE_U_INT8_T) && !defined(u_int8_t)
00129   typedef unsigned char  u_int8_t;
00130 #endif
00131
00132 #if !defined(HAVE_U_INT16_T) && !defined(u_int16_t)
00133   typedef unsigned short  u_int16_t;
00134 #endif
00135
00136 #if !defined(HAVE_U_INT32_T) && !defined(u_int32_t)
00137   typedef unsigned long  u_int32_t;
00138 #endif
00139
00140 #if !defined(HAVE_STDINT_H)
00141   #if !defined(HAVE_INT16_T) && !defined(int16_t)
00142     typedef short  int16_t;
00143     #define HAVE_INT16_T
00144   #endif
00145
00146   #if !defined(HAVE_INT32_T) && !defined(int32_t)
00147     typedef long  int32_t;
00148     #define HAVE_INT32_T
00149   #endif
00150 #endif
00151
00152 #if !defined(HAVE_U_QUAD_T) && !defined(u_quad_t)
00153   #define HAVE_U_QUAD_T
00154   #ifdef HAVE_U_INT64_T
00155     #define u_quad_t  u_int64_t
00156   #else
00157     #define u_quad_t  unsigned long
00158   #endif
00159 #endif
00160
00161 #if !defined(IOVEC_DEFINED)
00162   #define IOVEC_DEFINED
00163   struct iovec {
00164          void *iov_base;
00165          int   iov_len;
00166        };
00167 #endif
00168
00169
00170 #define __BIT_TYPES_DEFINED__
00171
00172 #if !defined(FD_SET)  /* not djgpp */
00173
00174   #undef  FD_SETSIZE
00175   #define FD_SETSIZE    512
00176   #define FD_SET(n, p)  ((p)->fd_bits[(n)/8] |=  (1 << ((n) & 7)))
00177   #define FD_CLR(n, p)  ((p)->fd_bits[(n)/8] &= ~(1 << ((n) & 7)))
00178   #define FD_ISSET(n,p) ((p)->fd_bits[(n)/8] &   (1 << ((n) & 7)))
00179   #define FD_ZERO(p)    memset ((void*)(p), 0, sizeof(*(p)))
00180
00181   typedef struct fd_set {
00182           unsigned char fd_bits [(FD_SETSIZE+7)/8];
00183         } fd_set;
00184 #endif
00185
00186 #ifndef LITTLE_ENDIAN
00187 #define LITTLE_ENDIAN 1234
00188 #endif
00189
00190 #ifndef BIG_ENDIAN
00191 #define BIG_ENDIAN    4321
00192 #endif
00193
00194 #if defined(BIG_ENDIAN_MACHINE) || defined(USE_BIGENDIAN)
00195   #define BYTE_ORDER  BIG_ENDIAN
00196 #else
00197   #define BYTE_ORDER  LITTLE_ENDIAN
00198 #endif
00199
00200 #endif
Generated on Wed Jan 25 15:42:33 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/ACCEPT.C Source File

SRC/ACCEPT.C

Go to the documentation of this file.
00001
00005 /*  BSD sockets functionality for Waterloo TCP/IP
00006  *
00007  *  Copyright (c) 1997-2002 Gisle Vanem <giva@bgnett.no>
00008  *
00009  *  Redistribution and use in source and binary forms, with or without
00010  *  modification, are permitted provided that the following conditions
00011  *  are met:
00012  *  1. Redistributions of source code must retain the above copyright
00013  *     notice, this list of conditions and the following disclaimer.
00014  *  2. Redistributions in binary form must reproduce the above copyright
00015  *     notice, this list of conditions and the following disclaimer in the
00016  *     documentation and/or other materials provided with the distribution.
00017  *  3. All advertising materials mentioning features or use of this software
00018  *     must display the following acknowledgement:
00019  *       This product includes software developed by Gisle Vanem
00020  *       Bergen, Norway.
00021  *
00022  *  THIS SOFTWARE IS PROVIDED BY ME (Gisle Vanem) AND CONTRIBUTORS ``AS IS''
00023  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00024  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00025  *  ARE DISCLAIMED.  IN NO EVENT SHALL I OR CONTRIBUTORS BE LIABLE FOR ANY
00026  *  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00027  *  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00028  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00029  *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00030  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00031  *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00032  *
00033  *  Version
00034  *
00035  *  0.5 : Dec 18, 1997 : G. Vanem - created
00036  *  0.6 : Sep 16, 1999 : fixes by Claus Oberste-Brandenburg
00037  *  0.7 : Nov 22, 1999 : G. Vanem - simplified the socket 'dup' action.
00038  *                       Simply allocate a new 'remote_addr'.
00039  *                       Poll backlogged listen-queue in accept-loop.
00040  *  0.8 : Dec 15, 1999 : Listen-queue filled in _sock_append() and TCB
00041  *                       is cloned when SYN is received in tcp_listen_state().
00042  *  0.9 : Mar 09, 2000 : Plugged a memory leak in dup_bind() where 'tcp_sock'
00043  *                       memory from socket() wasn't free'ed. Thanks to
00044  *                       Francisco Pastor <fpastor.etra-id@etra.es> for
00045  *                       finding this.
00046  *  0.91: Jun 01, 2000 : Rearranged accept-loop for EWOULDBLOCK with no
00047  *                       listen_queue element (dropped 'continue' construct).
00048  *  0.92: Aug 07, 2002 : G. Vanem - added AF_INET6 support
00049  */
00050
00051 #include "socket.h"
00052
00053 #if defined(USE_BSD_API)
00054
00055 static int  dup_bind   (Socket *socket, Socket **clone, int idx);
00056 static int  alloc_addr (Socket *socket, Socket  *clone);
00057 static void listen_free(Socket *socket, int idx);
00058
00059
00060 int W32_CALL accept (int s, struct sockaddr *addr, int *addrlen)
00061 {
00062   Socket  *socket, *clone = NULL;
00063   volatile DWORD   timeout;
00064   volatile int     newsock = -1;
00065   volatile int     que_idx;
00066   volatile int     maxconn;
00067   volatile BOOL    is_ip6;
00068
00069   socket = _socklist_find (s);
00070
00071   SOCK_PROLOGUE (socket, "\naccept:%d", s);
00072
00073   is_ip6 = (socket->so_family == AF_INET6);
00074
00075   if (socket->so_type != SOCK_STREAM)
00076   {
00077     SOCK_DEBUGF ((", EOPNOTSUPP"));
00078     SOCK_ERRNO (EOPNOTSUPP);
00079     return (-1);
00080   }
00081
00082   if (!socket->local_addr)
00083   {
00084     SOCK_DEBUGF ((", not bound"));
00085     SOCK_ERRNO (ENOTCONN);
00086     return (-1);
00087   }
00088
00089   if (!(socket->so_options & SO_ACCEPTCONN)) /* listen() not called */
00090   {
00091     SOCK_DEBUGF ((", not SO_ACCEPTCONN"));
00092     SOCK_ERRNO (EINVAL);
00093     return (-1);
00094   }
00095
00096   if (!(socket->so_state & (SS_ISLISTENING | SS_ISCONNECTING)))
00097   {
00098     SOCK_DEBUGF ((", not listening"));
00099     SOCK_ERRNO (ENOTCONN);
00100     return (-1);
00101   }
00102
00103   if (addr && addrlen)
00104   {
00105     int sa_len = is_ip6 ? sizeof(struct sockaddr_in6) :
00106                           sizeof(struct sockaddr_in);
00107     if (*addrlen < sa_len)
00108     {
00109       SOCK_DEBUGF ((", EFAULT"));
00110       SOCK_ERRNO (EFAULT);
00111       return (-1);
00112     }
00113     VERIFY_RW (addr, sa_len);
00114   }
00115
00116   /* Get max possible TCBs on listen-queue.
00117    * Some (or all) may be NULL until a SYN comes in.
00118    */
00119   maxconn = socket->backlog;
00120   if (maxconn < 1 || maxconn > SOMAXCONN)
00121   {
00122     SOCK_FATAL (("%s(%d): Illegal socket backlog %d\n",
00123                 __FILE__, __LINE__, maxconn));
00124     SOCK_ERRNO (EINVAL);
00125     return (-1);
00126   }
00127
00128   /* A listening socket should have infinite timeout unless
00129    * option SO_RCVTIMEO used. I.e. socket->timeout = 0.
00130    * Ref. listen.c.
00131    */
00132   if (socket->timeout)
00133        timeout = set_timeout (1000 * socket->timeout);
00134   else timeout = 0UL;
00135
00136   if (_sock_sig_setup() < 0)
00137   {
00138     SOCK_ERRNO (EINTR);
00139     goto accept_fail;
00140   }
00141
00142   _sock_crit_start();
00143
00144   /* Loop over all queue-slots and accept first connected TCB
00145    */
00146   for (que_idx = 0; ; que_idx = (que_idx+1) % maxconn)
00147   {
00148     _tcp_Socket *sk = socket->listen_queue [que_idx];
00149
00150     tcp_tick (NULL);
00151
00152     WATT_YIELD();
00153
00154     if (_sock_sig_pending())
00155     {
00156       SOCK_DEBUGF ((", EINTR"));
00157       SOCK_ERRNO (EINTR);
00158       goto accept_fail;
00159     }
00160
00161     /* No SYNs received yet. This shouldn't happen if we called 'accept()'
00162      * after 'select_s()' said that socket was readable. (At least one
00163      * connection on the listen-queue).
00164      */
00165     if (sk)
00166     {
00167       /* This could happen if 'accept()' was called too long after connection
00168        * was established and then closed by peer. This could also happen if
00169        * someone did a portscan on us. I.e. he sent 'SYN', we replied with
00170        * 'SYN+ACK' and he never sent an 'ACK'. Thus we timeout in
00171        * 'tcp_Retransmitter()' and abort the TCB.
00172        *
00173        * Queue slot is in any case ready for another 'SYN' to come and be
00174        * handled by '_sock_append()'.
00175        */
00176       if (sk->state >= tcp_StateESTCL && sk->ip_type == 0)
00177       {
00178         SOCK_DEBUGF ((", aborted TCB (idx %d)", que_idx));
00179         listen_free (socket, que_idx);
00180         continue;
00181       }
00182
00186       if (sk->state >= tcp_StateESTAB && sk->state < tcp_StateCLOSED)
00187       {
00188         SOCK_DEBUGF ((", connected! (idx %d)", que_idx));
00189         break;
00190       }
00191     }
00192
00193     /* We've polled all listen-queue slots and none are connected.
00194      * Return fail if socket is non-blocking.
00195      */
00196     if (que_idx == maxconn-1 && (socket->so_state & SS_NBIO))
00197     {
00198       SOCK_DEBUGF ((", would block"));
00199       SOCK_ERRNO (EWOULDBLOCK);
00200       goto accept_fail;
00201     }
00202
00203     if (chk_timeout(timeout))
00204     {
00205       SOCK_DEBUGF ((", ETIMEDOUT"));
00206       SOCK_ERRNO (ETIMEDOUT);
00207       goto accept_fail;
00208     }
00209   }
00210
00211   /* We're here only when above 'tcp_established()' succeeded.
00212    * Now duplicate 'socket' into a new listening socket 'clone'
00213    * with handle 'newsock'.
00214    */
00215   SOCK_ENTER_SCOPE();
00216   newsock = dup_bind (socket, &clone, que_idx);
00217   if (newsock < 0)
00218      goto accept_fail;
00219
00220   if (!alloc_addr(socket, clone))
00221   {
00222     SOCK_DEL_FD (newsock);
00223     goto accept_fail;
00224   }
00225
00226   /* Clone is connected, but *not* listening/accepting.
00227    * Note: other 'so_state' bits from parent is unchanged.
00228    *       e.g. clone may be non-blocking.
00229    */
00230   clone->so_state   |=  SS_ISCONNECTED;
00231   clone->so_state   &= ~(SS_ISLISTENING | SS_ISCONNECTING);
00232   clone->so_options &= ~SO_ACCEPTCONN;
00233
00234   /* Prevent a PUSH on first segment sent.
00235    */
00236   sock_noflush ((sock_type*)clone->tcp_sock);
00237
00238 #if defined(USE_IPV6)
00239   if (is_ip6)
00240   {
00241     struct sockaddr_in6 *ra = (struct sockaddr_in6*)clone->remote_addr;
00242
00243     SOCK_DEBUGF (("\nremote %s (%d)",
00244                   _inet6_ntoa (&ra->sin6_addr), ntohs(ra->sin6_port)));
00245     ARGSUSED (ra);
00246   }
00247   else
00248 #endif
00249     SOCK_DEBUGF (("\nremote %s (%d)",
00250                   inet_ntoa (clone->remote_addr->sin_addr),
00251                   ntohs (clone->remote_addr->sin_port)));
00252
00253   if (addr && addrlen)
00254   {
00255 #if defined(USE_IPV6)
00256     if (socket->so_family == AF_INET6)
00257     {
00258       struct sockaddr_in6 *sa = (struct sockaddr_in6*)addr;
00259
00260       memset (sa, 0, sizeof(*sa));
00261       memcpy (&sa->sin6_addr, &clone->remote_addr->sin_addr, sizeof(sa->sin6_addr));
00262       sa->sin6_family   = AF_INET6;
00263       sa->sin6_port     = clone->remote_addr->sin_port;
00264       sa->sin6_flowinfo = sa->sin6_scope_id = 0;  /* !! */
00265       *addrlen = sizeof(*sa);
00266     }
00267     else
00268 #endif
00269     {
00270       struct sockaddr_in *sa = (struct sockaddr_in*)addr;
00271
00272       sa->sin_family = AF_INET;
00273       sa->sin_port   = clone->remote_addr->sin_port;
00274       sa->sin_addr   = clone->remote_addr->sin_addr;
00275       memset (sa->sin_zero, 0, sizeof(sa->sin_zero));
00276       *addrlen = sizeof(*sa);
00277     }
00278   }
00279
00280   SOCK_LEAVE_SCOPE();
00281   _sock_crit_stop();
00282   _sock_sig_restore();
00283   return (newsock);
00284
00285 accept_fail:
00286   SOCK_LEAVE_SCOPE();
00287   _sock_crit_stop();
00288   _sock_sig_restore();
00289   return (-1);
00290 }
00291
00292
00293 /*
00294  * Duplicate a SOCK_STREAM 'socket' to '*newconn'. Doesn't set
00295  * local/remote addresses. Transfer TCB from listen-queue[idx] of
00296  * 'socket' to TCB of 'clone'.
00297  */
00298 static int dup_bind (Socket *sock, Socket **newconn, int idx)
00299 {
00300   Socket *clone;
00301   int     fd = socket (sock->so_family, SOCK_STREAM, IPPROTO_TCP);
00302
00303   if (fd < 0)
00304      return (fd);
00305
00306   clone = _socklist_find (fd);  /* cannot fail */
00307
00308   /* child gets state from parent
00309    */
00310   clone->timeout    = sock->timeout;
00311   clone->close_time = sock->close_time;
00312   clone->keepalive  = sock->keepalive;
00313   clone->ip_tos     = sock->ip_tos;
00314   clone->ip_ttl     = sock->ip_ttl;
00315   clone->so_state   = sock->so_state;
00316   clone->so_options = sock->so_options;
00317
00318   /* TCB for clone is from listen-queue[idx]; free tcp_sock from
00319    * socket(). Reuse listen-queue slot for another SYN.
00320    */
00321   free (clone->tcp_sock);
00322   clone->tcp_sock = sock->listen_queue[idx];
00323   sock->listen_queue [idx] = NULL;
00324   sock->syn_timestamp[idx] = 0UL;
00325   *newconn = clone;
00326   return (fd);
00327 }
00328
00329 /*
00330  * Allocate and fill local/remote addresses for 'clone'.
00331  * Take local address from 'socket', and remote address from
00332  * TCB of clone.
00333  */
00334 static int alloc_addr (Socket *socket, Socket *clone)
00335 {
00336   BOOL is_ip6 = (socket->so_family == AF_INET6);
00337   int  sa_len = is_ip6 ? sizeof(struct sockaddr_in6) :
00338                          sizeof(struct sockaddr_in);
00339
00340   clone->local_addr = (struct sockaddr_in*) SOCK_CALLOC (sa_len);
00341   if (!clone->local_addr)
00342   {
00343     SOCK_DEBUGF ((", ENOMEM"));
00344     SOCK_ERRNO (ENOMEM);
00345     return (0);
00346   }
00347
00348   clone->remote_addr = (struct sockaddr_in*) SOCK_CALLOC (sa_len);
00349   if (!clone->remote_addr)
00350   {
00351     SOCK_DEBUGF ((", ENOMEM"));
00352     SOCK_ERRNO (ENOMEM);
00353     free (clone->local_addr);
00354     clone->local_addr = NULL;
00355     return (0);
00356   }
00357
00358 #if defined(USE_IPV6)
00359   if (is_ip6)
00360   {
00361     struct sockaddr_in6 *la = (struct sockaddr_in6*) clone->local_addr;
00362     struct sockaddr_in6 *ra = (struct sockaddr_in6*) clone->remote_addr;
00363     struct sockaddr_in6 *sa = (struct sockaddr_in6*) socket->local_addr;
00364
00365     la->sin6_family = AF_INET6;
00366     la->sin6_port   = sa->sin6_port;
00367     memcpy (&la->sin6_addr, &sa->sin6_addr, sizeof(la->sin6_addr));
00368
00369     ra->sin6_family = AF_INET6;
00370     ra->sin6_port   = htons (clone->tcp_sock->hisport);
00371     memcpy (&ra->sin6_addr, &clone->tcp_sock->his6addr, sizeof(ra->sin6_addr));
00372   }
00373   else
00374 #endif
00375   {
00376     struct in_addr peer;
00377
00378     peer.s_addr = htonl (clone->tcp_sock->hisaddr);
00379     clone->local_addr->sin_family  = AF_INET;
00380     clone->local_addr->sin_port    = socket->local_addr->sin_port;
00381     clone->local_addr->sin_addr    = socket->local_addr->sin_addr;
00382
00383     clone->remote_addr->sin_family = AF_INET;
00384     clone->remote_addr->sin_port   = htons (clone->tcp_sock->hisport);
00385     clone->remote_addr->sin_addr   = peer;
00386   }
00387   return (1);
00388 }
00389
00390 /*
00391  * Release a listen-queue slot and associated memory.
00392  */
00393 static void listen_free (Socket *socket, int idx)
00394 {
00395   _tcp_Socket *tcb = socket->listen_queue [idx];
00396
00397   _tcp_unthread (tcb, TRUE);
00398   _sock_free_rcv_buf ((sock_type*)tcb); /* free large Rx buffer */
00399   free (tcb);
00400   socket->listen_queue [idx] = NULL;
00401 }
00402
00416 int _sock_append (_tcp_Socket **tcp)
00417 {
00418   _tcp_Socket *clone;
00419   _tcp_Socket *orig = *tcp;
00420   Socket      *sock = NULL;   /* associated socket for 'orig' */
00421   int          i;
00422
00423   /* Lookup BSD-socket for WatTcp TCB
00424    */
00425   if (!_bsd_socket_hook ||
00426       (sock = (*_bsd_socket_hook)(BSO_FIND_SOCK,orig)) == NULL)
00427   {
00428     /* This could be a native Wattcp socket. Pass it on in
00429      * tcp_listen_state() for further processing.
00430      */
00431     SOCK_DEBUGF (("\n  sock_append: not found!?"));
00432     return (1);
00433   }
00434
00435   SOCK_DEBUGF (("\n  sock_append:%d", sock->fd));
00436
00437   if (!(sock->so_options & SO_ACCEPTCONN))
00438   {
00439     SOCK_DEBUGF ((", not SO_ACCEPTCONN"));
00440     return (0);  /* How could this happen (SYN attack)? */
00441   }
00442
00443   /* Find the first vacant slot for this clone
00444    */
00445   for (i = 0; i < sock->backlog; i++)
00446       if (!sock->listen_queue[i])
00447          break;
00448
00451   if (i >= sock->backlog || i >= SOMAXCONN)
00452   {
00455     SOCK_DEBUGF ((", queue full (idx %d)", i));
00456     return (0);
00457   }
00458
00459   SOCK_DEBUGF ((", idx %d", i));
00460
00461   clone = (_tcp_Socket*) SOCK_CALLOC (sizeof(*clone));
00462   if (!clone)
00463   {
00464     SOCK_DEBUGF ((", ENOMEM"));
00465     return (0);
00466   }
00467
00468   /* Link in the semi-connected socket (SYN received, ACK will be sent)
00469    */
00470   sock->listen_queue[i]  = clone;
00471   sock->syn_timestamp[i] = set_timeout (0);
00472
00473   /* Copy the TCB to clone. Tx buffer of clone must not
00474    * be set to parent's Tx buffer.
00475    */
00476   memcpy (clone, orig, sizeof(*clone));
00477   clone->tx_data     = &clone->tx_buf[0];
00478   clone->tx_datalen  = 0;
00479   clone->max_tx_data = sizeof (clone->tx_buf) - 1;
00480
00481 #if defined(USE_DEBUG)          /* !!needs some work */
00482   clone->last_acknum[0] = orig->last_acknum[0];
00483   clone->last_acknum[1] = orig->last_acknum[1];
00484   clone->last_seqnum[0] = orig->last_seqnum[0];
00485   clone->last_seqnum[1] = orig->last_seqnum[1];
00486   orig->last_acknum[0]  = orig->last_acknum[1] = 0L;
00487   orig->last_seqnum[0]  = orig->last_seqnum[1] = 0L;
00488 #endif
00489
00490   /* Increase the TCP window (to 16kB by default)
00491    */
00492   _sock_set_rcv_buf ((sock_type*)clone, tcp_recv_win);
00493
00494   /* Undo what tcp_handler() and tcp_listen_state() did to
00495    * this listening socket.
00496    */
00497   orig->hisport = 0;
00498   orig->hisaddr = 0;
00499   orig->myaddr  = 0;
00500 #if defined(USE_IPV6)
00501   memset (&orig->my6addr, 0, sizeof(orig->my6addr));
00502 #endif
00503
00504   orig->send_next = INIT_SEQ();   /* set new ISS */
00505   orig->unhappy   = FALSE;
00506   CLR_PEER_MAC_ADDR (orig);
00507
00508   clone->next  = _tcp_allsocs;
00509   _tcp_allsocs = clone;         /* prepend clone to TCB-list */
00510   *tcp = clone;                 /* the new TCB is now the clone */
00511   return (1);
00512 }
00513
00514 /*
00515   A handy note from:
00516     http://help.netscape.com/kb/corporate/960513-73.html
00517
00518 Solaris 2.3, 2.4, and 2.5 have a listen backlog queue for incoming
00519 TCP/IP connections; its maximum length is 5 by default.  If you leave
00520 this set to the default, then you will frequently see connections to
00521 your web server time out under moderate loads, even though there are
00522 enough idle web server listener processes available to handle the
00523 connections and your Solaris system shows no other signs of resource
00524 saturation.
00525
00526 The listen backlog queue holds connections that are "half-open" (in
00527 the process of being opened), as well as connections that have been
00528 fully opened but have not yet been accepted by any local processes.
00529 This has no effect on the total number of open TCP/IP connections that
00530 your Solaris system can deal with at once; it only means that your
00531 system can't juggle more than five loose connections at a time, and
00532 any other connections that come in while Solaris is busy with five
00533 loose connections will be dropped and will time out on the client end.
00534
00535 On Solaris 2.3 and 2.4, you can bring the maximum queue length from 5
00536 up to 32 by using the "ndd" command, which must be run as root:
00537
00538     /usr/sbin/ndd -set /dev/tcp tcp_conn_req_max 32
00539
00540     It is theoretically possible to increase this number beyond 32,
00541     although this is not recommended.  If increasing the maximum length
00542     from 5 to 32 solved the problem temporarily for you but your web
00543     server's traffic has now increased to a point where the symptoms
00544     appear with the maximum queue length set to 32, then you should
00545     contact Sun for further help with this.
00546
00547     The Netscape servers on any Unix system will request a listen backlog
00548     queue length of 128 when they run; the operating system then reduces
00549     that to something it can handle.
00550
00551     Solaris 2.5 allows a maximum listen backlog queue length as high as
00552     1024 (and you can raise it in the same way), but it still defaults to
00553     a maximum queue length of 5.
00554
00555 */
00556
00557 #endif /* USE_BSD_API */
Generated on Wed Jan 25 15:42:34 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/ADR2ASC.C Source File

SRC/ADR2ASC.C

Go to the documentation of this file.
00001
00005 /*
00006  * Copyright 1996 Massachusetts Institute of Technology
00007  *
00008  * Permission to use, copy, modify, and distribute this software and
00009  * its documentation for any purpose and without fee is hereby
00010  * granted, provided that both the above copyright notice and this
00011  * permission notice appear in all copies, that both the above
00012  * copyright notice and this permission notice appear in all
00013  * supporting documentation, and that the name of M.I.T. not be used
00014  * in advertising or publicity pertaining to distribution of the
00015  * software without specific, written prior permission.  M.I.T. makes
00016  * no representations about the suitability of this software for any
00017  * purpose.  It is provided "as is" without express or implied
00018  * warranty.
00019  *
00020  * THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''.  M.I.T. DISCLAIMS
00021  * ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE,
00022  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
00023  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT
00024  * SHALL M.I.T. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00025  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00026  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
00027  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00028  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00029  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
00030  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00031  * SUCH DAMAGE.
00032  *
00033  *      $ANA: addr2ascii.c,v 1.1 1996/06/13 18:41:46 wollman Exp $
00034  *
00035  *  $Id: addr2ascii.c,v 1.2 1998/08/20 21:56:23 joel Exp $
00036  */
00037
00038 #include "socket.h"
00039
00040 #if defined(USE_BSD_API)
00041
00042 /*-
00043  * Convert a network address from binary to printable numeric format.
00044  * This API is copied from INRIA's IPv6 implementation, but it is a
00045  * bit bogus in two ways:
00046  *
00047  *      1) There is no value in passing both an address family and
00048  *         an address length; either one should imply the other,
00049  *         or we should be passing sockaddrs instead.
00050  *      2) There should by contrast be /added/ a length for the buffer
00051  *         that we pass in, so that programmers are spared the need to
00052  *         manually calculate (read: ``guess'') the maximum length.
00053  *
00054  * Flash: the API is also the same in the NRL implementation, and seems to
00055  * be some sort of standard, so we appear to be stuck with both the bad
00056  * naming and the poor choice of arguments.
00057  */
00058 char *addr2ascii (int af, const void *addrp, int len, char *buf)
00059 {
00060   static char staticbuf[64];    /* 64 for AF_LINK > 16 for AF_INET */
00061
00062   if (!buf)
00063      buf = staticbuf;
00064
00065   switch (af)
00066   {
00067     case AF_INET:
00068          if (len != sizeof (struct in_addr))
00069          {
00070            SOCK_ERRNO (ENAMETOOLONG);
00071            return (NULL);
00072          }
00073          strcpy (buf, inet_ntoa (*(const struct in_addr *) addrp));
00074          break;
00075
00076     case AF_LINK:
00077          if (len != sizeof (struct sockaddr_dl))
00078          {
00079            SOCK_ERRNO (ENAMETOOLONG);
00080            return (NULL);
00081          }
00082          strcpy (buf, link_ntoa ((const struct sockaddr_dl *) addrp));
00083          break;
00084
00085     default:
00086          SOCK_ERRNO (EPROTONOSUPPORT);
00087          return (NULL);
00088   }
00089   return (buf);
00090 }
00091 #endif
Generated on Wed Jan 25 15:42:34 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/ASC2ADR.C Source File

SRC/ASC2ADR.C

Go to the documentation of this file.
00001
00005 /* Copyright 1996 Massachusetts Institute of Technology
00006  *
00007  * Permission to use, copy, modify, and distribute this software and
00008  * its documentation for any purpose and without fee is hereby
00009  * granted, provided that both the above copyright notice and this
00010  * permission notice appear in all copies, that both the above
00011  * copyright notice and this permission notice appear in all
00012  * supporting documentation, and that the name of M.I.T. not be used
00013  * in advertising or publicity pertaining to distribution of the
00014  * software without specific, written prior permission.  M.I.T. makes
00015  * no representations about the suitability of this software for any
00016  * purpose.  It is provided "as is" without express or implied
00017  * warranty.
00018  *
00019  * THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''.  M.I.T. DISCLAIMS
00020  * ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE,
00021  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
00022  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT
00023  * SHALL M.I.T. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00024  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00025  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
00026  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00027  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00028  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
00029  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00030  * SUCH DAMAGE.
00031  *
00032  *      $ANA: ascii2addr.c,v 1.2 1996/06/13 18:46:02 wollman Exp $
00033  *
00034  *  $Id: ascii2addr.c,v 1.2 1998/08/20 21:56:23 joel Exp $
00035  */
00036
00037 #include "socket.h"
00038
00039 #if defined(USE_BSD_API)
00040
00041 int ascii2addr (int af, const char *ascii, void *result)
00042 {
00043   struct in_addr *ina;
00044   char   strbuf [4*sizeof("123")];  /* long enough for V4 only */
00045
00046   switch (af)
00047   {
00048     case AF_INET:
00049          ina = (struct in_addr*) result;
00050          strbuf[0] = '\0';
00051          strncat (strbuf, ascii, sizeof(strbuf)-1);
00052          if (inet_aton (strbuf, ina))
00053             return sizeof (*ina);
00054          SOCK_ERRNO (EINVAL);
00055          break;
00056
00057     case AF_LINK:
00058          link_addr (ascii, (struct sockaddr_dl*)result);
00059          /* oops... no way to detect failure */
00060          return sizeof (struct sockaddr_dl);
00061
00062 #if defined(USE_IPV6)
00063     case AF_INET6:
00064          return inet_pton (AF_INET6, ascii, result);
00065 #endif
00066
00067     default:
00068          SOCK_ERRNO (EPROTONOSUPPORT);
00069          break;
00070   }
00071   return (-1);
00072 }
00073 #endif
Generated on Wed Jan 25 15:42:34 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/ASMPKT.H Source File

SRC/ASMPKT.H

Go to the documentation of this file.
00001
00005 #ifndef _w32_ASMPKT_H
00006 #define _w32_ASMPKT_H
00007
00008 #if (DOSX == 0)                                  /* for real-mode targets */
00009   extern void far cdecl pkt_receiver_rm (void);  /* in asmpkt.asm */
00010
00011 #elif (DOSX & DOS4GW) && !defined(USE_FAST_PKT)  /* in asmpkt4.asm */
00012   extern WORD             cdecl asmpkt_size_chk;
00013   extern struct pkt_info *cdecl asmpkt_inf;
00014
00015   extern void cdecl pkt_receiver4_start (void);
00016   extern void cdecl pkt_receiver4_rm    (void);
00017   extern void cdecl pkt_receiver4_end   (void);
00018 #endif
00019
00020 #endif
00021
Generated on Wed Jan 25 15:42:34 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/BIND.C Source File

SRC/BIND.C

Go to the documentation of this file.
00001
00005 /*  BSD sockets functionality for Waterloo TCP/IP
00006  *
00007  *  Copyright (c) 1997-2002 Gisle Vanem <giva@bgnett.no>
00008  *
00009  *  Redistribution and use in source and binary forms, with or without
00010  *  modification, are permitted provided that the following conditions
00011  *  are met:
00012  *  1. Redistributions of source code must retain the above copyright
00013  *     notice, this list of conditions and the following disclaimer.
00014  *  2. Redistributions in binary form must reproduce the above copyright
00015  *     notice, this list of conditions and the following disclaimer in the
00016  *     documentation and/or other materials provided with the distribution.
00017  *  3. All advertising materials mentioning features or use of this software
00018  *     must display the following acknowledgement:
00019  *       This product includes software developed by Gisle Vanem
00020  *       Bergen, Norway.
00021  *
00022  *  THIS SOFTWARE IS PROVIDED BY ME (Gisle Vanem) AND CONTRIBUTORS ``AS IS''
00023  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00024  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00025  *  ARE DISCLAIMED.  IN NO EVENT SHALL I OR CONTRIBUTORS BE LIABLE FOR ANY
00026  *  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00027  *  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00028  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00029  *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00030  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00031  *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00032  *
00033  *  Version
00034  *
00035  *  0.5 : Dec 18, 1997 : G. Vanem - created
00036  *  0.6 : Aug 06, 2002 : G. Vanem - added AF_INET6 support
00037  */
00038
00039 #include "socket.h"
00040
00041 #if defined(USE_BSD_API)
00042
00043 /*
00044  * Bind:
00045  *  The purpose of bind is to fill in the information for the local IP
00046  *  address and local port (local_addr). In this respect, it is the
00047  *  opposite of connect(). connect() fills in the destination IP address
00048  *  and destination port (remote_addr).
00049  *  In most situations, one does not need to call bind().
00050  *
00051  *  Calling bind() on a SOCK_DGRAM socket and for multiple addresses
00052  *  ('myaddr->sin_addr.s_addr == INADDR_ANY') requires special attention:
00053  *  Wattcp's 'udp_handler()' doesn't store address information for
00054  *  broadcast.
00055  *
00056  *  We therefore install a 's->dataHandler' pointing to '_recvdaemon()'
00057  *  which queues up SOCK_DGRAM messages. This queue is polled (by
00058  *  'sock_recv_from') when we call 'receive()' on such a socket.
00059  *  Thus the '*from' address in 'receive()' will be correctly set to
00060  *  source address/port of peer.
00061  */
00062 int W32_CALL bind (int s, const struct sockaddr *myaddr, int namelen)
00063 {
00064   Socket              *socket = _socklist_find (s);
00065   struct sockaddr_in  *addr   = (struct sockaddr_in*) myaddr;
00066   struct sockaddr_in6 *addr6  = (struct sockaddr_in6*) myaddr;
00067   BOOL   bind_any, is_bcast, is_mcast, our_addr;
00068   WORD   local_port;
00069   BOOL   is_ip6;
00070   int    sa_len;
00071
00072   SOCK_PROLOGUE (socket, "\nbind:%d", s);
00073
00074   is_ip6 = (socket->so_family == AF_INET6);
00075   sa_len = is_ip6 ? sizeof(*addr6) : sizeof(*addr);
00076
00077   if (_sock_chk_sockaddr(socket, myaddr, namelen) < 0)
00078      return (-1);
00079
00080   if (socket->so_type == SOCK_STREAM)
00081   {
00082     if (is_ip6)
00083          is_mcast = IN6_IS_ADDR_MULTICAST (&addr6->sin6_addr);
00084     else is_mcast = IN_MULTICAST (ntohl(addr->sin_addr.s_addr));
00085     if (is_mcast)
00086     {
00087       SOCK_DEBUGF ((", EINVAL (mcast)"));
00088       SOCK_ERRNO (EINVAL);
00089       return (-1);
00090     }
00091   }
00092
00093   /* binding to any address/port on local machine?
00094    */
00095 #if defined(USE_IPV6)
00096   if (is_ip6)
00097   {
00098     our_addr = _ip6_is_local_addr (&addr6->sin6_addr);
00099     bind_any = IN6_ARE_ADDR_EQUAL (&addr6->sin6_addr, &in6addr_any);
00100     is_bcast = IN6_IS_ADDR_MC_GLOBAL (&addr6->sin6_addr);   /* ?? */
00101   }
00102   else
00103 #endif
00104   {
00105     our_addr = _ip4_is_local_addr (ntohl(addr->sin_addr.s_addr));
00106     bind_any = (addr->sin_addr.s_addr == INADDR_ANY);
00107     is_bcast = ((~addr->sin_addr.s_addr & ~sin_mask) == 0);
00108   }
00109
00110   if (socket->so_type == SOCK_STREAM &&
00111       !bind_any && !our_addr && !is_bcast)
00112   {
00113     SOCK_DEBUGF ((", EADDRNOTAVAIL"));
00114     SOCK_ERRNO (EADDRNOTAVAIL);
00115     return (-1);
00116   }
00117
00118   if (socket->local_addr)
00119   {
00120     struct in6_addr *ip6 = &((struct sockaddr_in6*) socket->local_addr)->sin6_addr;
00121     u_short port  = socket->local_addr->sin_port;
00122     u_long  ip4   = socket->local_addr->sin_addr.s_addr;
00123     BOOL    equal = (!is_ip6 && ip4 == addr->sin_addr.s_addr) ||
00124                    (is_ip6 && IN6_ARE_ADDR_EQUAL(ip6,&addr6->sin6_addr));
00125
00126     if ((addr->sin_port != IPPORT_ANY && addr->sin_port == port) ||
00127         (!bind_any && equal))
00128     {
00129       SOCK_DEBUGF ((", EADDRINUSE, local port %d, bind_any %d",
00130                      ntohs(port), bind_any));
00131       SOCK_ERRNO (EADDRINUSE);
00132       return (-1);
00133     }
00134
00138   }
00139   else
00140   {
00141     socket->local_addr = (struct sockaddr_in*) SOCK_CALLOC (sa_len);
00142     if (!socket->local_addr)
00143     {
00144       SOCK_DEBUGF ((", ENOMEM"));
00145       SOCK_ERRNO (ENOMEM);
00146       return (-1);
00147     }
00148   }
00149
00150 #if defined(USE_IPV6)
00151   if (is_ip6 && addr6->sin6_port == IPPORT_ANY)
00152   {
00153     local_port = find_free_port (0, TRUE);
00154     addr6->sin6_port = htons (local_port);
00155   }
00156   else
00157 #endif
00158   if (!is_ip6 && addr->sin_port == IPPORT_ANY)
00159   {
00160     local_port = find_free_port (0, TRUE);
00161     addr->sin_port = htons (local_port);
00162   }
00163   else  /* check if requested port is vacant */
00164   {
00165     local_port = ntohs (addr->sin_port);
00166     if (grab_localport(local_port) < 0)
00167     {
00168       SOCK_DEBUGF ((", EADDRNOTAVAIL, local port %d", local_port));
00169       SOCK_ERRNO (EADDRNOTAVAIL);
00170       return (-1);
00171     }
00172   }
00173
00174 #if defined(USE_IPV6)
00175   if (is_ip6)
00176   {
00177     struct sockaddr_in6 *la = (struct sockaddr_in6*)socket->local_addr;
00178
00179     la->sin6_family = AF_INET6;
00180     la->sin6_port   = addr6->sin6_port;
00181     memcpy (&la->sin6_addr, &addr6->sin6_addr, sizeof(la->sin6_addr));
00182
00183     SOCK_DEBUGF ((", %s, (%d)",
00184                   bind_any ? "INADDR_ANY" : _inet6_ntoa(&addr6->sin6_addr),
00185                   ntohs(addr->sin_port)));
00186   }
00187   else
00188 #endif
00189   {
00190     socket->local_addr->sin_port   = addr->sin_port;
00191     socket->local_addr->sin_addr   = addr->sin_addr;
00192     socket->local_addr->sin_family = AF_INET;
00193
00194     SOCK_DEBUGF ((", %s, (%d)",
00195                   bind_any ? "INADDR_ANY" : inet_ntoa(addr->sin_addr),
00196                   ntohs(addr->sin_port)));
00197   }
00198
00199   /* Since SOCK_DGRAM sockets are connectionless, the application need
00200    * not use connect() or accept(). Hence we need to use _UDP_listen().
00201    */
00202   if (socket->so_type == SOCK_DGRAM)
00203   {
00204     if (bind_any)
00205        socket->so_state |= SS_PRIV; /* privileged for broadcast reception */
00206
00207 #if defined(USE_IPV6)
00208     if (is_ip6)
00209     {
00210       if (_UDP6_listen (socket, &addr6->sin6_addr, addr6->sin6_port) < 0)
00211          return (-1);
00212     }
00213     else
00214 #endif
00215     if (_UDP_listen (socket, addr->sin_addr, addr->sin_port) < 0)
00216        return (-1);
00217   }
00218   return (0);
00219 }
00220
00221
00222 /*
00223  * A small test djgpp program
00224  */
00225 #if defined(TEST_PROG)
00226
00227 #define MY_PORT_ID  6060
00228 #undef  close
00229
00230 #include <unistd.h>
00231 #include <conio.h>
00232 #include "pcdbug.h"
00233
00234 int main (int argc, char **argv)
00235 {
00236   struct sockaddr_in addr;
00237   int    sock, quit;
00238
00239   dbug_init();
00240
00241   sock = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP);
00242   if (sock < 0)
00243   {
00244     perror ("socket");
00245     return (-1);
00246   }
00247
00248   memset (&addr, 0, sizeof(addr));
00249   addr.sin_family = AF_INET;
00250
00251   if (argc >= 2 && !strcmp(argv[1],"-frag")) /* test Tx of large datagrams */
00252   {
00253     #define CHUNK_SIZE 500
00254     char data [3*CHUNK_SIZE];
00255     int  i;
00256
00257     for (i = 0; i < sizeof(data);  i++)
00258         data[i] = i;
00259
00260     addr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
00261     addr.sin_port        = IPPORT_ANY;
00262
00263     if (sendto (sock, &data, sizeof(data), 0, (struct sockaddr*)&addr, sizeof(addr)) < 0)
00264        perror ("sendto");
00265
00266     close (sock);
00267     return (-1);
00268   }
00269
00270   /* INADDR_ANY will take all the address of the system
00271    */
00272   addr.sin_addr.s_addr = htonl (INADDR_ANY);
00273   addr.sin_port        = htons (MY_PORT_ID);
00274
00275   if (bind(sock, (struct sockaddr*)&addr, sizeof(addr)) < 0)
00276   {
00277     perror ("bind");
00278     close (sock);
00279     return (-1);
00280   }
00281
00282 #if 0
00283   if (listen (sock, 5) < 0)
00284   {
00285     perror ("listen");
00286     close (sock);
00287     return (-1);
00288   }
00289 #endif
00290
00291   quit = 0;
00292
00293   while (!quit)
00294   {
00295     struct timeval  tv;
00296     struct sockaddr from;
00297     fd_set fd_read, fd_write, fd_exc;
00298     int    num, from_len = sizeof(from);
00299
00300     FD_ZERO (&fd_read);
00301     FD_ZERO (&fd_write);
00302     FD_ZERO (&fd_exc);
00303     FD_SET (STDIN_FILENO, &fd_read);
00304     FD_SET (sock, &fd_read);
00305     FD_SET (sock, &fd_write);
00306     FD_SET (sock, &fd_exc);
00307     tv.tv_usec = 0;
00308     tv.tv_sec  = 1;
00309
00310     num = select (sock+1, &fd_read, &fd_write, &fd_exc, &tv);
00311
00312     if (FD_ISSET(sock, &fd_read))  fputc ('r', stderr);
00313     if (FD_ISSET(sock, &fd_write)) fputc ('w', stderr);
00314     if (FD_ISSET(sock, &fd_exc))   fputc ('x', stderr);
00315
00316     if (FD_ISSET(STDIN_FILENO, &fd_read))
00317     {
00318       int ch = getch();
00319       quit = (ch == 27);
00320       fputc (ch, stderr);
00321     }
00322
00323     if (FD_ISSET(sock, &fd_read) &&
00324         accept (sock, &from, &from_len) < 0)
00325     {
00326       perror ("accept");
00327       break;
00328     }
00329     if (num < 0)
00330     {
00331       perror ("select");
00332       break;
00333     }
00334     fputc ('.', stderr);
00335     usleep (300000);   /* 300ms */
00336   }
00337
00338   close (sock);
00339   return (0);
00340 }
00341 #endif  /* TEST_PROG */
00342
00343 #endif /* USE_BSD_API */
00344
Generated on Wed Jan 25 15:42:34 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/BSDDBUG.C Source File

SRC/BSDDBUG.C

Go to the documentation of this file.
00001
00005 /*  BSD sockets functionality for Waterloo TCP/IP
00006  *
00007  *  Copyright (c) 1997-2002 Gisle Vanem <giva@bgnett.no>
00008  *
00009  *  Redistribution and use in source and binary forms, with or without
00010  *  modification, are permitted provided that the following conditions
00011  *  are met:
00012  *  1. Redistributions of source code must retain the above copyright
00013  *     notice, this list of conditions and the following disclaimer.
00014  *  2. Redistributions in binary form must reproduce the above copyright
00015  *     notice, this list of conditions and the following disclaimer in the
00016  *     documentation and/or other materials provided with the distribution.
00017  *  3. All advertising materials mentioning features or use of this software
00018  *     must display the following acknowledgement:
00019  *       This product includes software developed by Gisle Vanem
00020  *       Bergen, Norway.
00021  *
00022  *  THIS SOFTWARE IS PROVIDED BY ME (Gisle Vanem) AND CONTRIBUTORS ``AS IS''
00023  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00024  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00025  *  ARE DISCLAIMED.  IN NO EVENT SHALL I OR CONTRIBUTORS BE LIABLE FOR ANY
00026  *  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00027  *  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00028  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00029  *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00030  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00031  *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00032  *
00033  *  Version
00034  *
00035  *  0.5 : Dec 18, 1997 : G. Vanem - created
00036  *        Debug functions moved from socket.c
00037  */
00038
00039 #include "socket.h"
00040 #include "get_xby.h"
00041
00042 #if defined(USE_DEBUG) && defined(USE_BSD_API)  /* Whole file */
00043
00044 #define USE_PRINTK   0
00045 #define SCOPE_INDENT 2    /* How much to indent printout at each new scope */
00046
00047 static int sk_scope = 0;
00049 static void (*prev_hook) (const char*, const char*);
00050 static BOOL   dbg_use_ods  = FALSE;
00051 static FILE  *dbg_file     = NULL;
00052 static char   dbg_omode[5] = "w+";           /* max "w+tc" */
00053 static char   dbg_fname[MAX_PATHLEN+1] = "";
00054
00055 static void bsddbug_exit (void);
00056 static void bsddbug_close (void);
00057
00058 int MS_CDECL _sock_debugf (const char *fmt, ...)
00059 {
00060   int     rc, len = 0;
00061   char    buf[256];
00062   va_list arg;
00063   int     errno_save = errno;
00064
00065   if (!_dbugxmit || !fmt)  /* dbug_init() not called */
00066      return (0);
00067
00068 #if defined(WIN32)
00069   if (dbg_use_ods)
00070   {
00071     char  *p    = buf;
00072     size_t left = sizeof(buf);
00073
00074     if (*fmt == '\n')
00075     {
00076       p    += _snprintf (p, left, "\n%9s: ", elapsed_str(set_timeout(0)));
00077       left -= p - buf;
00078       fmt++;
00079       if (sk_scope > 0)
00080       {
00081         p    += _snprintf (p, left, "%*s", SCOPE_INDENT*sk_scope, "");
00082         left -= p - buf;
00083       }
00084     }
00085     va_start (arg, fmt);
00086     p += _vsnprintf (p, left, fmt, arg);
00087     OutputDebugString (buf);
00088     va_end (arg);
00089     return (p - buf);
00090   }
00091 #endif
00092
00093   if (!dbg_file)
00094      return (0);
00095
00096   va_start (arg, fmt);
00097
00098   if (*fmt == '\n')
00099   {
00100 #if (USE_PRINTK)
00101     _printk ("\n%9s: ", elapsed_str(set_timeout(0)));
00102     fmt++;
00103     if (sk_scope > 0)
00104        _printk ("%*s", SCOPE_INDENT*sk_scope, "");
00105 #else
00106     fprintf (dbg_file, "\n%9s: ", elapsed_str(set_timeout(0)));
00107     fmt++;
00108     if (sk_scope > 0)
00109        fprintf (dbg_file, "%*s", SCOPE_INDENT*sk_scope, "");
00110 #endif
00111   }
00112
00113 #if (USE_PRINTK)
00114   _vsnprintk (buf, sizeof(buf), fmt, arg);
00115   rc = _fputsk (buf, dbg_file);
00116 #else
00117   vsprintf (buf, fmt, arg);
00118   rc = fputs (buf, dbg_file);
00119 #endif
00120
00121   _sock_dbug_flush();
00122
00123   if (rc == EOF)
00124   {
00125     TCP_CONSOLE_MSG (1, ("%s (%d): write failed; %s\n",
00126                      __FILE__, __LINE__, strerror(errno)));
00127     bsddbug_close();
00128   }
00129   errno = errno_save;
00130   va_end (arg);
00131   return (len);
00132 }
00133
00134 BOOL _sock_dbug_active (void)
00135 {
00136   return (dbg_file != NULL || dbg_use_ods);
00137 }
00138
00139 void _sock_dbug_flush (void)
00140 {
00141   if (!dbg_file)
00142      return;
00143
00144 #if (USE_PRINTK)
00145   _printk_safe = TRUE;
00146   _printk_flush();
00147 #else
00148   fflush (dbg_file);
00149 #endif
00150 }
00151
00152 /*
00153  * Called from sock_ini.c if '_dbugxmit' != NULL.
00154  */
00155 void _sock_dbug_open (void)
00156 {
00157   if (dbg_file == stdout || dbg_file == stderr || dbg_use_ods)
00158      return;
00159
00160 #if (USE_PRINTK)
00161   if (_printk_init(2000, dbg_fname))
00162   {
00163     dbg_file = _printk_file;
00164     RUNDOWN_ADD (bsddbug_exit, 150);
00165   }
00166 #else
00167   if (!dbg_fname[0])
00168      return;
00169
00170   dbg_file = fopen_excl (dbg_fname, dbg_omode);
00171   if (dbg_file)
00172   {
00173 #if !defined(__BORLANDC__)  /* buggy output with this */
00174     static char buf [1024];
00175     setvbuf (dbg_file, buf, _IOLBF, sizeof(buf));
00176 #endif
00177     RUNDOWN_ADD (bsddbug_exit, 150);
00178   }
00179 #endif  /* USE_PRINTK */
00180
00181   TCP_CONSOLE_MSG (2, ("%s (%d): dbg_file `%s', handle %d, errno %d\n",
00182                    __FILE__, __LINE__, dbg_fname,
00183                    dbg_file ? fileno(dbg_file) : -1, errno));
00184 }
00185
00186 /*
00187  * Callbacks for config-table parser.
00188  */
00189 static void set_dbg_fname (const char *value)
00190 {
00191   StrLcpy (dbg_fname, value, sizeof(dbg_fname));
00192
00193   if (!stricmp(dbg_fname,"stderr"))
00194      dbg_file = stderr;
00195   if (!stricmp(dbg_fname,"stdout") || !stricmp(dbg_fname,"con"))
00196      dbg_file = stdout;
00197 #if defined(WIN32)
00198   if (!stricmp(dbg_fname,"$ods"))
00199      dbg_use_ods = TRUE;
00200 #endif
00201 }
00202
00203 static void set_dbg_openmode (const char *value)
00204 {
00205   StrLcpy (dbg_omode, value, sizeof(dbg_omode));
00206 }
00207
00208 /*
00209  * Config-file hook routine called from parser.
00210  * (set_values() in pcconfig.c and via ourinit() in pcdbug.c)
00211  *
00212  * Parses keywords:
00213  *   SK_DEBUG.DEVICE   = <file>
00214  *   SK_DEBUG.OPENMODE = <mode>
00215  */
00216 static void dbug_parse (const char *name, const char *value)
00217 {
00218   static const struct config_table cfg[] = {
00219             { "DEVICE",   ARG_FUNC, (void*)set_dbg_fname    },
00220             { "OPENMODE", ARG_FUNC, (void*)set_dbg_openmode },
00221             { NULL,       0,        NULL                    }
00222           };
00223
00224   if (!parse_config_table(&cfg[0], "SK_DEBUG.", name, value) && prev_hook)
00225      (*prev_hook) (name, value);
00226 }
00227
00228 /*
00229  * Normally called from dbug_init() (in pcdbug.c) if USE_DEBUG is defined.
00230  * Must be called before watt_sock_init() and any other socket functions.
00231  */
00232 void _sock_dbug_init (void)
00233 {
00234   prev_hook = usr_init;
00235   usr_init  = dbug_parse;
00236 }
00237
00238 static void show_local_ports_inuse (void)
00239 {
00240   WORD port, num = 0;
00241
00242 #if (USE_PRINTK)
00243   _printk ("\nLocal ports still in use:\n");
00244 #else
00245   fprintf (dbg_file, "\nLocal ports still in use:\n");
00246 #endif
00247
00248   for (port = 1025; port < USHRT_MAX; port++)
00249   {
00250     int rc = reuse_localport (port);
00251
00252     if (rc < 0)
00253        break;
00254     if (rc > 0)
00255     {
00256       num++;
00257 #if (USE_PRINTK)
00258       _printk ("%5u%c", port, num % 12 ? ',' : '\n');
00259 #else
00260       fprintf (dbg_file, "%5u%c", port, num % 12 ? ',' : '\n');
00261 #endif
00262     }
00263   }
00264 }
00265
00266 void bsd_fortify_print (const char *buf)
00267 {
00268   if (dbg_file)
00269 #if (USE_PRINTK)
00270      _fputsk (buf, dbg_file);
00271 #else
00272      fputs (buf, dbg_file);
00273 #endif
00274 }
00275
00276
00277 #include "nochkstk.h"
00278
00279 static void bsddbug_close (void)
00280 {
00281 #if (USE_PRINTK == 0)
00282   if (dbg_file && dbg_file != stdout && dbg_file != stderr)
00283      fclose (dbg_file);
00284 #endif
00285   dbg_file = NULL;
00286 }
00287
00288 static void bsddbug_exit (void)
00289 {
00290   if (!_watt_fatal_error && dbg_file)
00291   {
00292     DumpHostsCache();
00293 #if defined(USE_IPV6)
00294     DumpHosts6Cache();
00295 #endif
00296     show_local_ports_inuse();
00297     _sock_dbug_flush();
00298   }
00299   bsddbug_close();
00300   set_dbg_openmode ("at");  /* append next time we open it */
00301 }
00302
00303 /*
00304  * These two functions are meant to increase/decrease the suspension
00305  * depth of a "task". I.e. _sock_enter_scope() should awake other
00306  * sleeping "tasks" waiting to be signalled. Ref. sk_block in socket.c.
00307  * Now they're only used to make the sock-trace prettier.
00308  */
00309 void _sock_enter_scope (void)
00310 {
00311   if (sk_scope < INT_MAX)
00312      sk_scope++;
00313 }
00314
00315 void _sock_leave_scope (void)
00316 {
00317   if (sk_scope > 0)
00318       sk_scope--;
00319 }
00320 #endif  /* USE_DEBUG && USE_BSD_API */
00321
Generated on Wed Jan 25 15:42:34 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/BSDDBUG.H Source File

SRC/BSDDBUG.H

Go to the documentation of this file.
00001
00003 #ifndef _w32_BSDDBUG_H
00004 #define _w32_BSDDBUG_H
00005
00006 /*
00007  * Debugging of BSD-socket API. Writes to "sk_debug.device"
00008  * when dbug_init() is called or `SO_DEBUG' is set on socket.
00009  */
00010 #if defined(USE_DEBUG) && defined(USE_BSD_API)
00011   extern int MS_CDECL _sock_debugf (const char *fmt, ...) ATTR_PRINTF (1,2);
00012   extern void         _sock_dbug_flush  (void);
00013   extern void         _sock_dbug_init   (void);
00014   extern void         _sock_dbug_open   (void);
00015   extern BOOL         _sock_dbug_active (void);
00016   extern void         _sock_enter_scope (void);
00017   extern void         _sock_leave_scope (void);
00018
00019   extern void bsd_fortify_print (const char *buf);
00020
00021   #define SOCK_DEBUGF(x)      _sock_debugf x
00022   #define SOCK_DBUG_FLUSH()   _sock_dbug_flush()
00023   #define SOCK_ENTER_SCOPE()  _sock_enter_scope()
00024   #define SOCK_LEAVE_SCOPE()  _sock_leave_scope()
00025 #else
00026   #define SOCK_DEBUGF(x)      ((void)0)
00027   #define SOCK_DBUG_FLUSH()   ((void)0)
00028   #define SOCK_ENTER_SCOPE()  ((void)0)
00029   #define SOCK_LEAVE_SCOPE()  ((void)0)
00030 #endif
00031
00032 #endif
Generated on Wed Jan 25 15:42:34 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/BSDNAME.C Source File

SRC/BSDNAME.C

Go to the documentation of this file.
00001
00007 #include <stdio.h>
00008 #include <stdlib.h>
00009 #include <string.h>
00010 #include <errno.h>
00011 #include <sys/socket.h>
00012
00013 #include "copyrigh.h"
00014 #include "wattcp.h"
00015 #include "udp_dom.h"
00016 #include "pcbuf.h"
00017 #include "pctcp.h"
00018 #include "pcdbug.h"
00019 #include "pcconfig.h"
00020 #include "ip6_out.h"
00021 #include "misc.h"
00022 #include "wdpmi.h"
00023 #include "x32vm.h"
00024 #include "powerpak.h"
00025 #include "strings.h"
00026 #include "bsdname.h"
00027
00032 DWORD _gethostid (void)
00033 {
00034   return (my_ip_addr);
00035 }
00036
00041 DWORD _sethostid (DWORD ip)
00042 {
00043   return (my_ip_addr = ip);
00044 }
00045
00046 #if defined(USE_BSD_API)
00047
00051 u_long W32_CALL gethostid (void)
00052 {
00053   if (!netdb_init())
00054      return (INADDR_NONE);
00055   return htonl (my_ip_addr);
00056 }
00057
00062 u_long W32_CALL sethostid (DWORD ip)
00063 {
00064   return (my_ip_addr = ntohl(ip));
00065 }
00066 #endif
00067
00068 #if defined(USE_IPV6)
00069
00074 const void *_gethostid6 (void)
00075 {
00076   if (!netdb_init())
00077      return (&in6addr_any);
00078   return (&in6addr_my_ip);
00079 }
00080
00085 void _sethostid6 (const void *addr)
00086 {
00087   memcpy (&in6addr_my_ip, addr, sizeof(in6addr_my_ip));
00088 }
00089 #endif  /* USE_IPV6 */
00090
00091
00096 int _getpeername (const sock_type *s, void *dest, int *len)
00097 {
00098   struct watt_sockaddr temp;
00099   size_t ltemp;
00100   int    chk = _chk_socket (s);
00101
00102   if (!s->tcp.hisaddr || !s->tcp.hisport ||
00103       (chk != VALID_UDP && chk != VALID_TCP))
00104   {
00105     if (len)
00106        *len = 0;
00107     return (-1);
00108   }
00109
00110   memset (&temp, 0, sizeof(temp));
00111   temp.s_ip   = s->tcp.hisaddr;
00112   temp.s_port = s->tcp.hisport;
00113   temp.s_type = s->tcp.ip_type;
00114
00115   /* how much do we move?
00116    */
00117   ltemp = (len ? *(size_t*)len : sizeof(struct watt_sockaddr));
00118   if (ltemp > sizeof (struct watt_sockaddr))
00119       ltemp = sizeof (struct watt_sockaddr);
00120   memcpy (dest, &temp, ltemp);
00121
00122   if (len)
00123      *len = ltemp;
00124   return (0);
00125 }
00126
00131 int _getsockname (const sock_type *s, void *dest, int *len)
00132 {
00133   struct watt_sockaddr temp;
00134   size_t ltemp;
00135   int    chk = _chk_socket (s);
00136
00137   if (!s->tcp.myaddr || !s->tcp.myport ||
00138       (chk != VALID_UDP && chk != VALID_TCP))
00139   {
00140     if (len)
00141        *len = 0;
00142     return (-1);
00143   }
00144
00145   memset (&temp, 0, sizeof(temp));
00146   temp.s_ip   = s->tcp.myaddr;
00147   temp.s_port = s->tcp.myport;
00148   temp.s_type = s->tcp.ip_type;
00149
00150   /* how much do we move
00151    */
00152   ltemp = (len ? *(size_t*)len : sizeof (struct watt_sockaddr));
00153   if (ltemp > sizeof (struct watt_sockaddr))
00154       ltemp = sizeof (struct watt_sockaddr);
00155   memcpy (dest, &temp, ltemp);
00156
00157   if (len)
00158      *len = ltemp;
00159   return (0);
00160 }
00161
00170 int W32_CALL getdomainname (char *buffer, int buflen)
00171 {
00172   const char *my_domainname = def_domain ? def_domain : "";
00173
00174   if (!buffer || buflen < 0 || buflen < (int)strlen(my_domainname))
00175   {
00176     SOCK_ERRNO (EINVAL);
00177     return (-1);
00178   }
00179 #if (DOSX)
00180   if (!valid_addr((DWORD)buffer, buflen))
00181   {
00182     SOCK_ERRNO (EFAULT);
00183     return (-1);
00184   }
00185 #endif
00186
00187   strncpy (buffer, my_domainname, buflen);
00188   /* no terminating '\0' needs to be forced here per bsd spec */
00189   return (0);
00190 }
00191
00197 int W32_CALL setdomainname (const char *name, int len)
00198 {
00199   if (!name || len < 0 || len > SIZEOF(defaultdomain)-1)
00200   {
00201     SOCK_ERRNO (EINVAL);
00202     return (-1);
00203   }
00204
00205 #if (DOSX)
00206   if (!valid_addr((DWORD)name, len))
00207   {
00208     SOCK_ERRNO (EFAULT);
00209     return (-1);
00210   }
00211 #endif
00212
00213   def_domain = StrLcpy (defaultdomain, name, len);
00214   return (0);
00215 }
00216
00217 /*
00218  * BSD-style: \n
00219  * Make a FQDN from `hostname' & `def_domain'.
00220  * Set errno on failure and return -1.
00221  */
00222 int W32_CALL gethostname (char *buffer, int buflen)
00223 {
00224   /* the FQDN when no hostname has been set is "localhost.localdomain".
00225    * the FQDN when a hostname has been set, but no domname is set, is 'my_hostname'
00226    * the FQDN when both are set is 'my_hostname.my_domname'
00227    */
00228   const char *my_hostname = "localhost";
00229   const char *my_domname  = "localdomain";
00230   int   pos;
00231
00232   if (!buffer || buflen < 0)
00233   {
00234     SOCK_ERRNO (EINVAL);
00235     return (-1);
00236   }
00237   if (buflen == 0)
00238      return (0);
00239
00240 #if (DOSX)
00241   if (!valid_addr((DWORD)buffer, buflen))
00242   {
00243     SOCK_ERRNO (EFAULT);
00244     return (-1);
00245   }
00246 #endif
00247
00248   if (*hostname) /* otherwise use localhost.localdomain */
00249   {
00250     my_hostname = hostname;
00251     my_domname  = NULL;         /* have hostname but no domain name */
00252     if (def_domain && *def_domain)
00253        my_domname = def_domain;
00254   }
00255   pos = 0;
00256   while (pos < buflen && *my_hostname)
00257       buffer[pos++] = *my_hostname++;
00258
00259   if (pos < buflen && my_domname)
00260   {
00261     buffer[pos++] = '.';
00262     /*@-nullderef@*/
00263     while (pos < buflen && *my_domname)
00264         buffer[pos++] = *my_domname++;
00265   }
00266   if (pos < buflen)
00267      buffer[pos] = '\0';
00268   return (0);
00269 }
00270
00277 int W32_CALL sethostname (const char *fqdn, int len)
00278 {
00279   int pos;
00280
00281   if (!fqdn || !*fqdn || len < 0 || len > MAX_HOSTLEN)
00282   {
00283     SOCK_ERRNO (EINVAL);
00284     return (-1);
00285   }
00286
00287 #if (DOSX)
00288   if (!valid_addr((DWORD)fqdn, len))
00289   {
00290     SOCK_ERRNO (EFAULT);
00291     return (-1);
00292   }
00293 #endif
00294
00295   pos = 0;
00296   while (pos < len && fqdn[pos] != '.')
00297   {
00298     if (!fqdn[pos]) /* should do complete alpha/digit/underscore check here */
00299     {
00300       pos = 0;
00301       break;
00302     }
00303     pos++;
00304   }
00305   if (pos == 0) /* leading '.' or invalid char in name */
00306   {
00307     SOCK_ERRNO (EINVAL);
00308     return (-1);
00309   }
00310   if (pos >= SIZEOF(hostname))
00311   {
00312     SOCK_ERRNO (ERANGE);
00313     return (-1);
00314   }
00315   if (fqdn[pos] == '.') /* a trailing '.' is ok too */
00316   {
00317     if (setdomainname(&fqdn[pos+1], len-pos) != 0)
00318        return (-1);
00319   }
00320   memcpy (&hostname[0], fqdn, pos);
00321   hostname[pos] = '\0';
00322   return (0);
00323 }
00324
00325
00326 #if defined(WIN32)
00327
00328 #ifndef ComputerNameDnsHostname
00329 #define ComputerNameDnsHostname 1
00330 #endif
00331
00332 /*
00333  * Get hostname excluding domain-name
00334  */
00335 int _get_machine_name (char *buf, int size)
00336 {
00337   int     rc;
00338   DWORD   sz  = size;
00339   HMODULE mod = GetModuleHandle ("KERNEL32.DLL");
00340   BOOL (WINAPI *_GetComputerNameExA) (int, char*, DWORD*) = NULL;
00341   typedef BOOL (WINAPI *gcn_ex) (int, char*, DWORD*);
00342
00343   if (mod)
00344      _GetComputerNameExA = (gcn_ex) GetProcAddress (mod, "GetComputerNameExA");
00345
00346   if (!_GetComputerNameExA)
00347        rc = GetComputerNameA (buf, &sz);
00348   else rc = (*_GetComputerNameExA) (ComputerNameDnsHostname, buf, &sz);
00349
00350   rc = rc ? 0 : -1;
00351   TCP_CONSOLE_MSG (2, ("_get_machine_name(): \"%s\", rc %d\n", buf, rc));
00352   return (rc);
00353 }
00354
00355 #else
00356
00357 /*
00358  * From Ralf Brown's interrupt list
00359  *
00360  * --------D-215E00-----------------------------
00361  * INT 21 - DOS 3.1+ network - GET MACHINE NAME
00362  *         AX = 5E00h
00363  *         DS:DX -> 16-byte buffer for ASCII machine name
00364  * Return: CF clear if successful
00365  *             CH = validity
00366  *                 00h name invalid
00367  *                 nonzero valid
00368  *                     CL = NetBIOS number for machine name
00369  *                     DS:DX buffer filled with blank-paded name
00370  *         CF set on error
00371  *             AX = error code (01h) (see #1366 at AH=59h)
00372  * Note:   supported by OS/2 v1.3+ compatibility box, PC-NFS
00373  */
00374
00375 /* Copyright (C) 1997 DJ Delorie, see COPYING.DJ for details */
00376 /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
00377
00381 int _get_machine_name (char *buf, int size)
00382 {
00383   IREGS reg;
00384   char *h;
00385   char  dosBuf[16];
00386   int   len;
00387
00388   memset (&reg, 0, sizeof(reg));
00389   reg.r_ax = 0x5E00;
00390
00391 #if (DOSX & DJGPP)
00392   if (_go32_info_block.size_of_transfer_buffer < sizeof(dosBuf))
00393      return (-1);
00394   reg.r_ds = __tb / 16;
00395   reg.r_dx = __tb & 15;
00396
00397 #elif (DOSX & (PHARLAP|X32VM|POWERPAK))
00398   if (_watt_dosTbSize < sizeof(dosBuf) || !_watt_dosTbr)
00399      return (-1);
00400   reg.r_ds = RP_SEG (_watt_dosTbr);
00401   reg.r_dx = RP_OFF (_watt_dosTbr);
00402
00403 #elif (DOSX & DOS4GW)
00404   if (_watt_dosTbSize < sizeof(dosBuf) || !_watt_dosTbSeg)
00405      return (-1);
00406   reg.r_ds = _watt_dosTbSeg;
00407   reg.r_dx = 0;
00408
00409 #elif (DOSX == 0)
00410   reg.r_ds = FP_SEG (dosBuf);
00411   reg.r_dx = FP_OFF (dosBuf);
00412
00413 #else
00414   #error Help me!
00415 #endif
00416
00417   GEN_INTERRUPT (0x21, &reg);
00418   if ((reg.r_flags & CARRY_BIT) || hiBYTE(reg.r_cx) == 0)
00419      return (-1);
00420
00421 #if (DOSX & DJGPP)
00422   dosmemget (__tb, sizeof(dosBuf), dosBuf);
00423
00424 #elif (DOSX & (PHARLAP|X32VM|POWERPAK))
00425   ReadRealMem ((void*)&dosBuf, _watt_dosTbr, sizeof(dosBuf));
00426
00427 #elif (DOSX & DOS4GW)
00428   memcpy (dosBuf, SEG_OFS_TO_LIN(_watt_dosTbSeg,0), sizeof(dosBuf));
00429 #endif
00430
00431   /* Remove right space padding
00432    */
00433   h = dosBuf + min (strlen(dosBuf), sizeof(dosBuf)-1);
00434   while (h > dosBuf && h[-1] == ' ')
00435         h--;
00436
00437   *h  = '\0';
00438   h   = dosBuf;
00439   len = strlen (h);
00440   if (len + 1 > size)
00441   {
00442     SOCK_ERRNO (ERANGE);
00443     return (-1);
00444   }
00445   strcpy (buf, h);
00446   strlwr (buf);
00447   return (0);
00448 }
00449 #endif  /*  WIN32 */
00450
Generated on Wed Jan 25 15:42:34 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/BSDNAME.H Source File

SRC/BSDNAME.H

Go to the documentation of this file.
00001
00003 #ifndef _w32_BSDNAME_H
00004 #define _w32_BSDNAME_H
00005
00006 #ifndef __SYS_SOCKET_H
00007 #include <sys/socket.h>
00008 #endif
00009
00010 /* Core-style name functions. BSD-style in above header.
00011  */
00012 W32_FUNC int   _getpeername (const sock_type *s, void *dest, int *len);
00013 W32_FUNC int   _getsockname (const sock_type *s, void *dest, int *len);
00014 W32_FUNC DWORD _gethostid   (void);
00015 W32_FUNC DWORD _sethostid   (DWORD ip);
00016
00017 /* privates */
00018 extern int         _get_machine_name (char *buf, int size);
00019 extern void        _sethostid6 (const void *addr);
00020 extern const void *_gethostid6 (void);
00021
00022 #endif
Generated on Wed Jan 25 15:42:34 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/BTRACE.H Source File

SRC/BTRACE.H

Go to the documentation of this file.
00001 #ifndef _w32_BACKTRACE_H
00002 #define _w32_BACKTRACE_H
00003
00011 #define backtrace             NAMESPACE (backtrace)
00012 #define backtrace_init        NAMESPACE (backtrace_init)
00013 #define backtrace_symbols_fd  NAMESPACE (backtrace_symbols_fd)
00014
00015 extern int backtrace_init       (const char *prog);
00016 extern int backtrace            (void **buf, int size);
00017 extern int backtrace_symbols_fd (const void *buf, int size, int file);
00018 extern int traceback_exit       (const void *caller);
00019
00020 #if defined(__GNUC__)
00021   #define CALLER_CS()     -1
00022   #define CALLER_EIP(stk) __builtin_return_address (0)
00023
00024 #elif (DOSX)
00025   #define CALLER_CS()     -1
00026   #define CALLER_EIP(stk) *(DWORD*)(&(stk)+1))
00027
00028 #elif defined(__LARGE__)
00029   #define CALLER_CS()     *(WORD*)(&(stk)+1))
00030   #define CALLER_EIP(stk) *(WORD*)(&(stk)+2))
00031
00032 #else  /* small model */
00033   #define CALLER_CS()     MY_CS()
00034   #define CALLER_EIP(stk) *(WORD*)(&(stk)+1))
00035 #endif
00036
00037 #endif
Generated on Wed Jan 25 15:42:34 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/BTREE.C Source File

SRC/BTREE.C

Go to the documentation of this file.
00001
00008 #include <stdio.h>
00009 #include <string.h>
00010
00011 #include "wattcp.h"
00012 #include "strings.h"
00013 #include "btree.h"
00014
00015 /*
00016  * \note This file is only used together with gethost2.c.
00017  *       But gethost2.c isn't finished yet.
00018  */
00019
00020 /*
00021  *  Non-recursive tree insertion.
00022  *  If duplicate key then new data is substituted.
00023  *
00024  *  returns 1 on success
00025  *          0 on failure
00026  */
00027 int tree_insert (TreeNode **root, const void *info, size_t info_size, CmpFunc cmp)
00028 {
00029   TreeNode *node = *root;
00030
00031   /* does not enter while loop when instantiating root
00032    */
00033   while (node)
00034   {
00035     int diff = (*cmp)(info, node->info);
00036
00037     if (diff == 0)
00038     {
00039       free (node->info);
00040       goto tree_load;
00041     }
00042     else if (diff < 0)
00043     {
00044       if (node->left)
00045           node = node->left;
00046       else
00047       {
00048         node->left = (struct TreeNode*) calloc (1, sizeof(*node));
00049         if (node->left)
00050             node->left->parent = node;
00051         node = node->left;
00052         goto tree_load;
00053       }
00054     }
00055     else
00056     {
00057       if (node->right)
00058           node = node->right;
00059       else
00060       {
00061         node->right = (struct TreeNode*) calloc (1, sizeof(*node));
00062         if (node->right)
00063             node->right->parent = node;
00064         node = node->right;
00065         goto tree_load;
00066       }
00067     }
00068   }
00069
00070   /* only arrives here when instantiating root
00071    */
00072   node  = (struct TreeNode*) calloc (1, sizeof(*node));
00073   *root = node;
00074
00075 tree_load:
00076   if (!node)
00077      return (0);
00078
00079   node->info = calloc (1, info_size);
00080   if (!node->info)
00081   {
00082     free (node);
00083     return (0);
00084   }
00085
00086   memcpy (node->info, info, info_size);
00087   node->info_size = info_size;
00088   return (1);
00089 }
00090
00091
00092 /*
00093  *  Non-recursive find, returns first matching entry or NULL
00094  */
00095 TreeNode *tree_find (TreeNode *root, const void *info, CmpFunc cmp)
00096 {
00097   TreeNode *node = root;
00098
00099   while (node)
00100   {
00101     int cmp_val = (*cmp)(info, node->info);
00102
00103     if (cmp_val == 0)
00104        break;
00105
00106     if (cmp_val < 0)
00107          node = node->left;
00108     else node = node->right;
00109   }
00110   return (node);
00111 }
00112
00113 TreeNode *tree_delete (TreeNode *root, TreeNode *node)
00114 {
00115   TreeChild  child;
00116   TreeNode  *temp;
00117
00118   if (!node || !root)
00119      return (root);
00120
00121   if (root == node)
00122        child = NOT_CHILD;
00123   else if (node->parent->left == node)
00124        child = LEFT_CHILD;
00125   else if (node->parent->right == node)
00126        child = RIGHT_CHILD;
00127   else return (root);
00128
00129   if (!node->right)
00130   {
00131     temp = node;
00132     node = node->left;
00133   }
00134   else if (!node->left)
00135   {
00136     temp = node;
00137     node = node->right;
00138   }
00139   else
00140   {
00141     temp = node->right;
00142     while (temp->left)
00143       temp = temp->left;
00144
00145     temp->left = node->left;
00146     temp->left->parent = temp;
00147     temp = node;
00148     node = node->right;
00149   }
00150
00151   switch (child)
00152   {
00153     case NOT_CHILD:
00154          free (temp->info);
00155          free (temp);
00156          if (node)
00157              node->parent = NULL;
00158          return (node);
00159
00160     case LEFT_CHILD:
00161          temp->parent->left = node;
00162          if (node)
00163              node->parent = temp->parent;
00164          free (temp->info);
00165          free (temp);
00166          break;
00167
00168     case RIGHT_CHILD:
00169          temp->parent->right = node;
00170          if (node)
00171              node->parent = temp->parent;
00172          free (temp->info);
00173          free (temp);
00174          /* drop through to return */
00175   }
00176   return (root);
00177 }
00178
00179 /*
00180  *  Recursive post-order traversal to deallocate tree memory
00181  */
00182 void tree_free (TreeNode *root)
00183 {
00184   if (!root)
00185      return;
00186
00187   tree_free (root->left);
00188   tree_free (root->right);
00189   if (root->info)
00190      free (root->info);
00191   free (root);
00192 }
00193
00194 #if defined(TEST_PROG)
00195
00196 #include <conio.h>
00197
00198 /*
00199  *  Interactive tree test driver
00200  */
00201
00202 #define KEYSIZE 80
00203
00204 typedef enum tree_order {
00205         NO_ORDER, PRE_ORDER,
00206         IN_ORDER, POST_ORDER
00207       } tree_order;
00208
00209 tree_order t_order = IN_ORDER;
00210
00211 typedef struct {
00212         char key[KEYSIZE];
00213         int  id;
00214       } record;
00215
00216 record rec;
00217
00218
00219 void prompt (const char *verb)
00220 {
00221   printf ("\nEnter String to %s\t( <Enter> for none )\n>", verb);
00222 }
00223
00224 int rec_cmp (const void *a, const void *b)
00225 {
00226   const record *rec1 = (record*)a;
00227   const record *rec2 = (record*)b;
00228   return strcmp (rec1->key, rec2->key);
00229 }
00230
00231 void tree_print (const record *record)
00232 {
00233   if (record)
00234      printf ("Key: %s\nRecord Number: %d\n", record->key, record->id);
00235 }
00236
00237 /*
00238  *  Recursive tree traversal function with 3 traversing modes
00239  */
00240 void tree_trace (TreeNode *root)
00241 {
00242   if (!root)
00243      return;
00244
00245   switch (t_order)
00246   {
00247     case PRE_ORDER:
00248          tree_print (root->info);
00249          tree_trace (root->left);
00250          tree_trace (root->right);
00251          return;
00252
00253     case IN_ORDER:
00254          tree_trace (root->left);
00255          tree_print (root->info);
00256          tree_trace (root->right);
00257          return;
00258
00259     case POST_ORDER:
00260          tree_trace (root->left);
00261          tree_trace (root->right);
00262          tree_print (root->info);
00263          return;
00264
00265     default:
00266          return;
00267   }
00268 }
00269
00270 int main (void)
00271 {
00272   TreeNode *tree_root = NULL;
00273   TreeNode *found     = NULL;
00274
00275   char *orders[4]    = { "no-order", "pre-order", "in-order", "post-order" };
00276   char  buf[KEYSIZE] = "";
00277   int   record_num   = 0;
00278   int   ch, count    = 0;
00279
00280   prompt ("Insert");
00281
00282   while (*gets(buf))
00283   {
00284     StrLcpy (rec.key, buf, KEYSIZE);
00285     rec.id = ++record_num;
00286     if (!tree_insert (&tree_root, &rec, sizeof(rec), (CmpFunc)rec_cmp))
00287     {
00288       printf ("\n\tTree Insertion Failure!\n");
00289       return (1);
00290     }
00291     prompt ("Insert");
00292   }
00293
00294   prompt ("Delete");
00295   gets (buf);
00296   rec.key[0] = '\0';
00297   StrLcpy (rec.key, buf, KEYSIZE);
00298
00299   while ((found = tree_find (tree_root, &rec, (CmpFunc)rec_cmp)) != NULL)
00300   {
00301     tree_print (found->info);
00302     tree_root = tree_delete (tree_root, found);
00303     count++;
00304   }
00305
00306   printf ("\n\t%d String(s) Deleted\n", count);
00307   printf ("\n\tSelect Tree Traversal Type\n");
00308   printf ("\n\t\t1) pre-order\n\t\t2) in-order\n\t\t3) post-order\n\n\t>");
00309
00310   ch = getch();
00311   ch -= '0';
00312   if (ch < PRE_ORDER || ch > POST_ORDER)
00313      ch = NO_ORDER;
00314
00315   printf ("\n\t... Walking Tree %s ...\n\n", orders[ch]);
00316   t_order = ch;
00317   tree_trace (tree_root);
00318   tree_free (tree_root);
00319   return (0);
00320 }
00321
00322 #endif  /* TEST_PROG */
Generated on Wed Jan 25 15:42:34 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/BTREE.H Source File

SRC/BTREE.H

Go to the documentation of this file.
00001
00004 #ifndef _w32_BTREE_H
00005 #define _w32_BTREE_H
00006
00007 typedef struct TreeNode {
00008         struct TreeNode *left;
00009         struct TreeNode *right;
00010         struct TreeNode *parent;
00011         void            *info;
00012         size_t           info_size;
00013       } TreeNode;
00014
00015 typedef enum TreeChild {
00016         NOT_CHILD  = 1,
00017         LEFT_CHILD,
00018         RIGHT_CHILD
00019       } TreeChild;
00020
00021 typedef int (*CmpFunc)(const void *, const void *);
00022
00023 int       tree_insert (TreeNode **, const void *, size_t, CmpFunc);
00024 TreeNode *tree_find   (TreeNode *, const void *, CmpFunc);
00025 TreeNode *tree_delete (TreeNode *, TreeNode *);
00026 void      tree_free   (TreeNode *);
00027
00028 #endif
Generated on Wed Jan 25 15:42:34 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/CHKSUM.C Source File

SRC/CHKSUM.C

Go to the documentation of this file.
00001
00007 #include <stdio.h>
00008 #include <stdlib.h>
00009
00010 #include "wattcp.h"
00011 #include "pcicmp.h"
00012 #include "pcconfig.h"
00013 #include "pcstat.h"
00014 #include "language.h"
00015 #include "strings.h"
00016 #include "misc.h"
00017 #include "ip6_in.h"
00018 #include "chksum.h"
00019
00029 WORD in_checksum (const void *ptr, unsigned len)
00030 {
00031   register long  sum       = 0;
00032   register long  slen      = (long) len;   /* must be signed */
00033   register const WORD *wrd = (const WORD*) ptr;
00034
00035   while (slen > 1)
00036   {
00037     sum  += *wrd++;
00038     slen -= 2;
00039   }
00040   if (slen > 0)
00041      sum += *(const BYTE*)wrd;
00042
00043   /*@-shiftsigned@*/
00044   while (sum >> 16)
00045       sum = (sum & 0xFFFF) + (sum >> 16);
00046
00047   return (WORD)sum;
00048 }
00049
00050
00051 #if defined(USE_IPV6)
00052
00055 WORD _ip6_checksum (const in6_Header *ip, WORD proto,
00056                     const void *payload, unsigned payloadlen)
00057 {
00058   tcp_PseudoHeader6 ph;
00059   DWORD chksum;
00060
00061   memset (&ph, 0, sizeof(ph));
00062   memcpy (&ph.src, &ip->source, sizeof(ph.src));
00063   memcpy (&ph.dst, &ip->destination, sizeof(ph.dst));
00064   ph.length   = intel16 (payloadlen);
00065   ph.next_hdr = (BYTE)proto;
00066
00067   chksum  = CHECKSUM (&ph, sizeof(ph));
00068   chksum += CHECKSUM (payload, payloadlen);
00069
00070   /* Wrap in the carries to reduce chksum to 16 bits.
00071    */
00072   chksum  = (chksum >> 16) + (chksum & 0xFFFF);
00073   chksum += (chksum >> 16);
00074
00075   /* Take ones-complement and replace 0 with 0xFFFF.
00076    */
00077   chksum = (WORD)~chksum;
00078   if (chksum == 0UL)
00079      chksum = 0xFFFFUL;
00080
00081   return (WORD)chksum;
00082 }
00083
00087 int _ip6_tcp_checksum (const in6_Header *ip, const tcp_Header *tcp, unsigned len)
00088 {
00089   if (_ip6_checksum(ip, IP6_NEXT_TCP, tcp, len) != 0xFFFF)
00090   {
00091     STAT (tcpstats.tcps_rcvbadsum++);
00092     if (debug_on)
00093        outsnl (_LANG("bad tcp checksum"));
00094     return (0);
00095   }
00096   return (1);
00097 }
00098
00102 int _ip6_udp_checksum (const in6_Header *ip, const udp_Header *udp, unsigned len)
00103 {
00104   if (_ip6_checksum(ip, IP6_NEXT_UDP, udp, len) != 0xFFFF)
00105   {
00106     STAT (udpstats.udps_badsum++);
00107     if (debug_on)
00108        outsnl (_LANG("bad udp checksum"));
00109     return (0);
00110   }
00111   return (1);
00112 }
00113
00114 /*
00115  * Check ICMP header checksum for an IPv6 packet.
00116  * Caller upcates stats.
00117  */
00118 int _ip6_icmp_checksum (const in6_Header *ip, const void *icmp, unsigned len)
00119 {
00120   return (_ip6_checksum(ip, IP6_NEXT_ICMP, icmp, len) == 0xFFFF);
00121 }
00122 #endif /* USE_IPV6 */
00123
00124
00125 #if defined(NOT_USED)
00126
00127 #define CKSUM_CARRY(x) (x = (x >> 16) + (x & 0xffff), \
00128                         (~(x + (x >> 16)) & 0xffff) )
00129
00130 #ifndef IP_PROTO
00131 #define IP_PROTO 0  /* dummy for IP */
00132 #endif
00133
00134 /*
00135  * Set header checksum on outgoing packets.
00136  * Dug Song came up with this very cool checksuming implementation
00137  * eliminating the need for explicit psuedoheader use. Check it out.
00138  *
00139  * Ripped from libnet 1.0.1
00140  */
00141 int do_checksum (const BYTE *buf, BYTE protocol, unsigned len)
00142 {
00143   struct in_Header   *ip = (struct in_Header*) buf;
00144   struct tcp_Header  *tcp;
00145   struct udp_Header  *udp;
00146   struct IGMP_packet *igmp;
00147   union  icmp_pkt    *icmp;
00148   WORD  sum = 0;
00149
00150   unsigned ip_hlen = in_GetHdrLen (ip);
00151
00152   switch (protocol)
00153   {
00154     case TCP_PROTO:
00155          tcp = (struct tcp_Header*) (buf + ip_hlen);
00156          tcp->checksum = 0;
00157          sum = CHECKSUM (&ip->source, 8);
00158          sum += intel16 (TCP_PROTO + len);
00159          sum += CHECKSUM (tcp, len);
00160          tcp->checksum = CKSUM_CARRY (sum);
00161          break;
00162
00163     case UDP_PROTO:
00164          udp = (struct udp_Header*) (buf + ip_hlen);
00165          udp->checksum = 0;
00166          sum = CHECKSUM (&ip->source, 8);
00167          sum += intel16 (UDP_PROTO + len);
00168          sum += CHECKSUM (udp, len);
00169          udp->checksum = CKSUM_CARRY (sum);
00170          break;
00171
00172     case ICMP_PROTO:
00173          icmp = (union icmp_pkt*) (buf + ip_hlen);
00174          icmp->unused.checksum = 0;
00175          sum = CHECKSUM (icmp, len);
00176          icmp->unused.checksum = CKSUM_CARRY (sum);
00177          break;
00178
00179     case IGMP_PROTO:
00180          igmp = (struct IGMP_packet*) (buf + ip_hlen);
00181          igmp->checksum = 0;
00182          sum += CHECKSUM (igmp, len);
00183          igmp->checksum = CKSUM_CARRY (sum);
00184          break;
00185
00186     case IP_PROTO:
00187          ip->checksum = 0;
00188          sum = CHECKSUM (ip, len);
00189          ip->checksum = CKSUM_CARRY (sum);
00190          break;
00191
00192     default:
00193         TCP_CONSOLE_MSG (2, ("do_checksum: unknown protocol %d\n", protocol));
00194         return (-1);
00195   }
00196   return (1);
00197 }
00198 #endif  /* NOT_USED */
00199
Generated on Wed Jan 25 15:42:34 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/CHKSUM.H Source File

SRC/CHKSUM.H

Go to the documentation of this file.
00001
00003 #ifndef _w32_CHECK_SUM_H
00004 #define _w32_CHECK_SUM_H
00005
00006 #define in_checksum      NAMESPACE (in_checksum)
00007 #define in_checksum_fast NAMESPACE (in_checksum_fast)
00008 #define do_checksum      NAMESPACE (do_checksum)
00009
00010 W32_FUNC WORD in_checksum (const void *ptr, unsigned len);
00011 extern   int  do_checksum (const BYTE *buf, BYTE proto, unsigned len);
00012
00013 extern WORD _ip6_checksum (const in6_Header *ip, WORD proto,
00014                            const void *payload, unsigned payloadlen);
00015 extern int  _ip6_tcp_checksum  (const in6_Header *ip, const tcp_Header *tcp, unsigned len);
00016 extern int  _ip6_udp_checksum  (const in6_Header *ip, const udp_Header *udp, unsigned len);
00017 extern int  _ip6_icmp_checksum (const in6_Header *ip, const void *icmp, unsigned len);
00018
00019 /*
00020  * In chksum0.asm / chksum0.s
00021  * Fast asm-version doesn't work with Watcom (don't know why).
00022  * LCC-win32's linker doesn't handle tasm's object files. So use
00023  * the slow C-version.
00024  */
00025 #if (DOSX)
00026   extern WORD cdecl in_checksum_fast (const void *ptr, unsigned len);
00027
00028   #if defined(__WATCOMC__)
00029     /* No decoration. Args on stack. All regs preserved */
00030     #pragma aux (cdecl) _w32_in_checksum_fast "_*" parm caller[];
00031   #elif defined(__HIGHC__)
00032     #pragma alias (_w32_in_checksum_fast, "_w32_in_checksum_fast")
00033   #endif
00034
00035   #if defined(__WATCOMC__) || defined(__LCC__)
00036     #define CHECKSUM(p, len)  in_checksum (p, len)
00037   #else
00038     #define HAVE_IN_CHECKSUM_FAST
00039     #define CHECKSUM(p, len)  in_checksum_fast (p, len)
00040   #endif
00041 #else
00042   #define CHECKSUM(p, len)    in_checksum (p, len)
00043 #endif
00044
00045 #endif
Generated on Wed Jan 25 15:42:34 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/CLOSE.C Source File

SRC/CLOSE.C

Go to the documentation of this file.
00001
00005 /*
00006  *  BSD sockets functionality for Waterloo TCP/IP
00007  *
00008  *  Copyright (c) 1997-2002 Gisle Vanem <giva@bgnett.no>
00009  *
00010  *  Redistribution and use in source and binary forms, with or without
00011  *  modification, are permitted provided that the following conditions
00012  *  are met:
00013  *  1. Redistributions of source code must retain the above copyright
00014  *     notice, this list of conditions and the following disclaimer.
00015  *  2. Redistributions in binary form must reproduce the above copyright
00016  *     notice, this list of conditions and the following disclaimer in the
00017  *     documentation and/or other materials provided with the distribution.
00018  *  3. All advertising materials mentioning features or use of this software
00019  *     must display the following acknowledgement:
00020  *       This product includes software developed by Gisle Vanem
00021  *       Bergen, Norway.
00022  *
00023  *  THIS SOFTWARE IS PROVIDED BY ME (Gisle Vanem) AND CONTRIBUTORS ``AS IS''
00024  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00025  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00026  *  ARE DISCLAIMED.  IN NO EVENT SHALL I OR CONTRIBUTORS BE LIABLE FOR ANY
00027  *  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00028  *  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00029  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00030  *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00031  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00032  *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00033  *
00034  *  Version
00035  *
00036  *  0.5 : Dec 18, 1997 : G. Vanem - created
00037  */
00038
00039 #include "socket.h"
00040
00041 #if defined(USE_BSD_API)
00042
00043 static int close_dgram  (Socket *socket);
00044 static int close_stream (Socket *socket);
00045
00046 int close_s (int s)
00047 {
00048   Socket *socket = _socklist_find (s);
00049
00050   SOCK_PROLOGUE (socket, "\nclose:%d", s);
00051
00052   socket->so_error = 0;
00053
00054   switch (socket->so_type)
00055   {
00056     case SOCK_PACKET:
00057     case SOCK_RAW:
00058          SOCK_DEL_FD (s);
00059          return (0);
00060
00061     case SOCK_DGRAM:
00062          return close_dgram (socket);
00063
00064     case SOCK_STREAM:
00065          return close_stream (socket);
00066   }
00067   SOCK_ERRNO (EOPNOTSUPP);
00068   return (-1);
00069 }
00070
00071 int W32_CALL closesocket (int s)
00072 {
00073   return close_s (s);
00074 }
00075
00076 /*
00077  * Close a SOCK_DGRAM socket
00078  */
00079 static int close_dgram (Socket *socket)
00080 {
00081   sock_type *sk = (sock_type*)socket->udp_sock;
00082
00083   sk->udp.rx_datalen = 0;   /* flush Rx data */
00084   sock_close (sk);
00085   socket->so_state |= (SS_ISDISCONNECTING | SS_CANTSENDMORE);
00086
00087   if (!socket->local_addr)
00088      SOCK_DEL_FD (socket->fd);
00089   return (0);
00090 }
00091
00092 /*
00093  * Close a SOCK_STREAM socket
00094  */
00095 static int close_stream (Socket *socket)
00096 {
00097   sock_type *sk       = (sock_type*)socket->tcp_sock;
00098   BOOL abort_it       = FALSE;
00099   BOOL blocking_close = FALSE;
00100   int  i, s;
00101
00102   if ((socket->so_state & SS_ISDISCONNECTING) && socket->close_time)
00103   {
00104     SOCK_DEBUGF ((", close already called"));
00105     SOCK_ERRNO (EBADF);
00106     return (-1);
00107   }
00108
00109   if (socket->so_options & SO_LINGER)
00110   {
00111     if (socket->linger_time == 0)
00112     {
00113       abort_it = TRUE;
00114       sk = NULL;
00115       SOCK_DEBUGF ((", zero-linger RST"));
00116     }
00117     else if (socket->linger_time > 0 && socket->linger_on)
00118     {
00119       blocking_close = TRUE;
00120       SOCK_DEBUGF ((", blocking lingering close"));
00121     }
00122   }
00123
00124   if (!socket->local_addr) /* Not bound or never received anything */
00125   {
00126     abort_it = TRUE;
00127     sk = NULL;
00128   }
00129
00130   /* Save memory and abort listen() socket and queue now.
00131    */
00132   if (socket->so_options & SO_ACCEPTCONN)
00133   {
00134     SOCK_DEBUGF ((", listen abort, backlog %d", socket->backlog));
00135     abort_it = TRUE;
00136     sk = NULL;
00137     for (i = 0; i < socket->backlog && i < SOMAXCONN; i++)
00138     {
00139       sock_type *tcb = (sock_type*) socket->listen_queue[i];
00140
00141       if (!tcb)
00142          continue;
00143
00144       tcb->tcp.rx_datalen = 0;   /* flush Rx data */
00145       TCP_ABORT (&tcb->tcp);
00146       free (tcb);
00147       socket->listen_queue[i] = NULL;
00148     }
00149   }
00150
00151   if (sk)
00152   {
00153     sk->tcp.rx_datalen = 0;
00154     sock_flush (sk);
00155     sock_close (sk);
00156   }
00157
00158   s = socket->fd;
00159
00160   if (abort_it)
00161   {
00162     SOCK_DEBUGF ((", fast kill!"));
00163     SOCK_DEL_FD (s);      /* calls _tcp_abort() */
00164   }
00165   else
00166   {
00167     /* sock_daemon() will free socket from list and inuse array.
00168      * Local port is marked for reuse after TCP_LINGERTIME (2min).
00169      */
00170     socket->so_state  |= (SS_ISDISCONNECTING | SS_CANTSENDMORE);
00171     socket->so_state  |= SS_CANTRCVMORE;  /* !! should we do this? */
00172     socket->close_time = time (NULL);
00173   }
00174
00175   if (blocking_close)
00176   {
00177     while (_socklist_find(s)) /* while still alive */
00178     {
00179       tcp_tick (NULL);        /* poll, sock_daemon() will delete it */
00180       WATT_YIELD();
00181     }
00182   }
00183   return (0);
00184 }
00185 #endif /* USE_BSD_API */
Generated on Wed Jan 25 15:42:34 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/CONFIG.H Source File

SRC/CONFIG.H

Go to the documentation of this file.
00001
00006 #ifndef _w32_CONFIG_H
00007 #define _w32_CONFIG_H
00008
00009 #if defined(_w32_WATTCP_H) && !defined(_w32_TARGET_H)
00010 #error CONFIG.H must be included after TARGET.H
00011 #endif
00012
00021 #undef USE_DEBUG       /* Include debug code */
00022 #undef USE_MULTICAST   /* Include IP multicast code by Jim Martin */
00023 #undef USE_BIND        /* Include Bind resolver code */
00024 #undef USE_BSD_API     /* Include BSD-sockets */
00025 #undef USE_BSD_FATAL   /* Exit application on BSD-socket fatal errors */
00026 #undef USE_BOOTP       /* Include BOOTP client code */
00027 #undef USE_DHCP        /* Include DHCP boot client code */
00028 #undef USE_RARP        /* Include RARP boot client code. Contributed by Dan Kegel. */
00029 #undef USE_IPV6        /* Include IPv6 dual-stack support */
00030 #undef USE_LANGUAGE    /* Include Language translation code */
00031 #undef USE_FRAGMENTS   /* Include IP-fragment handling */
00032 #undef USE_STATISTICS  /* Include protocol statistics count */
00033 #undef USE_FORTIFY     /* Use Fortify malloc-lib for allocations */
00034 #undef USE_FSEXT       /* Use djgpp's File Extensions for file I/O functions */
00035 #undef USE_LOOPBACK    /* Use the simple loopback device */
00036 #undef USE_EMBEDDED    /* Make an embeddable (ROM-able) target. See note at end */
00037 #undef USE_BUFFERED_IO /* Use buffered I/O in pcconfig.c */
00038 #undef USE_TFTP        /* Include TFTP protocol for simple file retrival */
00039 #undef USE_UDP_ONLY    /* Exclude all stuff related to the TCP protocol */
00040 #undef USE_MTU_DISC    /* Include support for atch MTU Discovery (not yet) */
00041 #undef USE_TCP_SACK    /* Include TCP Selective ACK feature (not yet) */
00042 #undef USE_ECHO_DISC   /* Include echo/discard servers */
00043 #undef USE_PPPOE       /* PPP-over-Ethernet encapsulation */
00044 #undef USE_RS232_DBG   /* Include RS232 serial port writing of trace-info */
00045 #undef USE_FAST_PKT    /* Use faster all real-mode PKTDRVR receiver (DOSX only) */
00046 #undef USE_DEAD_GWD    /* Dead Gateway detection in ARP module */
00047 #undef USE_GZIP_COMPR  /* Use gzip compression for PPPP and/or pcap debug file */
00048 #undef USE_PROFILER    /* Include simple execution profiler (only DOSX with 64-bit types) */
00049 #undef USE_TCP_MD5     /* TCP MD5 signature option */
00050 #undef USE_SECURE_ARP  /* Secure ARP client (experimental) */
00051 #undef USE_IDNA        /* Support national characters in DNS name lookups. */
00052 #undef USE_DYNIP_CLI   /* Support DynDNS.org name/IP client */
00053
00054 #undef USE_BIGENDIAN   /* Hard to believe, but someone uses Watt-32 on
00055                         * Motorola/PowerPC embedded target.
00056                         */
00057
00058
00059 /*
00060  * No options needed if you want to make a TSR.
00061  * You can reduce code further by "#define USE_UDP_ONLY".
00062  */
00063 #if defined(MAKE_TSR)
00064   #define OPT_DEFINED
00065 #endif
00066
00067
00068 /*
00069  * Building small-model applications doesn't leave
00070  * much room for the fancy stuff :-(
00071  */
00072 #if !defined(OPT_DEFINED) && defined(__SMALL16__)
00073   #define USE_UDP_ONLY     /* test udp-only (cookie,ping) */
00074   #define OPT_DEFINED
00075 #endif
00076
00077 /*
00078  * MS's Quick-C (6.0 at least) is severly limited in many ways..
00079  */
00080 #if !defined(OPT_DEFINED) && (defined(_MSC_VER) && (_MSC_VER <= 600) && defined(__LARGE__))
00081   #define OPT_DEFINED
00082 #endif
00083
00084 /*
00085  * So is Turbo-C (2.01 at least)
00086  */
00087 #if !defined(OPT_DEFINED) && (defined(OLD_TURBOC) && defined(__LARGE__))
00088   #define OPT_DEFINED
00089 #endif
00090
00091 /*
00092  * For other large models define these options:
00093  */
00094 #if !defined(OPT_DEFINED) && defined(__LARGE__)
00095   #define USE_DEBUG
00096   #define OPT_DEFINED
00097 #endif
00098
00099 /*
00100  * Else, for all targets define these options:
00101  */
00102 #if !defined(OPT_DEFINED)
00103   #define USE_DEBUG
00104   #define USE_BOOTP
00105   #define USE_DHCP
00106   #define USE_LANGUAGE
00107   #define USE_FRAGMENTS
00108   #define USE_STATISTICS
00109   #define USE_BIND
00110   #define USE_BSD_API
00111   #define USE_BSD_FATAL
00112   #define USE_LOOPBACK
00113   #define USE_BUFFERED_IO
00114   #define USE_TFTP
00115   #define USE_MULTICAST
00116   #define USE_PPPOE
00117   #define OPT_DEFINED
00118 #endif
00119
00120 /*
00121  * Add some more options for djgpp, HighC, 32-bit Watcom/DMC and Win32
00122  */
00123 #if defined(__DJGPP__) || defined(__HIGHC__) || defined(WATCOM386) || \
00124     defined(DMC386) || defined(WIN32)
00125   #define USE_ECHO_DISC
00126   #define USE_RARP
00127   #define USE_IPV6
00128   #define USE_IDNA
00129   #define USE_TCP_MD5
00130   #define USE_GZIP_COMPR
00131   #define USE_DYNIP_CLI
00132 #endif
00133
00134 #if defined(__DJGPP__)
00135   #define USE_FSEXT
00136   #define USE_RS232_DBG
00137   #define USE_FORTIFY
00138 /*#define USE_SECURE_ARP */
00139 #endif
00140
00141 #if (DOSX && DOSX != WINWATT)
00142   #define USE_FAST_PKT
00143 #endif
00144
00145 #if (DOSX) && defined(HAVE_UINT64)
00146   #define USE_PROFILER
00147 #endif
00148
00149 #if defined(__POCC__)
00150   #undef USE_IDNA    /* PunyCode.c causes crsh in pocc */
00151 #endif
00152
00153 #if defined(USE_PROFILER) && (!DOSX || !defined(HAVE_UINT64))
00154   #error Cannot define USE_PROFILER for this target
00155 #endif
00156
00157 /*
00158  * Test some illegal combinations.
00159  */
00160 #if defined(USE_IPV6) && !defined(USE_BSD_API)
00161 #error USE_IPV6 requires USE_BSD_API
00162 #endif
00163
00164 #if defined(USE_BIND) && !defined(USE_BSD_API)
00165 #error USE_BIND requires USE_BSD_API
00166 #endif
00167
00168 #if defined(USE_UDP_ONLY) && defined(USE_BSD_API)
00169 #error USE_UDP_ONLY and USE_BSD_API are meaningless
00170 #endif
00171
00172 #if defined(MAKE_TSR) && (DOSX)
00173 #error Making 32-bit TSRs is unsupported
00174 #endif
00175
00176 #if defined(__TURBOC__) && (__TURBOC__ <= 0x301)
00177   #if defined(USE_BIND) || defined(USE_SOCKET) || defined(USE_STATISTICS)
00178   #error tcc 2.0 cannot compile resolver, socket code or statistics
00179   #endif
00180 #endif
00181
00193 /*
00194  * Hack fix: When compiling with djgpp 2.04, but the
00195  *           ./util/dj_err.exe was compiled with 2.03, it's
00196  *           necessary to define the following.
00197  */
00198 #undef MIXING_DJGPP_203_AND_204
00199
00200 /*
00201  * Note safe or wise to use Fortify for these combinations.
00202  */
00203 #if defined(WATT32_DOS_DLL) || defined(MAKE_TSR)
00204   #undef USE_FORTIFY
00205 #endif
00206
00207 /*
00208  * Select malloc debuggers on Windows
00209  */
00210 #if defined(WIN32) && !defined(USE_FORTIFY)
00211   #if defined(_MSC_VER) && defined(_DEBUG)     /* cl -MDd -D_DEBUG */
00212     #define USE_CRTDBG       /* use CrtDebug; faster than Fortify? */
00213   #endif
00214 #endif
00215
00216 #if defined(__MINGW32__) && !defined(NDEBUG)
00217   #define USE_FORTIFY
00218 #endif
00219
00220 #if defined(WIN32) && 0
00221   #define USE_DYN_PACKET  /* load packet.dll dynamically */
00222 #endif
00223
00224 /*
00225  * If building .html-documentation with doxygen, document everything.
00226  * Add some stuff doxygen doesn't know about.
00227  */
00228 #ifdef DOXYGEN
00229   #define __far
00230   #define far
00231   #define __interrupt
00232   #define interrupt
00233   #define __cdecl
00234   #define cdecl
00235   #define USE_DEBUG
00236   #define USE_MULTICAST
00237   #define USE_BIND
00238   #define USE_BSD_API
00239   #define USE_BSD_FATAL
00240   #define USE_BOOTP
00241   #define USE_DHCP
00242   #define USE_RARP
00243   #define USE_IPV6
00244   #define USE_LANGUAGE
00245   #define USE_FRAGMENTS
00246   #define USE_STATISTICS
00247   #define USE_FORTIFY
00248   #define USE_FSEXT
00249   #define USE_LOOPBACK
00250   #define USE_EMBEDDED
00251   #define USE_BUFFERED_IO
00252   #define USE_TFTP
00253   #define USE_UDP_ONLY
00254   #define USE_MTU_DISC
00255   #define USE_TCP_SACK
00256   #define USE_ECHO_DISC
00257   #define USE_PPPOE
00258   #define USE_RS232_DBG
00259   #define USE_FAST_PKT
00260   #define USE_SECURE
00261   #define USE_TCP_MD5
00262 #endif
00263
00264 #if defined(USE_GZIP_COMPR)
00265   #define Z_NO_INFLATE  /* we don't need to read gzip streams */
00266   #define Z_PREFIX      /* use 'z_' prefix for zlib functions */
00267   #define FASTEST       /* use fastest deflate method */
00268 /*#define ASMV */       /* use assembly version of longest_match() */
00269   #define NO_vsnprintf
00270   #define Z_PRINTF_BUFSIZE 1024
00271 #endif
00272
00273 /*
00274  * A small HAVE_x section here.
00275  */
00276 #if defined(WIN32)
00277   #define HAVE_WINDNS_H
00278 #endif
00279
00280 #if defined(__BORLANDC__) && (__BORLANDC__ < 0x5600)
00281   #undef HAVE_WINDNS_H
00282 #endif
00283
00284 #endif /* _w32_CONFIG_H */
00285
Generated on Wed Jan 25 15:42:34 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/CONNECT.C Source File

SRC/CONNECT.C

Go to the documentation of this file.
00001
00005 /*  BSD sockets functionality for Waterloo TCP/IP
00006  *
00007  *  Copyright (c) 1997-2002 Gisle Vanem <giva@bgnett.no>
00008  *
00009  *  Redistribution and use in source and binary forms, with or without
00010  *  modification, are permitted provided that the following conditions
00011  *  are met:
00012  *  1. Redistributions of source code must retain the above copyright
00013  *     notice, this list of conditions and the following disclaimer.
00014  *  2. Redistributions in binary form must reproduce the above copyright
00015  *     notice, this list of conditions and the following disclaimer in the
00016  *     documentation and/or other materials provided with the distribution.
00017  *  3. All advertising materials mentioning features or use of this software
00018  *     must display the following acknowledgement:
00019  *       This product includes software developed by Gisle Vanem
00020  *       Bergen, Norway.
00021  *
00022  *  THIS SOFTWARE IS PROVIDED BY ME (Gisle Vanem) AND CONTRIBUTORS ``AS IS''
00023  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00024  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00025  *  ARE DISCLAIMED.  IN NO EVENT SHALL I OR CONTRIBUTORS BE LIABLE FOR ANY
00026  *  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00027  *  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00028  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00029  *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00030  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00031  *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00032  *
00033  *  Version
00034  *
00035  *  0.5 : Dec 18, 1997 : G. Vanem - created
00036  *  0.6 : Aug 06, 2002 : G. Vanem - added AF_INET6 support
00037  */
00038
00039 #include "socket.h"
00040
00041 #if defined(USE_BSD_API)
00042
00043 static int tcp_connect  (Socket *socket);
00044 static int udp_connect  (Socket *socket);
00045 static int raw_connect  (Socket *socket);
00046 static int nblk_connect (Socket *socket);
00047
00048 /*
00049  * connect()
00050  *  "connect" will attempt to open a connection on a foreign IP address and
00051  *  foreign port address.  This is achieved by specifying the foreign IP
00052  *  address and foreign port number in the "servaddr".
00053  */
00054 int W32_CALL connect (int s, const struct sockaddr *servaddr, int addrlen)
00055 {
00056   struct   sockaddr_in  *addr   = (struct sockaddr_in*) servaddr;
00057   struct   sockaddr_in6 *addr6  = (struct sockaddr_in6*) servaddr;
00058   struct   Socket       *socket = _socklist_find (s);
00059   volatile int rc, sa_len;
00060   BOOL     is_ip6;
00061
00062   SOCK_PROLOGUE (socket, "\nconnect:%d", s);
00063
00064   is_ip6 = (socket->so_family == AF_INET6);
00065   sa_len = is_ip6 ? sizeof(*addr6) : sizeof(*addr);
00066
00067   if (_sock_chk_sockaddr(socket, servaddr, addrlen) < 0)
00068      return (-1);
00069
00070   if (socket->so_type == SOCK_STREAM)
00071   {
00072     if (socket->so_state & SS_ISCONNECTED)
00073     {
00074       SOCK_DEBUGF ((", EISCONN"));
00075       SOCK_ERRNO (EISCONN);
00076       return (-1);
00077     }
00078     if (socket->so_options & SO_ACCEPTCONN)
00079     {
00080       SOCK_DEBUGF ((", EOPNOTSUPP (listen sock)"));
00081       SOCK_ERRNO (EOPNOTSUPP);
00082       return (-1);
00083     }
00084     if (!is_ip6 && IN_MULTICAST(ntohl(addr->sin_addr.s_addr)))
00085     {
00086       SOCK_DEBUGF ((", EINVAL (mcast)"));
00087       SOCK_ERRNO (EINVAL);
00088       return (-1);
00089     }
00090     else if (is_ip6 && IN6_IS_ADDR_MULTICAST(&addr6->sin6_addr))
00091     {
00092       SOCK_DEBUGF ((", EINVAL (mcast)"));
00093       SOCK_ERRNO (EINVAL);
00094       return (-1);
00095     }
00096   }
00097
00098   if (socket->remote_addr)
00099   {
00100     if ((socket->so_type == SOCK_STREAM) &&
00101         (socket->so_state & SS_NBIO))
00102        return nblk_connect (socket);
00103
00104     SOCK_DEBUGF ((", connect already done!"));
00105     SOCK_ERRNO (EISCONN);
00106     return (-1);
00107   }
00108
00109   socket->remote_addr = (struct sockaddr_in*) SOCK_CALLOC (sa_len);
00110   if (!socket->remote_addr)
00111   {
00112     SOCK_DEBUGF ((", ENOMEM (rem)"));
00113     SOCK_ERRNO (ENOMEM);
00114     return (-1);
00115   }
00116
00117 #if defined(USE_IPV6)
00118   if (is_ip6)
00119   {
00120     struct sockaddr_in6 *ra = (struct sockaddr_in6*)socket->remote_addr;
00121
00122     ra->sin6_family = AF_INET6;
00123     ra->sin6_port   = addr6->sin6_port;
00124     memcpy (&ra->sin6_addr, &addr6->sin6_addr, sizeof(ra->sin6_addr));
00125   }
00126   else
00127 #endif
00128   {
00129     socket->remote_addr->sin_family = AF_INET;
00130     socket->remote_addr->sin_port   = addr->sin_port;
00131     socket->remote_addr->sin_addr   = addr->sin_addr;
00132   }
00133
00134   if (!socket->local_addr)
00135   {
00136     SOCK_DEBUGF ((", auto-binding"));
00137
00138     socket->local_addr = (struct sockaddr_in*) SOCK_CALLOC (sa_len);
00139     if (!socket->local_addr)
00140     {
00141       free (socket->remote_addr);
00142       socket->remote_addr = NULL;
00143       SOCK_DEBUGF ((", ENOMEM (loc)"));
00144       SOCK_ERRNO (ENOMEM);
00145       return (-1);
00146     }
00147
00148 #if defined(USE_IPV6)
00149     if (is_ip6)
00150     {
00151       struct sockaddr_in6 *la = (struct sockaddr_in6*)socket->local_addr;
00152
00153       la->sin6_family = AF_INET6;
00154       la->sin6_port   = htons (find_free_port(0,TRUE));
00155       memcpy (&la->sin6_addr, &in6addr_my_ip, sizeof(la->sin6_addr));
00156     }
00157     else
00158 #endif
00159     {
00160       socket->local_addr->sin_family      = AF_INET;
00161       socket->local_addr->sin_port        = htons (find_free_port(0,TRUE));
00162       socket->local_addr->sin_addr.s_addr = htonl (my_ip_addr);
00163     }
00164   }
00165
00166   SOCK_DEBUGF ((", src/dest ports: %u/%u",
00167                 ntohs(socket->local_addr->sin_port),
00168                 ntohs(socket->remote_addr->sin_port)));
00169
00170
00171   /* Not safe to run sock_daemon() now
00172    */
00173   _sock_crit_start();
00174
00175   /* Setup SIGINT handler now.
00176    */
00177   if (_sock_sig_setup() < 0)
00178   {
00179     SOCK_ERRNO (EINTR);
00180     SOCK_DEBUGF ((", EINTR"));
00181     _sock_crit_stop();
00182     return (-1);
00183   }
00184
00185   switch (socket->so_type)
00186   {
00187     case SOCK_STREAM:
00188          rc = tcp_connect (socket);
00189          break;
00190
00191     case SOCK_DGRAM:
00192          rc = udp_connect (socket);
00193          break;
00194
00195     case SOCK_RAW:
00196          rc = raw_connect (socket);
00197          break;
00198
00199     default:
00200          SOCK_ERRNO (EPROTONOSUPPORT);
00201          rc = -1;
00202          break;
00203   }
00204
00205   _sock_sig_restore();
00206   _sock_crit_stop();
00207   return (rc);
00208 }
00209
00210 /*
00211  * Handle SOCK_DGRAM connection. Always blocking in _arp_resolve()
00212  */
00213 static int udp_connect (Socket *socket)
00214 {
00215 #if defined(USE_IPV6)
00216   if (socket->so_family == AF_INET6)
00217   {
00218     const struct sockaddr_in6 *la = (const struct sockaddr_in6*) socket->local_addr;
00219     const struct sockaddr_in6 *ra = (const struct sockaddr_in6*) socket->remote_addr;
00220
00221     if (!_UDP6_open (socket, &ra->sin6_addr, la->sin6_port, ra->sin6_port))
00222     {
00223       SOCK_DEBUGF ((", no route (udp6)"));
00224       SOCK_ERRNO (EHOSTUNREACH);
00225       STAT (ip6stats.ip6s_noroute++);
00226       return (-1);
00227     }
00228   }
00229   else
00230 #endif
00231   if (!_UDP_open (socket,
00232                   socket->remote_addr->sin_addr,
00233                   socket->local_addr->sin_port,
00234                   socket->remote_addr->sin_port))
00235   {
00236     /* errno already set in udp_open() */
00237     SOCK_DEBUGF ((", %s", socket->udp_sock->err_msg));
00238     return (-1);
00239   }
00240
00241   if ((socket->so_state & SS_PRIV) && socket->bcast_pool)
00242   {
00243     /* undo what udp_open() did above.
00244      * !!Fix me: clears recv data.
00245      */
00246     sock_recv_init ((sock_type*)socket->udp_sock,
00247                     socket->bcast_pool, socket->pool_size);
00248   }
00249
00250   socket->so_state &= ~SS_UNCONNECTED;
00251   socket->so_state |=  SS_ISCONNECTED;
00252   return (0);
00253 }
00254
00255
00256 /*
00257  * SOCK_RAW "connect" is very simple.
00258  */
00259 static int raw_connect (Socket *socket)
00260 {
00261   socket->so_state |= SS_ISCONNECTED;
00262
00263   /* Note: _arp_resolve() is done in ip_transmit()
00264    */
00265   return (0);
00266 }
00267
00268 /*
00269  * Check for catched signals
00270  */
00271 static int chk_signals (void)
00272 {
00273   if (_sock_sig_pending())
00274   {
00275     SOCK_DEBUGF ((", EINTR"));
00276     SOCK_ERRNO (EINTR);
00277     return (-1);
00278   }
00279   return (0);
00280 }
00281
00282 /*
00283  * Handle SOCK_STREAM blocking connection. Or non-blocking connect
00284  * the first time connect() is called.
00285  */
00286 static int tcp_connect (Socket *socket)
00287 {
00288   DWORD timeout;
00289   int   status;
00290
00291 #if defined(USE_IPV6)
00292   if (socket->so_family == AF_INET6)
00293   {
00294     const struct sockaddr_in6 *la = (const struct sockaddr_in6*) socket->local_addr;
00295     const struct sockaddr_in6 *ra = (const struct sockaddr_in6*) socket->remote_addr;
00296
00297     if (!_TCP6_open (socket, &ra->sin6_addr, la->sin6_port, ra->sin6_port))
00298     {
00299       /* errno already set in _TCP6_open() */
00300       SOCK_DEBUGF ((", %s", socket->tcp_sock->err_msg));
00301       return (-1);
00302     }
00303   }
00304   else
00305 #endif
00306   if (!_TCP_open (socket,
00307                   socket->remote_addr->sin_addr,
00308                   socket->local_addr->sin_port,
00309                   socket->remote_addr->sin_port))
00310   {
00311     /* errno already set in tcp_open() */
00312     SOCK_DEBUGF ((", %s", socket->tcp_sock->err_msg));
00313     return (-1);
00314   }
00315
00316   /* Don't let tcp_Retransmitter() kill this socket
00317    * before our `socket->timeout' expires
00318    */
00319   socket->tcp_sock->locflags |= LF_RCVTIMEO;
00320
00321   /* We're here only when connect() is called the 1st time
00322    * (blocking or non-blocking socket).
00323    */
00324   socket->so_state |= SS_ISCONNECTING;
00325   timeout = set_timeout (1000 * socket->timeout);
00326
00327   if (socket->so_state & SS_NBIO)
00328   {
00329     /* if user calls getsockopt(SO_ERROR) before calling connect() again
00330      */
00331     socket->so_error = EALREADY;
00332     socket->nb_timer = timeout;
00333     SOCK_DEBUGF ((", EINPROGRESS"));
00334     SOCK_ERRNO (EINPROGRESS);
00335     return (-1);
00336   }
00337
00338   /* Handle blocking stream socket connect.
00339    * Maybe we should use select_s() instead ?
00340    * Maybe set LF_NOCLOSE for all BSD sockets?
00341    */
00342   status = _ip_delay0 ((sock_type*)socket->tcp_sock,
00343                        socket->timeout, (UserHandler)chk_signals,
00344                        NULL);
00345
00346   if (socket->so_error == EHOSTUNREACH)
00347   {
00348     SOCK_DEBUGF ((", %s", socket->tcp_sock->err_msg ?
00349                   socket->tcp_sock->err_msg : "no route"));
00350     SOCK_ERRNO (EHOSTUNREACH);
00351     return (-1);
00352   }
00353
00354   /* We got an ICMP_UNREACH from someone
00355    */
00356   if (socket->so_state & SS_CONN_REFUSED)
00357   {
00358     socket->so_state &= ~SS_ISCONNECTING;
00359     SOCK_DEBUGF ((", ECONNREFUSED"));
00360     SOCK_ERRNO (ECONNREFUSED);
00361     return (-1);
00362   }
00363
00364   if (status < 0 && chk_timeout(timeout))
00365   {
00366     socket->so_state &= ~SS_ISCONNECTING;
00367     SOCK_DEBUGF ((", ETIMEDOUT"));
00368     SOCK_ERRNO (ETIMEDOUT);
00369     return (-1);
00370   }
00371
00372   if (status < 0)
00373   {
00374     socket->so_state &= ~SS_ISCONNECTING;
00375     SOCK_DEBUGF ((", ECONNRESET"));
00376     SOCK_ERRNO (ECONNRESET);
00377     return (-1);
00378   }
00379
00380   socket->so_state &= ~(SS_UNCONNECTED | SS_ISCONNECTING);
00381   socket->so_state |=  SS_ISCONNECTED;
00382   return (0);
00383 }
00384
00385
00386 /*
00387  * Handle non-blocking SOCK_STREAM connection.
00388  * Only called on 2nd (3rd etc) time a non-blocking
00389  * connect() is called.
00390  */
00391 static int nblk_connect (Socket *socket)
00392 {
00393   if (socket->so_state & SS_ISCONNECTED)
00394   {
00395     SOCK_DEBUGF ((", connected!"));
00396     socket->so_error = 0;
00397     return (0);
00398   }
00399
00400   /* Don't let tcp_Retransmitter() timeout this socket
00401    * (unless there is a ARP timeout etc.)
00402    */
00403   socket->tcp_sock->timeout = 0;
00404
00405   if ((socket->so_state & (SS_ISDISCONNECTING | SS_CONN_REFUSED)) ||
00406       (socket->tcp_sock->state >= tcp_StateCLOSED))
00407   {
00408     if (socket->so_error != 0 && socket->so_error != EALREADY)
00409     {
00410       SOCK_DEBUGF ((", %s", short_strerror(socket->so_error)));
00411       SOCK_ERRNO (socket->so_error);
00412     }
00413     else if (chk_timeout(socket->nb_timer))
00414     {
00415       socket->so_state &= ~SS_ISCONNECTING;
00416       SOCK_DEBUGF ((", ETIMEDOUT (%s)", socket->tcp_sock->err_msg));
00417       socket->so_error = ETIMEDOUT;
00418       SOCK_ERRNO (ETIMEDOUT);
00419     }
00420     else
00421     {
00422       SOCK_DEBUGF ((", ECONNREFUSED"));
00423       socket->so_error = ECONNREFUSED;
00424       SOCK_ERRNO (ECONNREFUSED);       /* could also be ECONNRESET */
00425     }
00426     return (-1);
00427   }
00428
00429   if (socket->so_state & SS_ISCONNECTING)
00430   {
00431     SOCK_DEBUGF ((", EALREADY"));
00432     socket->so_error = EALREADY;       /* should be redundant */
00433     SOCK_ERRNO (EALREADY);
00434     return (-1);
00435   }
00436
00437   SOCK_FATAL (("%s (%d) Fatal: Unhandled non-block event\n",
00438               __FILE__, __LINE__));
00439   return (-1);
00440 }
00441 #endif /* USE_BSD_API */
Generated on Wed Jan 25 15:42:34 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/COPYRIGH.H Source File

SRC/COPYRIGH.H

Go to the documentation of this file.
00001
Generated on Wed Jan 25 15:42:34 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/COUNTRY.C Source File

SRC/COUNTRY.C

Go to the documentation of this file.
00001
00006 /*
00007  *  Copyright (c) 1997-2002 Gisle Vanem <giva@bgnett.no>
00008  *
00009  *  Redistribution and use in source and binary forms, with or without
00010  *  modification, are permitted provided that the following conditions
00011  *  are met:
00012  *  1. Redistributions of source code must retain the above copyright
00013  *     notice, this list of conditions and the following disclaimer.
00014  *  2. Redistributions in binary form must reproduce the above copyright
00015  *     notice, this list of conditions and the following disclaimer in the
00016  *     documentation and/or other materials provided with the distribution.
00017  *  3. All advertising materials mentioning features or use of this software
00018  *     must display the following acknowledgement:
00019  *       This product includes software developed by Gisle Vanem
00020  *       Bergen, Norway.
00021  *
00022  *  THIS SOFTWARE IS PROVIDED BY ME (Gisle Vanem) AND CONTRIBUTORS ``AS IS''
00023  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00024  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00025  *  ARE DISCLAIMED.  IN NO EVENT SHALL I OR CONTRIBUTORS BE LIABLE FOR ANY
00026  *  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00027  *  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00028  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00029  *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00030  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00031  *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00032  *
00033  *
00034  *  These funtions are meant to:
00035  *   1) automatic detection and selection of language for the _LANG()
00036  *      function.  But not yet.
00037  *   2) obtaining the active codepage for IDNA/ACE conversion stuff.
00038  */
00039
00040 #include <stdio.h>
00041 #include <stdlib.h>
00042
00043 #include "wattcp.h"
00044 #include "wdpmi.h"
00045 #include "x32vm.h"
00046 #include "powerpak.h"
00047 #include "misc.h"
00048
00049 #if !defined(WIN32)
00050
00051 static char country_info[35];  /* not used yet */
00052
00053 int GetCountryCode (void)
00054 {
00055   IREGS reg;
00056
00057   if (_watt_os_ver < 0x300)
00058      return (0);
00059
00060   memset (&reg, 0, sizeof(reg));
00061   reg.r_ax = 0x3800;
00062
00063 #if (DOSX & DJGPP)
00064   if (_go32_info_block.size_of_transfer_buffer < sizeof(country_info))
00065      return (0);
00066   reg.r_ds = __tb / 16;
00067   reg.r_dx = __tb & 15;
00068
00069 #elif (DOSX & (PHARLAP|X32VM|POWERPAK))
00070   if (_watt_dosTbSize < sizeof(country_info))
00071      return (0);
00072   reg.r_ds = RP_SEG (_watt_dosTbr);
00073   reg.r_dx = RP_OFF (_watt_dosTbr);
00074
00075 #elif (DOSX & DOS4GW)
00076   if (_watt_dosTbSize < sizeof(country_info))
00077      return (0);
00078   reg.r_ds = _watt_dosTbSeg;
00079   reg.r_dx = 0;
00080
00081 #elif (DOSX == 0)
00082   reg.r_ds = FP_SEG (country_info);
00083   reg.r_dx = FP_OFF (country_info);
00084
00085 #else
00086   #error Unexpected target!
00087 #endif
00088
00089   GEN_INTERRUPT (0x21, &reg);
00090   if (reg.r_flags & 1)
00091      return (0);
00092
00093   memset (&country_info, 0, sizeof(country_info));
00094
00095 #if (DOSX & DJGPP)
00096   dosmemget (__tb, sizeof(country_info), &country_info);
00097
00098 #elif (DOSX & (PHARLAP|X32VM|POWERPAK))
00099   ReadRealMem (&country_info, _watt_dosTbr, sizeof(country_info));
00100
00101 #elif (DOSX & DOS4GW)
00102   memcpy (&country_info, SEG_OFS_TO_LIN(_watt_dosTbSeg,0), sizeof(country_info));
00103 #endif
00104
00105   return (WORD)reg.r_bx;
00106 }
00107
00108 /*
00109  * Return active codepage
00110  */
00111 int GetCodePage (void)
00112 {
00113   IREGS reg;
00114
00115   if (_watt_os_ver < 0x303)
00116      return (0);
00117
00118   memset (&reg, 0, sizeof(reg));
00119   reg.r_ax = 0x6601;
00120   GEN_INTERRUPT (0x21, &reg);
00121   if (reg.r_flags & CARRY_BIT)
00122      return (0);
00123   return (WORD)reg.r_bx;
00124 }
00125 #endif    /* !WIN32 */
00126
Generated on Wed Jan 25 15:42:34 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/CPUMODEL.H Source File

SRC/CPUMODEL.H

Go to the documentation of this file.
00001
00004 /*
00005  *  This file contains declaration for variables and code
00006  *  that may be used to get the Intel Cpu identification
00007  *  that has been performed by CheckCpuType() function.
00008  *
00009  *  COPYRIGHT (c) 1998 valette@crf.canon.fr
00010  *
00011  *  The license and distribution terms for this file may be
00012  *  found in the file LICENSE in this distribution or at
00013  *  http://www.OARcorp.com/rtems/license.html.
00014  *
00015  *  $Id: cpumodel.h,v 1.2 1998/08/05 16:51:39 joel Exp $
00016  */
00017
00018 #if !defined(_w32_CPUMODEL_H) && (DOSX)  /* Only for DOSX/Win32 targets */
00019 #define _w32_CPUMODEL_H
00020
00021 #if defined(CPU_TEST) || defined(__LCC__)
00022   #undef  CONST
00023   #define CONST
00024 #else
00025   #define CONST const
00026 #endif
00027
00028 #if defined(__DMC__)
00029   #define SYSCALL __syscall        /* no underscore prefix */
00030 #else
00031   #define SYSCALL
00032 #endif
00033
00034 #if defined(__GNUC__) || defined(_MSC_VER)
00035   #define DATA_DECL
00036 #else
00037   #define DATA_DECL cdecl
00038 #endif
00039
00040 extern CONST char  DATA_DECL x86_type;       /* type of CPU (3=386, 4=486, ...) */
00041 extern CONST char  DATA_DECL x86_model;
00042 extern CONST char  DATA_DECL x86_mask;
00043 extern CONST int   DATA_DECL x86_hard_math;  /* FPU present */
00044 extern CONST DWORD DATA_DECL x86_capability;
00045 extern CONST int   DATA_DECL x86_have_cpuid;
00046 extern CONST char  DATA_DECL x86_vendor_id[13];
00047
00048 /* x86_capability bits
00049  */
00050 #define X86_CAPA_FPU        (1UL << 0)     /* Floating Point processor */
00051 #define X86_CAPA_VME        (1UL << 1)     /* V86 Mode Extensions */
00052 #define X86_CAPA_DE         (1UL << 2)     /* Debug Extensions */
00053 #define X86_CAPA_PSE        (1UL << 3)     /* Page Size Extensions */
00054 #define X86_CAPA_TSC        (1UL << 4)     /* Time Stamp Counter */
00055 #define X86_CAPA_MSR        (1UL << 5)     /* Model Specific Registers */
00056 #define X86_CAPA_PAE        (1UL << 6)     /* Physical Address Extensions */
00057 #define X86_CAPA_MCE        (1UL << 7)     /* Machine Check Exception */
00058 #define X86_CAPA_CX8        (1UL << 8)     /* CMPXCHG8B instruction available */
00059 #define X86_CAPA_APIC       (1UL << 9)     /* APIC present (multiproc support) */
00060 #define X86_CAPA_FSC        (1UL << 10)    /* Fast System Call (AMD K6/Cyrix) */
00061 #define X86_CAPA_SEP        (1UL << 11)    /* Fast system call (SYSENTER/SYSEXIT) */
00062 #define X86_CAPA_MTRR       (1UL << 12)    /* Memory Type Range Registers */
00063 #define X86_CAPA_PGE        (1UL << 13)    /* Page Global Enable */
00064 #define X86_CAPA_MCA        (1UL << 14)    /* Machine Check Architecture */
00065 #define X86_CAPA_CMOV       (1UL << 15)    /* Conditional MOVe instructions */
00066 #define X86_CAPA_PAT        (1UL << 16)    /* Page Attribute Table */
00067 #define X86_CAPA_PSE36      (1UL << 17)    /* 36 bit Page Size Extenions */
00068 #define X86_CAPA_PSN        (1UL << 18)    /* Processor Serial Number */
00069 #define X86_CAPA_CFLSH      (1UL << 19)    /* Cache Flush */
00070 #define X86_CAPA_RSRV_20    (1UL << 20)    /* Reserved */
00071 #define X86_CAPA_DTES       (1UL << 21)    /* Debug Trace Store */
00072 #define X86_CAPA_ACPI       (1UL << 22)    /* ACPI support */
00073 #define X86_CAPA_MMX        (1UL << 23)    /* MultiMedia Extensions */
00074 #define X86_CAPA_FXSR       (1UL << 24)    /* FXSAVE/FXRSTOR instructions */
00075 #define X86_CAPA_SSE        (1UL << 25)    /* SSE instructions */
00076 #define X86_CAPA_SSE2       (1UL << 26)    /* SSE2 instructions */
00077 #define X86_CAPA_SSNOOP     (1UL << 27)    /* SELFSNOOP */
00078 #define X86_CAPA_RSRV_28    (1UL << 28)    /* Reserved */
00079 #define X86_CAPA_ACC        (1UL << 29)    /* Automatic Clock Control */
00080 #define X86_CAPA_IA64       (1UL << 30)    /* IA64 instructions */
00081 #define X86_CAPA_RSRV_31    (1UL << 31)    /* Reserved */
00082
00083 /* CR4 register bits.
00084  */
00085 #define CR4_TS_DISABLE  0x004
00086 #define CR4_OSFXSR      0x100  /* ?? OS does FXSAVE/FXRSTOR on task switch */
00087
00088 #if !defined(__LCC__)
00089   #define CheckCpuType NAMESPACE (CheckCpuType)
00090   #define MY_CS        NAMESPACE (MY_CS)
00091   #define MY_DS        NAMESPACE (MY_DS)
00092   #define MY_ES        NAMESPACE (MY_ES)
00093   #define MY_SS        NAMESPACE (MY_SS)
00094   #define asm_ffs      NAMESPACE (asm_ffs)
00095   #define Get_CR4      NAMESPACE (Get_CR4)
00096   #define SelWriteable NAMESPACE (SelWriteable)
00097   #define SelReadable  NAMESPACE (SelReadable)
00098   #define get_cpuid    NAMESPACE (get_cpuid)
00099   #define get_rdtsc    NAMESPACE (get_rdtsc)
00100   #define get_rdtsc2   NAMESPACE (get_rdtsc2)
00101
00102   extern void  SYSCALL cdecl CheckCpuType (void);
00103   extern int   SYSCALL cdecl asm_ffs (int val);
00104
00105   extern WORD  SYSCALL cdecl MY_CS   (void);
00106   extern WORD  SYSCALL cdecl MY_DS   (void);
00107   extern WORD  SYSCALL cdecl MY_ES   (void);
00108   extern WORD  SYSCALL cdecl MY_SS   (void);
00109   extern DWORD SYSCALL cdecl Get_CR4 (void);
00110
00111   extern BOOL  SYSCALL cdecl SelWriteable(WORD sel);
00112   extern BOOL  SYSCALL cdecl SelReadable (WORD sel);
00113 #endif
00114
00115 #if defined(__WATCOMC__) && 0 /* no more need for this */
00116   #pragma aux x86_type                    "*"
00117   #pragma aux x86_model                   "*"
00118   #pragma aux x86_mask                    "*"
00119   #pragma aux x86_hard_math               "*"
00120   #pragma aux x86_capability              "*"
00121   #pragma aux x86_vendor_id               "*"
00122   #pragma aux x86_have_cpuid              "*"
00123
00124   #pragma aux (__cdecl) _w32_CheckCpuType "*"
00125   #pragma aux (__cdecl) _w32_MY_CS        "*"
00126   #pragma aux (__cdecl) _w32_MY_DS        "*"
00127   #pragma aux (__cdecl) _w32_MY_ES        "*"
00128   #pragma aux (__cdecl) _w32_MY_SS        "*"
00129   #pragma aux (__cdecl) _w32_asm_ffs      "*"
00130   #pragma aux (__cdecl) _w32_Get_CR4      "*"
00131   #pragma aux (__cdecl) _w32_SelWriteable "*"
00132   #pragma aux (__cdecl) _w32_SelReadable  "*"
00133
00134 #elif defined(__HIGHC__)
00135   #pragma alias (x86_type,         "x86_type")
00136   #pragma alias (x86_model,        "x86_model")
00137   #pragma alias (x86_mask,         "x86_mask")
00138   #pragma alias (x86_hard_math,    "x86_hard_math")
00139   #pragma alias (x86_capability,   "x86_capability")
00140   #pragma alias (x86_vendor_id,    "x86_vendor_id")
00141   #pragma alias (x86_have_cpuid,   "x86_have_cpuid")
00142
00143   #pragma alias (_w32_CheckCpuType,"_w32_CheckCpuType")
00144   #pragma alias (_w32_MY_CS,       "_w32_MY_CS")
00145   #pragma alias (_w32_MY_DS,       "_w32_MY_DS")
00146   #pragma alias (_w32_MY_ES,       "_w32_MY_ES")
00147   #pragma alias (_w32_MY_SS,       "_w32_MY_SS")
00148   #pragma alias (_w32_asm_ffs,     "_w32_asm_ffs")
00149   #pragma alias (_w32_Get_CR4,     "_w32_Get_CR4")
00150   #pragma alias (_w32_SelWriteable,"_w32_SelWriteable")
00151   #pragma alias (_w32_SelReadable, "_w32_SelReadable")
00152 #endif
00153
00154
00155 #if defined(__GNUC__)
00156   /*
00157    * Call this only if x86_have_cpuid == TRUE.
00158    */
00159   /*@unused@*/ extern __inline__ void get_cpuid (DWORD val, DWORD *eax,
00160                                                  DWORD *ebx,DWORD *ecx,
00161                                                  DWORD *edx)
00162   {
00163     __asm__ __volatile__ (
00164               ".byte 0x0F,0xA2;"   /* cpuid opcode */
00165             : "=a" (*eax), "=b" (*ebx), "=c" (*ecx), "=d" (*edx)
00166             : "0" (val));
00167     ARGSUSED (val);  /* for lint */
00168     ARGSUSED (eax);
00169     ARGSUSED (ebx);
00170     ARGSUSED (ecx);
00171     ARGSUSED (edx);
00172   }
00173
00174   /*
00175    * Return CPU timestamp value. Don't call unless 'has_rdtsc'
00176    * is TRUE. This code is originally by
00177    *   Tom Burgess <Tom_Burgess@bc.sympatico.ca> and
00178    *   Douglas Eleveld <deleveld@dds.nl>
00179    */
00180   extern __inline__ uint64 get_rdtsc (void)
00181   {
00182     register uint64 tsc;
00183     __asm__ __volatile__ (
00184               ".byte 0x0F, 0x31;"   /* rdtsc opcode */
00185             : "=A" (tsc) );
00186     return (tsc);
00187   }
00188
00189   extern __inline__ void get_rdtsc2 (struct ulong_long *tsc)
00190   {
00191     __asm__ __volatile__ (
00192               ".byte 0x0F, 0x31;"
00193             : "=a" (tsc->lo), "=d" (tsc->hi) : );
00194   }
00195
00196 #elif defined(WATCOM386)
00197   /*
00198    * Call this only if x86_have_cpuid == TRUE.
00199    */
00200   extern void get_cpuid (DWORD val, DWORD *eax, DWORD *ebx, DWORD *ecx, DWORD *edx);
00201   #pragma aux _w32_get_cpuid =   \
00202         ".586"              \
00203         "push eax"          \
00204         "push ebx"          \
00205         "push ecx"          \
00206         "push edx"          \
00207         "mov eax, esi"      \
00208         "cpuid"             \
00209         "mov esi, [esp]"    \
00210         "mov [esi], edx"    \
00211         "mov esi, [esp+4]"  \
00212         "mov [esi], ecx"    \
00213         "mov esi, [esp+8]"  \
00214         "mov [esi], ebx"    \
00215         "mov esi, [esp+12]" \
00216         "mov [esi], eax"    \
00217         "add esp, 16"       \
00218         parm [esi] [eax] [ebx] [ecx] [edx] \
00219         modify [esi eax ebx ecx edx];
00220
00221   extern uint64 get_rdtsc (void);
00222   #pragma aux _w32_get_rdtsc = \
00223           ".586"          \
00224           "db 0Fh, 31h"   \
00225           "cld"           \
00226           "nop"           \
00227           "nop"           \
00228           "nop"           \
00229           "nop"           \
00230           modify [eax edx];
00231
00232 #elif defined(__LCC__)
00233   #undef  get_rdtsc
00234   #define get_rdtsc() _rdtsc() /* in  <intrinsics.h> */
00235
00236 #else
00237   /*
00238    * No inlining for other targets
00239    */
00240   extern void SYSCALL cdecl get_cpuid (DWORD val, DWORD *_eax,
00241                                        DWORD *_ebx, DWORD *_ecx,
00242                                        DWORD *_edx);
00243   #ifdef HAVE_UINT64
00244   extern uint64 cdecl get_rdtsc (void);
00245   #endif
00246 #endif
00247
00248 #if (DOSX) && !defined(__GNUC__)
00249   extern void cdecl get_rdtsc2 (struct ulong_long *);
00250 #endif
00251
00252 #if defined(__HIGHC__)
00253   #pragma alias (get_cpuid,  "_w32_get_cpuid")
00254   #pragma alias (get_rdtsc,  "_w32_get_rdtsc")
00255   #pragma alias (get_rdtsc2, "_w32_get_rdtsc2")
00256 #endif
00257
00258
00259 #if 0 && (defined(__BORLANDC__) || defined(__DMC__)) && \
00260          (defined(__SMALL16__) || defined(__LARGE__))
00261 /*
00262  * Save FPU state.
00263  */
00264 static void pkt_save_fpu (char far *state)
00265 {
00266   __asm les bx, state
00267   __asm fnstcw  es:[bx]     /* save IEM bit status */
00268   __asm nop                 /* delay while control word saved */
00269   __asm fndisi              /* disable BUSY signal */
00270   __asm mov ax, es:[bx]     /* get original control word in AX */
00271   __asm fsave   es:[bx]     /* save FPU state */
00272   __asm fwait               /* wait for save to complete */
00273   __asm mov es:[bx],ax      /* put original control word in saved state */
00274 }
00275
00276 /*
00277  * Restore FPU state.
00278  */
00279 static void pkt_restore_fpu (char far *state)
00280 {
00281   __asm les bx, state
00282   __asm frstor es:[bx]
00283 }
00284 #endif
00285
00286 #undef SYSCALL
00287 #undef DATA_DECL
00288
00289 /*
00290  * Check if a CPUID instruction is available on this CPU.
00291  * Note used at the moment. See cpumodel.asm instead.
00292  */
00293 #if defined(__GNUC__)
00294 extern __inline__ BOOL have_cpuid (void)
00295 {
00296   int result = -1;
00297
00298   /* We're checking if the bit #21 of EFLAGS
00299    * can be toggled. If yes = CPUID is available.
00300    */
00301   __asm__ __volatile__ (
00302             "pushf\n"
00303             "popl %%eax\n"
00304             "xorl $0x200000, %%eax\n"
00305             "movl %%eax, %%ecx\n"
00306             "andl $0x200000, %%ecx\n"
00307             "pushl %%eax\n"
00308             "popf\n"
00309             "pushf\n"
00310             "popl %%eax\n"
00311             "andl $0x200000, %%eax\n"
00312             "xorl %%eax, %%ecx\n"
00313             "movl %%ecx, %0\n"
00314           : "=r" (result) : : "eax", "ecx");
00315   return (result == 0);
00316 }
00317
00318 #elif defined(_MSC_VER) || defined(__POCC__)
00319 __declspec(naked) static BOOL have_cpuid (void)
00320 {
00321   _asm {
00322     pushfd
00323     pop  eax
00324     mov  ecx, eax
00325     xor  eax, 1 << 21
00326     push eax
00327     popfd
00328     pushfd
00329     pop  eax
00330     xor  eax, ecx
00331     bt   eax, 21
00332     jnc  no_cpuid
00333     mov  eax, 1
00334     ret
00335 no_cpuid:
00336     mov  eax, 0
00337     ret
00338   }
00339 }
00340 #endif
00341
00342 #endif   /* !_w32_CPUMODEL_H && DOSX */
00343
Generated on Wed Jan 25 15:42:34 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/CRC.C Source File

SRC/CRC.C

Go to the documentation of this file.
00001
00010 #include <stdio.h>
00011 #include <stdlib.h>
00012
00013 #include "wattcp.h"
00014 #include "misc.h"
00015
00016 #define CRCBITS    32
00017 #define CRCHIBIT   ((DWORD) (1L << (CRCBITS-1)))
00018 #define CRCSHIFTS  (CRCBITS-8)
00019 #define PRZCRC     0x864CFBL   /* PRZ's 24-bit CRC generator polynomial */
00020
00021 static DWORD *crctable;        /* Table for speeding up CRC's */
00022
00023 /*
00024  * mk_crctbl() derives a CRC lookup table from the CRC polynomial.
00025  * The table is used later by watt_crc_bytes() below.
00026  * mk_crctbl() only needs to be called once at the dawn of time.
00027  *
00028  * The theory behind mk_crctbl() is that table[i] is initialized
00029  * with the CRC of i, and this is related to the CRC of `i >> 1',
00030  * so the CRC of `i >> 1' (pointed to by p) can be used to derive
00031  * the CRC of i (pointed to by q).
00032  */
00033 static void mk_crctbl (DWORD poly, DWORD *tab)
00034 {
00035   DWORD *p = tab;
00036   DWORD *q = tab;
00037   int    i;
00038
00039   *q++ = 0;
00040   *q++ = poly;
00041   for (i = 1; i < 128; i++)
00042   {
00043     DWORD t = *(++p);
00044
00045     if (t & CRCHIBIT)
00046     {
00047       t <<= 1;
00048       *q++ = t ^ poly;
00049       *q++ = t;
00050     }
00051     else
00052     {
00053       t <<= 1;
00054       *q++ = t;
00055       *q++ = t ^ poly;
00056     }
00057   }
00058 }
00059
00060 /*
00061  * Calculate 32-bit CRC on buffer buf with length len
00062  */
00063 DWORD crc_bytes (const char *buf, unsigned len)
00064 {
00065   DWORD accum;
00066
00067   for (accum = 0; crctable && len > 0; len--)
00068       accum = (accum << 8) ^ crctable[(BYTE)(accum >> CRCSHIFTS) ^ *buf++];
00069   return (accum);
00070 }
00071
00072 BOOL crc_init (void)
00073 {
00074   if (crctable)
00075      return (TRUE);
00076
00077   crctable = (DWORD*) calloc (sizeof(DWORD), 256);
00078   if (!crctable)
00079      return (FALSE);
00080
00081   mk_crctbl (PRZCRC, crctable);
00082   return (TRUE);
00083 }
00084
Generated on Wed Jan 25 15:42:34 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/CRIT.C Source File

SRC/CRIT.C

Go to the documentation of this file.
00001
00005 /* Targets:
00006  *    Metaware HighC / PharLap
00007  *    WatcomC (real/prot mode)  \todo finish suport for Watcom
00008  *    GNU C / djgpp2
00009  *    real-mode DOS targets
00010  *
00011  *  Copyright (c) 1997-2002 Gisle Vanem <giva@bgnett.no>
00012  *
00013  *  Redistribution and use in source and binary forms, with or without
00014  *  modification, are permitted provided that the following conditions
00015  *  are met:
00016  *  1. Redistributions of source code must retain the above copyright
00017  *     notice, this list of conditions and the following disclaimer.
00018  *  2. Redistributions in binary form must reproduce the above copyright
00019  *     notice, this list of conditions and the following disclaimer in the
00020  *     documentation and/or other materials provided with the distribution.
00021  *  3. All advertising materials mentioning features or use of this software
00022  *     must display the following acknowledgement:
00023  *       This product includes software developed by Gisle Vanem
00024  *       Bergen, Norway.
00025  *
00026  *  THIS SOFTWARE IS PROVIDED BY ME (Gisle Vanem) AND CONTRIBUTORS ``AS IS''
00027  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00028  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00029  *  ARE DISCLAIMED.  IN NO EVENT SHALL I OR CONTRIBUTORS BE LIABLE FOR ANY
00030  *  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00031  *  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00032  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00033  *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00034  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00035  *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00036  *
00037  */
00038
00039 #include <stdio.h>
00040 #include <stdlib.h>
00041
00042 #include "wattcp.h"
00043 #include "language.h"
00044 #include "x32vm.h"
00045 #include "misc.h"
00046
00047 #if defined(NOT_USED_ANYMORE) || 1
00048
00049 #if (DOSX & PHARLAP)
00050 #include <mw/exc.h>
00051 #endif
00052
00053 #include "nochkstk.h"     /* disable stack-checking here */
00054
00055 #if defined(__HIGHC__)
00056   #pragma off(Call_trace)
00057   #pragma off(Prolog_trace)
00058   #pragma off(Epilog_trace)
00059 #endif
00060
00061 #if (DOSX & (PHARLAP|X32VM))
00062   static REALPTR int24_old, rmcb;
00063
00064   static void cdecl int24_isr (SWI_REGS *reg)
00065   {
00066     reg->r_ax = 3;  /* simply fail the function */
00067   }                 /* note: this only works on DOS 3.0 and above */
00068
00069   void int24_restore (void)
00070   {
00071     if (!rmcb)
00072        return;
00073     _dx_ulock_pgsn (&int24_isr, 20);
00074     _dx_rmiv_set (CRIT_VECT, int24_old);
00075     _dx_free_rmode_wrapper (rmcb);
00076     rmcb = 0;
00077   }
00078
00079   void int24_init (void)
00080   {
00081     if (_watt_os_ver < 0x300)
00082        return;
00083
00084     _dx_rmiv_get (CRIT_VECT, &int24_old);
00085     rmcb = _dx_alloc_rmode_wrapper_iret (int24_isr, 256);
00086
00087     if (!rmcb)
00088        return;
00089
00090     _dx_lock_pgsn (&int24_isr, 20);
00091     _dx_rmiv_set (CRIT_VECT, rmcb);
00092     RUNDOWN_ADD (int24_restore, 20);
00093   }
00094
00095 /*---------------------------------------------------------------------*/
00096
00097 #elif (defined (__DMC__) && !defined(DMC386)) || defined(__WATCOMC__)
00098   static int _far int24_isr (unsigned dev_err, unsigned err_code,
00099                              unsigned _far *dev_hdr)
00100   {
00101     ARGSUSED (dev_err);
00102     ARGSUSED (dev_hdr);
00103     ARGSUSED (err_code);
00104     return (_HARDERR_FAIL);
00105   }
00106
00107   void int24_init (void)
00108   {
00109     if (_watt_os_ver >= 0x300)
00110       _harderr (int24_isr);
00111   }
00112
00113 /*---------------------------------------------------------------------*/
00114
00115 #elif (DOSX & DJGPP)
00116   static _go32_dpmi_seginfo rm_cb, int24_old;
00117   static __dpmi_regs        rm_reg;
00118
00119   static void int24_isr (void)
00120   {
00121     rm_reg.x.ax = 3;
00122   }
00123
00124   void int24_restore (void)
00125   {
00126     if (int24_old.rm_segment)
00127     {
00128       _go32_dpmi_set_real_mode_interrupt_vector (CRIT_VECT, &int24_old);
00129       _go32_dpmi_free_real_mode_callback (&rm_cb);
00130       int24_old.rm_segment = 0;
00131     }
00132   }
00133
00134   void int24_init (void)
00135   {
00136     if (_watt_os_ver < 0x300)
00137        return;
00138
00139     _go32_dpmi_get_real_mode_interrupt_vector (CRIT_VECT, &int24_old);
00140     rm_cb.pm_offset = (DWORD) int24_isr;
00141     if (_go32_dpmi_allocate_real_mode_callback_iret(&rm_cb,&rm_reg))
00142        return;
00143
00144     _go32_dpmi_set_real_mode_interrupt_vector (CRIT_VECT, &rm_cb);
00145     RUNDOWN_ADD (int24_restore, 20);
00146   }
00147
00148 /*---------------------------------------------------------------------*/
00149
00150 #elif DOSX == 0      /* real-mode targets */
00151   static W32_IntrHandler int24_old;
00152
00153   static INTR_PROTOTYPE int24_isr (bp,di,si,ds,es,dx,cx,bx,ax,ip,cs,flags)
00154   {
00155     ax = 3;
00156     ARGSUSED (bp); ARGSUSED (di); ARGSUSED (si); ARGSUSED (ds);
00157     ARGSUSED (es); ARGSUSED (dx); ARGSUSED (cx); ARGSUSED (bx);
00158     ARGSUSED (ax); ARGSUSED (ip); ARGSUSED (cs); ARGSUSED (flags);
00159   }
00160
00161   void int24_restore (void)
00162   {
00163     if (int24_old)
00164        setvect (CRIT_VECT, int24_old);
00165     int24_old = NULL;
00166   }
00167
00168   void int24_init (void)
00169   {
00170     if (_watt_os_ver >= 0x300)
00171     {
00172       int24_old = getvect (CRIT_VECT);
00173       setvect (CRIT_VECT, int24_isr);
00174       RUNDOWN_ADD (int24_restore, 20);
00175     }
00176   }
00177 #endif
00178
00179 #endif /* NOT_USED_ANYMORE */
Generated on Wed Jan 25 15:42:34 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/DYNIP.C Source File

SRC/DYNIP.C

Go to the documentation of this file.
00001
00010 #include <stdio.h>
00011 #include <stdlib.h>
00012 #include <string.h>
00013 #include <limits.h>
00014 #include <ctype.h>
00015 #include <netdb.h>
00016
00017 #include "wattcp.h"
00018 #include "strings.h"
00019 #include "language.h"
00020 #include "misc.h"
00021 #include "pcconfig.h"
00022 #include "pcbuf.h"
00023 #include "pctcp.h"
00024 #include "udp_dom.h"
00025 #include "netaddr.h"
00026 #include "dynip.h"
00027
00028 #if defined(USE_DYNIP_CLI)
00029
00030 #if defined(SNPRINTF)
00031   #define BUF(buf)   buf, sizeof(buf)
00032   #define _SNPRINTF  SNPRINTF
00033 #else
00034   #define BUF(buf)   buf
00035   #define _SNPRINTF  sprintf
00036 #endif
00037
00038 #if defined(USE_DEBUG)
00039   #define TRACE(lvl,arg) \
00040           do {           \
00041             if (trace_level >= lvl && dynip_enable) { \
00042                (*_printf) arg;  \
00043                fflush (stdout); \
00044             }                   \
00045           } while (0)
00046 #else
00047   #define TRACE(lvl,arg)   ((void)0)
00048 #endif
00049
00050 struct URL  {
00051        char *host;
00052        char *get_req;
00053        WORD  port;
00054        BOOL  on_heap;
00055      };
00056
00057 static char dyndns_user    [MAX_VALUELEN+1] = "";
00058 static char dyndns_passwd  [MAX_VALUELEN+1] = "";
00059 static char dyn_myhostname [MAX_VALUELEN+1] = "";
00060 static char dyn_myip [20]  = "";
00061 static BOOL dynip_enable   = FALSE;
00062 static int  dyndns_refresh = 3600;
00063 static int  trace_level    = 0;
00064 static char config_file [MAX_PATHLEN+1] = "$(TEMP)\\W32DYNIP.TMP";
00065
00066 static struct URL dyndns = { "members.dyndns.org",
00067                              "/nic/update?system=dyndns&hostname=%s",
00068                              80, FALSE
00069                            };
00070 static struct URL chkip  = { NULL, NULL, 0, FALSE };
00071
00072 static char   resp_buf [2048];
00073 static void (*prev_hook) (const char*, const char*);
00074
00075 static int get_url (const char *host, int port, const char *path,
00076                     const char *user_pass);
00077
00078 static const char *parse_myip_address (const char *buf);
00079 static int         parse_dyndns_response (const char *buf);
00080 static int         chkip_method (const char *value);
00081 static int         dyndns_params (const char *value);
00082 static void        url_free (struct URL *url);
00083 static BOOL        url_parse (struct URL *res, const char *url);
00084
00085
00091 static void dynip_config (const char *name, const char *value)
00092 {
00093   static const struct config_table dynip_cfg[] = {
00094        { "ENABLE",       ARG_ATOI,   (void*) &dynip_enable   },
00095        { "MY_IPADDRESS", ARG_FUNC,   (void*) chkip_method    },
00096        { "MY_HOSTNAME",  ARG_STRCPY, (void*) &dyn_myhostname },
00097        { "UPDATE",       ARG_FUNC,   (void*) dyndns_params   },
00098        { "USER",         ARG_STRCPY, (void*) &dyndns_user    },
00099        { "PASSWD",       ARG_STRCPY, (void*) &dyndns_passwd  },
00100        { "REFRESH",      ARG_ATOI,   (void*) &dyndns_refresh },
00101        { "TRACE",        ARG_ATOI,   (void*) &trace_level    },
00102        { "CONFIG",       ARG_STRCPY, (void*) &config_file    },
00103        { NULL,           0,          NULL                    }
00104      };
00105
00106   if (!parse_config_table(&dynip_cfg[0], "DYNIP.", name, value) && prev_hook)
00107      (*prev_hook) (name, value);
00108 }
00109
00113 static void dynip_exit (void)
00114 {
00115   if (_watt_fatal_error)
00116      return;
00117
00118   url_free (&chkip);
00119   url_free (&dyndns);
00120 }
00121
00122 void dynip_init (void)
00123 {
00124   prev_hook = usr_init;
00125   usr_init  = dynip_config;
00126   RUNDOWN_ADD (dynip_exit, 262);
00127 }
00128
00129 /*
00130  * Do this at most once each hour:
00131  *
00132  * 1. Get our WAN ip (<wan-ip> below) by fetching:
00133  *    http://checkip.dyndns.org  or  http://ipdetect.dnspark.com
00134  *
00135  * 2. Send HTTP request to members.dyndns.org (63.208.196.94):
00136  *    GET /nic/update?system=dyndns&hostname=<host-name>&myip=<wan-ip> HTTP/1.1
00137  *    Host: members.dyndns.org
00138  *    Authorization: Basic <user-name>:<password>  base64 encoded
00139  *    Connection: close
00140  *
00141  * 3. Get result: "nohost" means <host-name> isn't registered in DynDNS.
00142  *                "noauth" means wrong <user-name> or <passord>.
00143  *                "nohost" means <host-name> not registeredd with DynDNS.
00144  *                "notfqdn" means invalid <host-name> etc.
00145  *                "nochg <wan-ip>" means no update needed.
00146  *                "good <wan-ip>" means the update was acccepted.
00147  *
00148  * \todo: this should be rewritten as a non-blocking WatTCP daemon.
00149  *        Use addwattcpd (dynip_exec).
00150  */
00151 int dynip_exec (void)
00152 {
00153   char auth_buf [512] = "";
00154   char request [512], *p;
00155   int  num_arg, rc = 0;
00156
00157   if (!dynip_enable)
00158      return (0);
00159
00160   if (!dyn_myip[0] && chkip.host)  /* Not already entered as dotted quad */
00161   {
00162     const char *myip;
00163
00164     rc = get_url (chkip.host, chkip.port, chkip.get_req, NULL);
00165     if (rc <= 0)
00166        return (0);
00167
00168     myip = parse_myip_address (resp_buf);
00169
00170     TRACE (2, ("Got %d bytes HTML, Found myip: `%s'\r\n", rc, myip));
00171     if (!myip)
00172        return (0);
00173     StrLcpy (dyn_myip, myip, sizeof(dyn_myip));
00174   }
00175
00176   if (!dyn_myhostname[0] || !dyndns.get_req)
00177      return (0);
00178
00179   for (num_arg = 0, p = strstr(dyndns.get_req,"%s"); p;
00180        p = strstr(p+1,"%s"))
00181       num_arg++;
00182
00183   if (num_arg != 1 && num_arg != 2)
00184   {
00185     TRACE (1, ("Update URL (%s) must contain 1 or 2 \"%%s\" parameters\n",
00186            dyndns.get_req));
00187     return (0);
00188   }
00189
00190   if (dyndns_user[0] && dyndns_passwd[0])
00191      _SNPRINTF (BUF(auth_buf), "%s:%s", dyndns_user, dyndns_passwd);
00192   else if (dyndns_user[0])
00193      _SNPRINTF (BUF(auth_buf), "%s", dyndns_user);
00194
00195   _SNPRINTF (BUF(request), dyndns.get_req, dyn_myhostname, dyn_myip);
00196   if (!dyn_myip[0])
00197   {
00198     p = strrchr (request, '&');  /* chop of "&myip.." */
00199     if (p)
00200        *p = '\0';
00201   }
00202   rc = get_url (dyndns.host, dyndns.port, request,
00203                 *auth_buf ? auth_buf : NULL);
00204   if (rc <= 0)
00205      return (0);
00206   return parse_dyndns_response (resp_buf);
00207 }
00208
00213 static const char *parse_myip_address (const char *orig)
00214 {
00215   const char *body, *end, *ret, *p;
00216   char  *buf;
00217   static char res[20];
00218
00219   buf = strdup (orig);
00220   if (!buf)
00221   {
00222     TRACE (1, ("No memory\n"));
00223     return (NULL);
00224   }
00225
00226   strlwr (buf);
00227
00228   /* Accept "<body>" or "<body bgcolor..>" etc.
00229    */
00230   body = strstr (buf, "<body");
00231   if (!body)
00232   {
00233     TRACE (1, ("No <body>\n"));
00234     free (buf);
00235     return (NULL);
00236   }
00237
00238   p   = body + sizeof("<body")-1;
00239   end = strstr (p, "</body>");
00240   if (!end)
00241   {
00242     TRACE (1, ("No </body>\n"));
00243     free (buf);
00244     return (NULL);
00245   }
00246
00247   /* Find an IP-address between 'p' and 'end'
00248    */
00249   TRACE (2, ("p: `%s', len %d\n", p, end-p));
00250   ret = NULL;
00251
00252   for ( ; *p && p < end; p++)
00253       if (isdigit(*p) && aton(p))
00254       {
00255         ret = StrLcpy (res, p, min(end-p+1,SIZEOF(res)));
00256         break;
00257       }
00258   free (buf);
00259   return (ret);
00260 }
00261
00265 static int parse_dyndns_response (const char *buf)
00266 {
00267   TRACE (1, ("DynDNS resp: `%s'\n", buf));
00268
00269 #if 0
00270   if (!strncmp(buf,"nohost",6))
00271      ;
00272   if (!strncmp(buf,"noauth",6))
00273      ;
00274   if (!strncmp(buf,"notfqdn",7))
00275      ;
00276   if (!strncmp(buf,"nochg",5))
00277      ;
00278   if (!strncmp(buf,"good",4))
00279      ;
00280   if (!strncmp(buf,"!yours",6))
00281      ;
00282   if (!strncmp(buf,"abuse",5))
00283      ;
00284   if (!strncmp(buf,"numhost",7))
00285      ;
00286   if (!strncmp(buf,"dnserr",6))
00287      ;
00288 #endif
00289   ARGSUSED (buf);
00290   return (1);
00291 }
00292
00297 static BOOL url_parse (struct URL *res, const char *url)
00298 {
00299   char  scheme [20+1];
00300   char  buf [256+1];
00301   char *p;
00302   const char *orig_url = url;
00303   int   num;
00304
00305   res->port    = 80;    /* default values */
00306   res->host    = NULL;
00307   res->get_req = NULL;
00308   res->on_heap = FALSE;
00309
00310   p = strstr (url, "://");
00311   if (p)
00312   {
00313     StrLcpy (scheme, url, min(SIZEOF(scheme), p-url+1));
00314     if (stricmp(scheme,"http"))
00315     {
00316       TRACE (1, ("Unsupported scheme `%s'\n", scheme));
00317       return (FALSE);
00318     }
00319     url = p + 3;
00320   }
00321
00322   num = sscanf (url, "%256[^/]/%*s", buf);
00323
00324   p = strrchr (url, '/'); /* workaround for djgpp 2.04 sscanf() bug */
00325   if (p && !*(p+1))
00326      num = 1;
00327
00328   if (num >= 1)
00329   {
00330     p = strchr (buf, ':');
00331     if (p)
00332     {
00333       res->port = atoi (p+1);
00334       *p = '\0';
00335     }
00336     res->host = strdup (buf);
00337     res->on_heap = TRUE;
00338     p = strchr (url, '/');
00339     if (p)
00340        res->get_req = strdup (p);
00341     TRACE (2, ("url_parse: host `%s', port %u, req `%s'\r\n",
00342                res->host, res->port, res->get_req));
00343     return (TRUE);
00344   }
00345   TRACE (1, ("Malformed URL `%s'\r\n", orig_url));
00346   ARGSUSED (orig_url);
00347   return (FALSE);
00348 }
00349
00353 static void url_free (struct URL *url)
00354 {
00355   if (url->on_heap)
00356   {
00357     DO_FREE (url->get_req);
00358     DO_FREE (url->host);
00359   }
00360   url->on_heap = FALSE;
00361 }
00362
00367 static int chkip_method (const char *value)
00368 {
00369   if (isaddr(value))
00370        StrLcpy (dyn_myip, value, sizeof(dyn_myip));
00371   else url_parse (&chkip, value);
00372   return (1);
00373 }
00374
00379 static int dyndns_params (const char *value)
00380 {
00381   url_parse (&dyndns, value);
00382   return (1);
00383 }
00384
00385 /*
00386  * Taken from:
00387  *
00388  *   HTGET
00389  *
00390  *   Get a document via HTTP
00391  *
00392  *   This program was compiled under Borland C++ 3.1 in C mode for the small
00393  *   model. You will require the WATTCP libraries. A copy is included in the
00394  *   distribution. For the sources of WATTCP, ask archie where the archives
00395  *   are.
00396  *
00397  *   Please send bug fixes, ports and enhancements to the author for
00398  *   incorporation in newer versions.
00399  *
00400  *   Copyright (C) 1996  Ken Yap (ken@syd.dit.csiro.au)
00401  *
00402  *   This program is free software; you can redistribute it and/or modify it
00403  *   under the terms of the Artistic License, a copy of which is included
00404  *   with this distribution.
00405  *
00406  *   THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
00407  *   IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
00408  *   WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00409  */
00410 #define USER_AGENT  "Watt-32/DynIP-client 0.5"
00411 #define AUTHOR      "Copyright (C) 1996 Ken Yap (ken@syd.dit.csiro.au)"
00412
00413 #define HTTPVER     "HTTP/1.0"   /* HTTP version to use */
00414 #define HTTPVER10   "HTTP/1.0"
00415 #define HTTPVER11   "HTTP/1.1"
00416 #define strn(s)     s, sizeof(s)-1
00417
00418 static int base64encode (const char *in, char *out, size_t out_len)
00419 {
00420   int    c1, c2, c3;
00421   size_t len = 0;
00422   static char basis_64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"\
00423                            "abcdefghijklmnopqrstuvwxyz0123456789+/";
00424   while (*in)
00425   {
00426     c1 = *in++;
00427     if (*in == '\0')
00428        c2 = c3 = 0;
00429     else
00430     {
00431       c2 = *in++;
00432       if (*in == '\0')
00433            c3 = 0;
00434       else c3 = *in++;
00435     }
00436     out_len -= 4;
00437     if (out_len <= 4)
00438        return (-1);
00439
00440     *out++ = basis_64 [c1 >> 2];
00441     *out++ = basis_64 [((c1 & 0x3) << 4) | ((c2 & 0xF0) >> 4)];
00442     len += 2;
00443     if (c2 == 0 && c3 == 0)
00444     {
00445       *out++ = '=';
00446       *out++ = '=';
00447       len += 2;
00448     }
00449     else if (c3 == 0)
00450     {
00451       *out++ = basis_64 [((c2 & 0xF) << 2) | ((c3 & 0xC0) >> 6)];
00452       *out++ = '=';
00453       len += 2;
00454     }
00455     else
00456     {
00457       *out++ = basis_64 [((c2 & 0xF) << 2) | ((c3 & 0xC0) >> 6)];
00458       *out++ = basis_64 [c3 & 0x3F];
00459       len += 2;
00460     }
00461   }
00462   *out = '\0';
00463   return (0);
00464 }
00465
00471 static BOOL get_header (void *sock, long *cont_len_ptr)
00472 {
00473   int   i, len, response;
00474   long  content_length;
00475   char  buf [512];
00476   char *s;
00477
00478   *cont_len_ptr = 0L;
00479
00480   len = sock_gets (sock, (BYTE*)buf, sizeof(buf));
00481   if (len <= 0)
00482   {
00483     TRACE (1, ("EOF from server\n"));
00484     return (FALSE);
00485   }
00486   TRACE (1, ("HTTP: `%.*s'\r\n", len, buf));
00487
00488   if (strncmp(buf,strn(HTTPVER10)) &&  /* no HTTP/1.[01]? */
00489       strncmp(buf,strn(HTTPVER11)))
00490   {
00491     TRACE (1, ("Not a HTTP/1.[01] server\n"));
00492     return (FALSE);
00493   }
00494
00495   s = buf + sizeof(HTTPVER10)-1;
00496   i = strspn (s, " \t");
00497   if (i <= 0)        /* no whitespace? */
00498   {
00499     TRACE (1, ("Malformed HTTP/1.[01] line\n"));
00500     return (FALSE);
00501   }
00502
00503   s += i;
00504   response = 500;
00505   sscanf (s, "%3d", &response);
00506   if (response == 401)
00507   {
00508     TRACE (1, ("Authorisation failed\n"));
00509     return (FALSE);
00510   }
00511   if (response != 200 && response != 301 &&
00512       response != 302 && response != 304)
00513   {
00514     TRACE (1, ("Unexpected response %s\n", s));
00515     return (FALSE);
00516   }
00517
00518   /* Eat up the other header lines here.
00519    * Set to LONG_MAX, in case no "Content-length" header.
00520    */
00521   content_length = LONG_MAX;
00522
00523   while ((len = sock_gets(sock, (BYTE*)buf, sizeof(buf))) > 0)
00524   {
00525     TRACE (1, ("HTTP: `%.*s'\r\n", len, buf));
00526     s = buf;
00527     if (!strnicmp(s,strn("Content-Length:")))
00528     {
00529       s += sizeof("Content-Length:") - 1;
00530       content_length = atol (s);
00531     }
00532 #if 0
00533     else if (!strnicmp(s,strn("Transfer-encoding: chunked")))
00534     {
00535       TRACE (1, ("Chunked encoding not supported\n"));
00536       return (FALSE);
00537     }
00538 #endif
00539     else if (!strnicmp(buf, strn("Location:")))
00540     {
00541       if (response == 301 || response == 302)
00542          TRACE (1, ("Location at %s\n", buf));
00543     }
00544     else if (strchr(" \t", buf[0]))
00545             TRACE (1, ("Warning: continuation line encountered\n"));
00546   }
00547   *cont_len_ptr = content_length;
00548   return (TRUE);
00549 }
00550
00554 static int get_url (const char *host, int port, const char *path,
00555                     const char *user_pass)
00556 {
00557   DWORD addr;
00558   int   status = 0;
00559   int   length;
00560   long  content_length = 0L;
00561   char  req_buf [512], *p;
00562   sock_type *sock;
00563
00564   if (!host)
00565   {
00566     TRACE (1, ("get_url: NULL host\n"));
00567     return (-1);
00568   }
00569
00570   addr = resolve (host);
00571   if (!addr)
00572   {
00573     TRACE (1, ("%s\n", dom_strerror(dom_errno)));
00574     return (-1);
00575   }
00576
00577   sock = malloc (sizeof(*sock));
00578   if (!sock)
00579   {
00580     puts ("get_url: No memory");
00581     return (-1);
00582   }
00583
00584   if (!tcp_open(&sock->tcp, 0, addr, port, NULL))
00585   {
00586     printf ("Cannot connect to `%s'\n", host);
00587     free (sock);
00588     return (-1);
00589   }
00590
00591   length = 0;
00592
00593   sock_wait_established (sock, 10, NULL, &status);
00594   sock_tick (sock, &status);   /* in case they sent reset */
00595
00596   p = req_buf;
00597   p += _SNPRINTF (BUF(req_buf),
00598                   "GET %s %s\r\n"
00599                   "Host: %s\r\n"
00600                   "User-Agent: %s\r\n",
00601                   path, HTTPVER, host, USER_AGENT);
00602   if (user_pass)
00603   {
00604     char encoded_auth [256];
00605
00606     if (base64encode (user_pass, encoded_auth, sizeof(encoded_auth)) < 0)
00607        goto sock_err;
00608     p += sprintf (p, "Authorization: Basic %s\r\n", encoded_auth);
00609   }
00610
00611   p += sprintf (p, "Connection: close\r\n\r\n");
00612
00613   TRACE (2, ("Sent: %s\n", req_buf));
00614
00615   sock_write (sock, (BYTE*)req_buf, p - req_buf);
00616   sock_wait_input (sock, 10, NULL, &status);
00617
00618   if (get_header (sock, &content_length))
00619      TRACE (2, ("Content-length %ld, remaining %u\n",
00620             content_length, sock_dataready(sock)));
00621
00622   if (content_length >= 0L)
00623   {
00624     while (sock_dataready(sock) > 0)
00625     {
00626       int i = sock_gets (sock, (BYTE*)(resp_buf+length),
00627                          sizeof(resp_buf)-1-length);
00628       TRACE (1, ("%s", resp_buf+length));
00629       length += i;
00630       if (length > SIZEOF(resp_buf))
00631       {
00632         length = SIZEOF(resp_buf);
00633         break;
00634       }
00635     }
00636     if (content_length != LONG_MAX && length != content_length)
00637        TRACE (1, ("Warning, actual length = %d, content length = %ld\n",
00638               length, content_length));
00639   }
00640
00641 sock_err:
00642
00643   /* since 'sock' is on the stack, kill it from the '_tcp_allsocs' list.
00644    */
00645   sock_abort (sock);
00646
00647   if (status == -1)
00648      TRACE (1, ("get_url(): %s, %s, ", host, sockerr(sock)));
00649   TRACE (2, ("got %d bytes\n", length));
00650   free (sock);
00651   return (length);
00652 }
00653 #endif
Generated on Wed Jan 25 15:42:34 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/DYNIP.H Source File

SRC/DYNIP.H

Go to the documentation of this file.
00001
00003 #ifndef _w32_DYNIP_H
00004 #define _w32_DYNIP_H
00005
00006 #define dynip_init  NAMESPACE (dynip_init)
00007 #define dynip_exec  NAMESPACE (dynip_exec)
00008
00009 void dynip_init (void);
00010 int  dynip_exec (void);
00011
00012 #endif
Generated on Wed Jan 25 15:42:34 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/ECHO.C Source File

SRC/ECHO.C

Go to the documentation of this file.
00001
00007 /*
00008  *  Copyright (c) 1997-2002 Gisle Vanem <giva@bgnett.no>
00009  *
00010  *  Redistribution and use in source and binary forms, with or without
00011  *  modification, are permitted provided that the following conditions
00012  *  are met:
00013  *  1. Redistributions of source code must retain the above copyright
00014  *     notice, this list of conditions and the following disclaimer.
00015  *  2. Redistributions in binary form must reproduce the above copyright
00016  *     notice, this list of conditions and the following disclaimer in the
00017  *     documentation and/or other materials provided with the distribution.
00018  *  3. All advertising materials mentioning features or use of this software
00019  *     must display the following acknowledgement:
00020  *       This product includes software developed by Gisle Vanem
00021  *       Bergen, Norway.
00022  *
00023  *  THIS SOFTWARE IS PROVIDED BY ME (Gisle Vanem) AND CONTRIBUTORS ``AS IS''
00024  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00025  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00026  *  ARE DISCLAIMED.  IN NO EVENT SHALL I OR CONTRIBUTORS BE LIABLE FOR ANY
00027  *  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00028  *  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00029  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00030  *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00031  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00032  *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00033  *
00034  */
00035
00036 #include <stdio.h>
00037 #include <stdlib.h>
00038
00039 #include "wattcp.h"
00040 #include "strings.h"
00041 #include "pcconfig.h"
00042 #include "pctcp.h"
00043 #include "pcdbug.h"
00044 #include "misc.h"
00045 #include "netaddr.h"
00046 #include "echo.h"
00047
00048 #if defined(USE_ECHO_DISC)
00049
00050 static _udp_Socket *udp_echo_sock, *udp_disc_sock;
00051 static _tcp_Socket *tcp_echo_sock, *tcp_disc_sock;
00052
00053 static BOOL  do_echo   = 0;
00054 static WORD  echo_port = 7;
00055 static DWORD echo_host = 0;
00056
00057 static BOOL  do_disc   = 0;
00058 static WORD  disc_port = 9;
00059 static DWORD disc_host = 0;
00060
00061 static void (*prev_hook) (const char*, const char*) = NULL;
00062
00063 static void echo_discard_daemon (void);
00064 static void udp_handler (sock_type *s, void *data, int len, const tcp_PseudoHeader *ph);
00065
00066 /*
00067  * Parse and match "echo.daemon = 0/1", "echo.port = <n>" etc.
00068  */
00069 static void echo_config (const char *name, const char *value)
00070 {
00071   static const struct config_table echo_cfg[] = {
00072             { "DAEMON", ARG_ATOI,    (void*)&do_echo   },
00073             { "HOST",   ARG_RESOLVE, (void*)&echo_host },
00074             { "PORT",   ARG_ATOI,    (void*)&echo_port },
00075             { NULL,     0,           NULL              }
00076           };
00077   static const struct config_table disc_cfg[] = {
00078             { "DAEMON", ARG_ATOI,    (void*)&do_disc   },
00079             { "HOST",   ARG_RESOLVE, (void*)&disc_host },
00080             { "PORT",   ARG_ATOI,    (void*)&disc_port },
00081             { NULL,     0,           NULL              }
00082           };
00083
00084   if (!parse_config_table(&echo_cfg[0], "ECHO.", name, value) &&
00085       !parse_config_table(&disc_cfg[0], "DISCARD.", name, value))
00086   {
00087     if (prev_hook)
00088       (*prev_hook) (name, value);
00089   }
00090 }
00091
00096 static void echo_discard_exit (void)
00097 {
00098   delwattcpd (echo_discard_daemon);
00099   if (udp_echo_sock)
00100      free (udp_echo_sock);
00101   if (tcp_echo_sock)
00102      free (tcp_echo_sock);
00103   if (udp_disc_sock)
00104      free (udp_disc_sock);
00105   if (tcp_disc_sock)
00106      free (tcp_disc_sock);
00107 }
00108
00113 void echo_discard_init (void)
00114 {
00115   prev_hook = usr_init;
00116   usr_init  = echo_config;
00117   udp_echo_sock = udp_disc_sock = NULL;
00118   tcp_echo_sock = tcp_disc_sock = NULL;
00119   RUNDOWN_ADD (echo_discard_exit, 258);
00120 }
00121
00125 void echo_discard_start (void)
00126 {
00127   if (do_echo)
00128   {
00129     udp_echo_sock = malloc (sizeof(*udp_echo_sock));
00130     tcp_echo_sock = malloc (sizeof(*tcp_echo_sock));
00131     if (udp_echo_sock && tcp_echo_sock)
00132     {
00133       udp_listen (udp_echo_sock, echo_port, echo_host, 0,
00134                   (ProtoHandler)udp_handler);
00135       udp_echo_sock->sockmode &= ~SOCK_MODE_UDPCHK;  /* no checksum testing */
00136       tcp_listen (tcp_echo_sock, echo_port, echo_host, 0, NULL, 0);
00137     }
00138     else
00139       do_echo = FALSE;
00140   }
00141
00142   if (do_disc)
00143   {
00144     udp_disc_sock = malloc (sizeof(*udp_disc_sock));
00145     tcp_disc_sock = malloc (sizeof(*tcp_disc_sock));
00146     if (udp_disc_sock && tcp_disc_sock)
00147     {
00148       udp_listen (udp_disc_sock, disc_port, disc_host, 0,
00149                   (ProtoHandler)udp_handler);
00150       udp_disc_sock->sockmode &= ~SOCK_MODE_UDPCHK;
00151       tcp_listen (tcp_disc_sock, disc_port, disc_host, 0, NULL, 0);
00152     }
00153     else
00154       do_disc = FALSE;
00155   }
00156
00157   if (do_echo || do_disc)
00158      addwattcpd (echo_discard_daemon);
00159 }
00160
00165 static void echo_discard_daemon (void)
00166 {
00167   sock_type *s = (sock_type*) tcp_echo_sock;
00168
00169   if (sock_dataready(s))  /* only echo back from echo-socket */
00170   {
00171     BYTE buf[MAX_IP4_DATA-sizeof(tcp_Header)];
00172     int  len = sock_read (s, buf, sizeof(buf));
00173     sock_write (s, buf, len);
00174   }
00175   tcp_disc_sock->rx_datalen = 0;  /* discard recv data */
00176 }
00177
00181 static void udp_handler (sock_type *s, void *data, int len,
00182                          const tcp_PseudoHeader *ph)
00183 {
00184   if (s == (sock_type*)udp_echo_sock)
00185   {
00186     TCP_CONSOLE_MSG (2, ("echo (udp): looping %d bytes from %s\n",
00187                      len, _inet_ntoa(NULL,intel(ph->src))));
00188
00189     if (!sock_enqueue(s, (const BYTE*)data, len))
00190        sock_close (s);
00191   }
00192   else   /* discard packet */
00193   {
00194     TCP_CONSOLE_MSG (2, ("discard (udp): dropping %d bytes from %s\n",
00195                      len, _inet_ntoa(NULL,intel(ph->src))));
00196   }
00197   ARGSUSED (ph);
00198 }
00199
00200 #if defined(TEST_PROG)
00201
00202 int main (int argc, char **argv)
00203 {
00205   return (0);
00206 }
00207 #endif /* TEST_PROG */
00208 #endif /* USE_ECHO_DISC */
00209
Generated on Wed Jan 25 15:42:34 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/ECHO.H Source File

SRC/ECHO.H

Go to the documentation of this file.
00001
00003 #ifndef _w32_ECHO_DISCARD_H
00004 #define _w32_ECHO_DISCARD_H
00005
00006 extern void echo_discard_init (void);
00007 extern void echo_discard_start (void);
00008
00009 #endif
Generated on Wed Jan 25 15:42:34 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/FCNTL.C Source File

SRC/FCNTL.C

Go to the documentation of this file.
00001
00005 /*
00006  *  BSD sockets functionality for Waterloo TCP/IP
00007  *
00008  *  Copyright (c) 1997-2002 Gisle Vanem <giva@bgnett.no>
00009  *
00010  *  Redistribution and use in source and binary forms, with or without
00011  *  modification, are permitted provided that the following conditions
00012  *  are met:
00013  *  1. Redistributions of source code must retain the above copyright
00014  *     notice, this list of conditions and the following disclaimer.
00015  *  2. Redistributions in binary form must reproduce the above copyright
00016  *     notice, this list of conditions and the following disclaimer in the
00017  *     documentation and/or other materials provided with the distribution.
00018  *  3. All advertising materials mentioning features or use of this software
00019  *     must display the following acknowledgement:
00020  *       This product includes software developed by Gisle Vanem
00021  *       Bergen, Norway.
00022  *
00023  *  THIS SOFTWARE IS PROVIDED BY ME (Gisle Vanem) AND CONTRIBUTORS ``AS IS''
00024  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00025  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00026  *  ARE DISCLAIMED.  IN NO EVENT SHALL I OR CONTRIBUTORS BE LIABLE FOR ANY
00027  *  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00028  *  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00029  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00030  *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00031  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00032  *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00033  *
00034  *  Version
00035  *
00036  *  0.5 : 19 Aug 1999 : by Claus Oberste-Brandenburg
00037  *                        <Claus.OBERSTE-BRANDENBURG@jacala.ensmp.fr>
00038  *
00039  *  0.6 : 19 Aug 1999 : Changed function prototype, added fd_duped (GV)
00040  */
00041
00042 #include "socket.h"
00043
00044 #if defined(USE_BSD_API)
00045
00046 #ifndef O_NONBLOCK
00047 #define O_NONBLOCK 0x2000
00048 #endif
00049
00050 #if defined(USE_DEBUG)
00051 /*
00052  * Return string for fcntlsocket() command
00053  */
00054 static const struct search_list commands[] = {
00055            { F_DUPFD,  "F_DUPFD"  },
00056            { F_GETFL,  "F_GETFL"  },
00057            { F_SETFL,  "F_SETFL"  },
00058            { F_GETFD,  "F_GETFD"  },
00059            { F_SETFD,  "F_SETFD"  },
00060            { F_GETLK,  "F_GETLK"  },
00061            { F_SETLK,  "F_SETLK"  },
00062            { F_SETLKW, "F_SETLKW" },
00063            { F_GETOWN, "F_GETOWN" },
00064            { F_SETOWN, "F_SETOWN" }
00065          };
00066 #endif  /* USE_DEBUG */
00067
00068
00069 int MS_CDECL fcntlsocket (int s, int cmd, ...)
00070 {
00071   Socket  *socket = _socklist_find (s);
00072   unsigned arg;
00073   int      rc = 0;
00074   va_list  va;
00075
00076   va_start (va, cmd);
00077   arg = va_arg (va, unsigned);
00078
00079   SOCK_PROLOGUE (socket, "\nfcntlsocket:%d, ", s);
00080
00081   SOCK_DEBUGF ((", %s: ", list_lookup (cmd, commands, DIM(commands))));
00082
00083   /* fcntl is always file-ioctrl
00084    */
00085   switch (cmd)
00086   {
00087     case F_DUPFD:
00088          socket->fd_duped++;
00089          SOCK_DEBUGF (("dup %d", socket->fd_duped));
00090          return (0);
00091
00092     case F_GETFL:
00095          if (socket->so_state & SS_NBIO)
00096          {
00097            SOCK_DEBUGF (("non-blocking"));
00098            return (O_NONBLOCK);
00099          }
00100          SOCK_DEBUGF (("blocking"));
00101          return (0);
00102
00103     case F_SETFL:
00104          if (arg & O_NONBLOCK)  /* O_APPEND will not be served */
00105          {
00106            SOCK_DEBUGF (("non-blocking"));
00107            socket->so_state |= SS_NBIO;
00108            socket->timeout = 0;
00109            if (socket->tcp_sock)
00110               socket->tcp_sock->timeout = 0;
00111          }
00112          else
00113          {
00114            SOCK_DEBUGF (("blocking"));
00115            socket->so_state &= ~SS_NBIO;
00116            socket->timeout = sock_delay;
00117          }
00118          return (0);
00119
00120     case F_GETFD:
00121          return (0); /* socket remains open across exec() */
00122
00123     case F_SETFD:
00124     case F_GETLK:
00125     case F_SETLK:
00126     case F_SETLKW:
00127     case F_GETOWN:
00128     case F_SETOWN:
00129          SOCK_DEBUGF (("not supported"));
00130          SOCK_ERRNO (ESOCKTNOSUPPORT);
00131          rc = -1;
00132          break;
00133
00134     default:
00135          SOCK_ENTER_SCOPE();
00136          if (ioctlsocket(s, cmd, (char*)arg) < 0)
00137          {
00138            SOCK_DEBUGF ((", unknown cmd %d", cmd));
00139            SOCK_ERRNO (ESOCKTNOSUPPORT);
00140            rc = -1;
00141          }
00142          SOCK_LEAVE_SCOPE();
00143   }
00144   return (rc);
00145 }
00146 #endif  /* USE_BSD_API */
00147
Generated on Wed Jan 25 15:42:34 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/FORTIFY.C Source File

SRC/FORTIFY.C

Go to the documentation of this file.
00001
00005 /*
00006  * This software is not public domain. All material in
00007  * this archive is (C) Copyright 1995 Simon P. Bullen. The
00008  * software is freely distributable, with the condition that
00009  * no more than a nominal fee is charged for media.
00010  * Everything in this distribution must be kept together, in
00011  * original, unmodified form.
00012  *
00013  * The software may be modified for your own personal use,
00014  * but modified files may not be distributed.
00015  *
00016  * The material is provided "as is" without warranty of
00017  * any kind. The author accepts no responsibility for damage
00018  * caused by this software.
00019  *
00020  * This software may not be used in any way by Microsoft
00021  * Corporation or its subsidiaries, or current employees of
00022  * Microsoft Corporation or its subsidiaries.
00023  *
00024  * This software may not be used for the construction,
00025  * development, production, or testing of weapon systems of
00026  * any kind.
00027  *
00028  * This software may not be used for the construction,
00029  * development, production, or use of plants/installations
00030  * which include the processing of radioactive/fissionable
00031  * material.
00032  */
00033
00034 /*
00035  * If you use this software at all, I'd love to hear from
00036  * you.  All questions, criticisms, suggestions, praise and
00037  * postcards are most welcome.
00038  *
00039  *            email:    sbullen@cybergraphic.com.au
00040  *
00041  *            snail:    Simon P. Bullen
00042  *                      PO BOX 12138
00043  *                      A'Beckett St.
00044  *                      Melbourne 3000
00045  *                      Australia
00046  */
00047
00048 #include <stdio.h>
00049 #include <stdlib.h>
00050 #include <stdarg.h>
00051 #include <string.h>
00052 #include <math.h>
00053 #include <ctype.h>
00054 #include <time.h>
00055
00056 #if defined(_WIN32) || defined(WIN32)
00057 #define WIN32_LEAN_AND_MEAN
00058 #include <windows.h>
00059 #include <windowsx.h>
00060 #endif
00061
00062 /* Prototypes and such */
00063 #define __FORTIFY_C__
00064
00065 #include "wattcp.h"
00066 #include "misc.h"
00067 #include "strings.h"
00068 #include "nochkstk.h"
00069
00070 #include "fortify.h"
00071 /* #include "chksum.h" */
00072
00073 #if defined(USE_FORTIFY) && !defined(USE_CRTDBG)
00074
00075 /*
00076  * struct Header - this structure is used
00077  * internally by Fortify to manage it's
00078  * own private lists of memory.
00079  */
00080 struct Header {
00081        WORD           Checksum;     /* For the integrity of our goodies  */
00082        const char    *File;         /* The sourcefile of the allocator   */
00083        DWORD          Line;         /* The sourceline of the allocator   */
00084 #ifdef FORTIFY_TRACK_DEALLOCATED_MEMORY
00085        const char    *FreedFile;    /* The sourcefile of the deallocator */
00086        DWORD          FreedLine;    /* The sourceline of the deallocator */
00087        BYTE           Deallocator;  /* The deallocator used              */
00088 #endif
00089        size_t         Size;         /* The size of the malloc'd block    */
00090        struct Header *Prev;         /* Previous link                     */
00091        struct Header *Next;         /* Next link                         */
00092        char          *Label;        /* User's Label (may be null)        */
00093        BYTE           Scope;        /* Scope level of the caller         */
00094        BYTE           Allocator;    /* malloc/realloc/new/etc            */
00095      };
00096
00097 /*
00098  * Round x up to the nearest multiple of n.
00099  */
00100 #define ROUND_UP(x,n)        ((((x) + (n)-1)/(n))*(n))
00101
00102 #define FORTIFY_HEADER_SIZE  ROUND_UP(sizeof(struct Header), sizeof(WORD))
00103
00104 /*
00105  * FORTIFY_ALIGNED_BEFORE_SIZE is FORTIFY_BEFORE_SIZE rounded up to the
00106  * next multiple of FORTIFY_ALIGNMENT. This is so that we can guarantee
00107  * the alignment of user memory for such systems where this is important
00108  * (eg storing doubles on a SPARC)
00109  */
00110 #define FORTIFY_ALIGNED_BEFORE_SIZE ( \
00111         ROUND_UP (FORTIFY_HEADER_SIZE+FORTIFY_BEFORE_SIZE, FORTIFY_ALIGNMENT) \
00112         - FORTIFY_HEADER_SIZE)
00113
00114 /*
00115  * FORTIFY_OVERHEAD is the total overhead added by Fortify to each
00116  * memory block.
00117  */
00118 #define FORTIFY_OVERHEAD (FORTIFY_HEADER_SIZE         + \
00119                           FORTIFY_ALIGNED_BEFORE_SIZE + \
00120                           FORTIFY_AFTER_SIZE)
00121
00122 #if (DOSX)
00123   #define VALIDATE(p,len,neg_action)  \
00124           ((int) (valid_addr ((DWORD)(p),len) ? 1 : (int)(neg_action)))
00125 #else
00126   #define VALIDATE(p,len,neg_action)  (1)
00127 #endif
00128
00129 /*
00130  * Static Function Prototypes
00131  */
00132 static int  st_CheckBlock         (struct Header *h, const char *file, DWORD line);
00133 static int  st_CheckFortification (BYTE *ptr, BYTE value, size_t size);
00134 static void st_SetFortification   (BYTE *ptr, BYTE value, size_t size);
00135 static void st_OutputFortification(BYTE *ptr, BYTE value, size_t size);
00136 static void st_HexDump            (BYTE *ptr, size_t offset, size_t size, int title);
00137 static void st_MakeHeaderValid    (struct Header *h);
00138 static int  st_IsHeaderValid      (const struct Header *h);
00139 static WORD st_ChecksumHeader     (const struct Header *h);
00140 static int  st_IsOnAllocatedList  (const struct Header *h);
00141 static int  st_OutputHeader       (struct Header *h);
00142 static void st_OutputMemory       (struct Header *h);
00143 static void st_OutputLastVerifiedPoint(void);
00144 static void st_DefaultOutput      (const char *String);
00145 static const char *st_MemoryBlockString(struct Header *h);
00146 static void st_OutputDeleteTrace (void);
00147
00148 #if defined(FORTIFY_TRACK_DEALLOCATED_MEMORY)
00149 #if defined(FORTIFY_WARN_WHEN_DISCARDING_DEALLOCATED_MEMORY) && \
00150     defined(FORTIFY_VERBOSE_WARN_WHEN_DISCARDING_DEALLOCATED_MEMORY)
00151     static const char *st_DeallocatedMemoryBlockString(struct Header *h);
00152 #endif
00153     static int  st_IsOnDeallocatedList(const struct Header *h);
00154     static int  st_PurgeDeallocatedBlocks(DWORD Bytes, const char *file, DWORD line);
00155     static int  st_PurgeDeallocatedScope(BYTE Scope, const char *file, DWORD line);
00156     static int  st_CheckDeallocatedBlock(struct Header *h, const char *file, DWORD line);
00157     static void st_FreeDeallocatedBlock(struct Header *h, const char *file, DWORD line);
00158 #endif
00159
00160
00161 /*
00162  * Static variables
00163  */
00164 static char                  st_Buffer[4096]     = { 0 }; /* don't use BSS */
00165 static struct Header        *st_AllocatedHead    = 0;
00166 static int                   st_AllocateFailRate = 0;
00167 static Fortify_OutputFuncPtr st_Output           = st_DefaultOutput;
00168 static const char           *st_LastVerifiedFile = "unknown";
00169 static DWORD                 st_LastVerifiedLine = 0;
00170 static BYTE                  st_Scope            = 0;
00171 static BYTE                  st_Disabled         = 0;
00172
00173 #if defined(__HIGHC__) && 0 /* !! not yet */
00174 static char st_LockDataStart = 0;
00175 #endif
00176
00177 #ifdef __cplusplus
00178   using namespace std;
00179
00180   int    gbl_FortifyMagic = 0;
00181   static const char *st_DeleteFile[FORTIFY_DELETE_STACK_SIZE];
00182   static DWORD       st_DeleteLine[FORTIFY_DELETE_STACK_SIZE];
00183   static DWORD       st_DeleteStackTop;
00184 #endif
00185
00186 #ifndef ST_OUTPUT
00187 #define ST_OUTPUT(s) do { if (st_Output) (*st_Output)(s); } while (0)
00188 #endif
00189
00190 static void message (BOOL warn, const char *fmt, ...)
00191 {
00192   va_list args;
00193   char   *pos = st_Buffer;
00194
00195   if (!st_Output)
00196      return;
00197
00198   va_start (args, fmt);
00199   if (warn)
00200   {
00201     strcpy (pos, "\nFortify: ");
00202     pos += 10;
00203   }
00204
00205 #if defined(VSNPRINTF)
00206   VSNPRINTF (pos, sizeof(st_Buffer) - (pos-st_Buffer)-1, fmt, args);
00207 #else
00208   vsprintf (pos, fmt, args);
00209 #endif
00210   (*st_Output) (st_Buffer);
00211 }
00212
00213
00214 /* statistics */
00215 static DWORD  st_MaxBlocks        = 0;
00216 static DWORD  st_MaxAllocation    = 0;
00217 static DWORD  st_CurBlocks        = 0;
00218 static DWORD  st_CurAllocation    = 0;
00219 static DWORD  st_Allocations      = 0;
00220 static DWORD  st_Frees            = 0;
00221 static DWORD  st_TotalAllocation  = 0;
00222 static DWORD  st_AllocationLimit  = 0xffffffff;
00223
00224 #ifdef FORTIFY_TRACK_DEALLOCATED_MEMORY
00225   static struct Header *st_DeallocatedHead  = 0;
00226   static struct Header *st_DeallocatedTail  = 0;
00227   static DWORD          st_TotalDeallocated = 0;
00228 #endif
00229
00230
00231 /* allocators */
00232 static const char *st_AllocatorName[] = {
00233                   "malloc()",
00234                   "calloc()",
00235                   "realloc()",
00236                   "strdup()",
00237                   "new",
00238                   "new[]",
00239                   "GlobalAllocPtr()"
00240                 };
00241
00242 /* deallocators */
00243 static const char *st_DeallocatorName[] = {
00244                   "nobody",
00245                   "free()",
00246                   "realloc()",
00247                   "delete",
00248                   "delete[]",
00249                   "GlobalFreePtr()"
00250                 };
00251
00252 static const BYTE st_ValidDeallocator[] = {
00253     (1 << Fortify_Deallocator_free) | (1 << Fortify_Deallocator_realloc),
00254     (1 << Fortify_Deallocator_free) | (1 << Fortify_Deallocator_realloc),
00255     (1 << Fortify_Deallocator_free) | (1 << Fortify_Deallocator_realloc),
00256     (1 << Fortify_Deallocator_free) | (1 << Fortify_Deallocator_realloc),
00257 #if defined(FORTIFY_PROVIDE_ARRAY_NEW) && defined(FORTIFY_PROVIDE_ARRAY_DELETE)
00258     (1 << Fortify_Deallocator_delete),
00259     (1 << Fortify_Deallocator_array_delete)
00260 #else
00261     (1 << Fortify_Deallocator_delete) | (1 << Fortify_Deallocator_array_delete),
00262     (1 << Fortify_Deallocator_delete) | (1 << Fortify_Deallocator_array_delete)
00263 #endif
00264 };
00265
00266 #if defined(__HIGHC__)
00267
00268 #if 0  /* !! not yet */
00269 #include <pharlap.h>
00270 #include <hw386.h>
00271
00272 static char st_LockDataEnd = 0;
00273
00274 /*
00275  *  Change page-attributes for local data.
00276  *  Set to present or non-present pages.
00277  */
00278 static Fortify_LockLocalData (int lock)
00279 {
00280   UINT  lockSize  = (ULONG)&st_LockDataEnd - (ULONG)&st_LockDataStart;
00281   ULONG num_pages = (lockSize + 4095) / 4096;
00282   ULONG page      = ((ULONG)&st_LockDataStart + 4095) / 4096;
00283
00284   for ( ; page < page + num_pages; page++)
00285   {
00286     ULONG pte, ptInfo;
00287     if (_dx_rd_ptinfl (page << 12, &pte, &ptInfo))
00288        break;
00289     if (lock)
00290          pte &= ~PE_PRESENT;
00291     else pte |=  PE_PRESENT;
00292     if (_dx_wr_ptinfl (page << 12, pte, ptInfo))
00293        break;
00294   }
00295 }
00296 #endif
00297
00298 #pragma data (common,"?_MWHEAP");
00299
00300 BYTE Check_heap_integrity_flag; /* must be public */
00301 BYTE Heap_init_byte;
00302 BYTE Init_allocated_storage;
00303
00304 #pragma data;
00305
00306 static void heap_integrity_check (BOOL on)
00307 {
00308   if (on)
00309   {
00310     Check_heap_integrity_flag = Init_allocated_storage = 1;
00311     Heap_init_byte = 0xFE;
00312   }
00313   else
00314     Check_heap_integrity_flag = Init_allocated_storage = 0;
00315 }
00316 #endif
00317
00318
00319
00320 /*
00321  * Fortify_Allocate() - allocate a block of fortified memory
00322  */
00323 void *FORTIFY_STORAGE
00324 Fortify_Allocate (size_t size, unsigned char allocator, unsigned long flags,
00325                   const char *file, DWORD line)
00326 {
00327   struct Header *h;
00328   int    another_try;
00329   BYTE  *ptr = NULL;
00330
00331   /* If Fortify has been disabled, then it's easy
00332    */
00333   if (st_Disabled)
00334   {
00335 #ifdef FORTIFY_FAIL_ON_ZERO_MALLOC
00336     if (size == 0 &&
00337         (allocator == Fortify_Allocator_new ||
00338          allocator == Fortify_Allocator_array_new))
00339     {
00340       /* A new of zero bytes must succeed, but a malloc of
00341        * zero bytes probably won't
00342        */
00343       return malloc (1);
00344     }
00345 #endif
00346 #ifdef WIN32
00347     if (allocator == Fortify_Allocator_GlobalAlloc)
00348        return GlobalAlloc (flags, size);
00349 #endif
00350     return malloc (size);
00351   }
00352
00353   if (allocator != Fortify_Allocator_GlobalAlloc)
00354   {
00355 #ifdef FORTIFY_CHECK_ALL_MEMORY_ON_ALLOCATE
00356     #ifdef __HIGHC__
00357       heap_integrity_check (TRUE);
00358     #endif
00359     Fortify_CheckAllMemory (file, line);
00360 #endif
00361   }
00362
00363   if (st_AllocateFailRate > 0)
00364   {
00365     if ((rand() % 100) < st_AllocateFailRate)
00366     {
00367 #ifdef FORTIFY_WARN_ON_FALSE_FAIL
00368       message (1, "A \"%s\" of %lu bytes failed at %s.%lu\n",
00369                st_AllocatorName[allocator], (DWORD)size, file, line);
00370 #endif
00371       return (NULL);
00372     }
00373   }
00374
00375   /* Check to see if this allocation will
00376    * push us over the artificial limit
00377    */
00378   if (st_CurAllocation + size > st_AllocationLimit)
00379   {
00380 #ifdef FORTIFY_WARN_ON_FALSE_FAIL
00381     message (1, "A \"%s\" of %lu bytes \"false failed\" at %s.%lu\n",
00382              st_AllocatorName[allocator], (DWORD)size, file, line);
00383 #endif
00384     return (0);
00385   }
00386
00387 #ifdef FORTIFY_WARN_ON_ZERO_MALLOC
00388   if (size == 0 && (allocator == Fortify_Allocator_malloc ||
00389                     allocator == Fortify_Allocator_calloc ||
00390                     allocator == Fortify_Allocator_realloc))
00391     message (1, "A \"%s\" of 0 bytes attempted at %s.%lu\n",
00392              st_AllocatorName[allocator], file, line);
00393 #endif
00394
00395 #ifdef FORTIFY_FAIL_ON_ZERO_MALLOC
00396   if (size == 0 && (allocator == Fortify_Allocator_malloc ||
00397                     allocator == Fortify_Allocator_calloc ||
00398                     allocator == Fortify_Allocator_realloc))
00399   {
00400 #ifdef FORTIFY_WARN_ON_ALLOCATE_FAIL
00401     message (1, "A \"%s\" of %lu bytes failed at %s.%lu\n",
00402              st_AllocatorName[allocator], (DWORD)size, file, line);
00403 #endif
00404     return (NULL);
00405   }
00406 #endif
00407
00408 #ifdef FORTIFY_WARN_ON_SIZE_T_OVERFLOW
00409   /*
00410    * Ensure the size of the memory block plus the overhead isn't
00411    * bigger than size_t (that'd be a drag)
00412    */
00413   {
00414     size_t private_size = FORTIFY_HEADER_SIZE +
00415                           FORTIFY_ALIGNED_BEFORE_SIZE + size +
00416                           FORTIFY_AFTER_SIZE;
00417
00418     if (private_size < size)
00419     {
00420       message (1, "A \"%s\" of %lu bytes has overflowed size_t at %s.%lu\n",
00421                st_AllocatorName[allocator], (DWORD)size, file, line);
00422       return (0);
00423     }
00424 #if (DOSX) && defined(__WATCOMC__) && 0
00425     if (private_size >= 65536UL)
00426     {
00427       message (1, "A \"%s\" of %lu bytes has exceeded 64kB limit by %d bytes, "
00428                "at %s.%lu\n", st_AllocatorName[allocator], (DWORD)size,
00429                private_size - size, file, line);
00430       return (NULL);
00431     }
00432 #endif
00433   }
00434 #endif
00435
00436   another_try = 1;
00437   do
00438   {
00439     /* malloc the memory, including the space
00440      * for the header and fortification buffers
00441      */
00442     ptr = (BYTE*) malloc (FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE +
00443                           size + FORTIFY_AFTER_SIZE);
00444
00445 #ifdef FORTIFY_TRACK_DEALLOCATED_MEMORY
00446     /* If we're tracking deallocated memory, then we can free some of
00447      * it, rather than let this malloc fail
00448      */
00449     if (!ptr)
00450        another_try = st_PurgeDeallocatedBlocks (size, file, line);
00451
00452 #endif /* FORTIFY_TRACK_DEALLOCATED_MEMORY */
00453   }
00454   while (!ptr && another_try);
00455
00456   if (!ptr)
00457   {
00458 #ifdef FORTIFY_WARN_ON_ALLOCATE_FAIL
00459     message (1, "A \"%s\" of %lu bytes failed at %s.%lu\n",
00460              st_AllocatorName[allocator], (DWORD)size, file, line);
00461 #endif
00462     return (NULL);
00463   }
00464
00465   /* Begin Critical Region
00466    */
00467   FORTIFY_LOCK();
00468
00469   /* Make the head's prev pointer point to us
00470    * ('cos we're about to become the head)
00471    */
00472   if (st_AllocatedHead)
00473   {
00474     st_CheckBlock (st_AllocatedHead, file, line);
00475     /* what should we do if this fails? (apart from panic) */
00476
00477     st_AllocatedHead->Prev = (struct Header*) ptr;
00478     st_MakeHeaderValid (st_AllocatedHead);
00479   }
00480
00481   /* Initialize and validate the header
00482    */
00483   h = (struct Header *)ptr;
00484   h->Size      = size;
00485   h->File      = file;
00486   h->Line      = line;
00487   h->Next      = st_AllocatedHead;
00488   h->Prev      = 0;
00489   h->Scope     = st_Scope;
00490   h->Allocator = allocator;
00491   h->Label     = 0;
00492 #ifdef FORTIFY_TRACK_DEALLOCATED_MEMORY
00493   h->FreedFile = 0;
00494   h->FreedLine = 0;
00495   h->Deallocator = Fortify_Deallocator_nobody;
00496 #endif
00497   st_MakeHeaderValid (h);
00498   st_AllocatedHead = h;
00499
00500   /* Initialize the fortifications
00501    */
00502   st_SetFortification (ptr + FORTIFY_HEADER_SIZE,
00503                        FORTIFY_BEFORE_VALUE, FORTIFY_ALIGNED_BEFORE_SIZE);
00504   st_SetFortification (ptr + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE +
00505                        size, FORTIFY_AFTER_VALUE, FORTIFY_AFTER_SIZE);
00506
00507 #ifdef FORTIFY_FILL_ON_ALLOCATE
00508   /* Fill the actual user memory
00509    */
00510   st_SetFortification (ptr + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE,
00511                        FORTIFY_FILL_ON_ALLOCATE_VALUE, size);
00512 #endif
00513
00514   /* End Critical Region
00515    */
00516   FORTIFY_UNLOCK();
00517
00518   /* update the statistics
00519    */
00520   st_TotalAllocation += size;
00521   st_Allocations++;
00522   st_CurBlocks++;
00523   st_CurAllocation += size;
00524   if (st_CurBlocks > st_MaxBlocks)
00525       st_MaxBlocks = st_CurBlocks;
00526   if (st_CurAllocation > st_MaxAllocation)
00527       st_MaxAllocation = st_CurAllocation;
00528
00529   /* We return the address of the user's memory, not the start of the block,
00530    * which points to our magic cookies
00531    */
00532   ARGSUSED (flags);
00533   return (ptr + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE);
00534 }
00535
00536
00537 /*
00538  * Fortify_Deallocate() - Free a block of memory allocated with Fortify_Allocate()
00539  */
00540 void FORTIFY_STORAGE
00541 Fortify_Deallocate (void *uptr, BYTE deallocator, const char *file, DWORD line)
00542 {
00543   BYTE *ptr = (BYTE*) uptr - FORTIFY_HEADER_SIZE -
00544               FORTIFY_ALIGNED_BEFORE_SIZE;
00545   struct Header *h = (struct Header*) ptr;
00546
00547 #ifdef FORTIFY_CHECK_ALL_MEMORY_ON_DEALLOCATE
00548   #ifdef __HIGHC__
00549     heap_integrity_check (TRUE);
00550   #endif
00551   Fortify_CheckAllMemory(file, line);
00552 #endif
00553
00554   /* If Fortify has been disabled, then it's easy (well, almost)
00555    */
00556   if (st_Disabled)
00557   {
00558     /* there is a possibility that this memory block was allocated
00559      * when Fortify was enabled, so we must check the Allocated
00560      * list before we free it.
00561      */
00562     if (!st_IsOnAllocatedList(h))
00563     {
00564       free (uptr);
00565       return;
00566     }
00567
00568     /* the block was allocated by Fortify, so we
00569      * gotta free it differently.
00570      */
00571
00572     /* Begin critical region
00573      */
00574     FORTIFY_LOCK();
00575
00576     /* Remove the block from the list
00577      */
00578     if (h->Prev)
00579          h->Prev->Next = h->Next;
00580     else st_AllocatedHead = h->Next;
00581
00582     if (h->Next)
00583         h->Next->Prev = h->Prev;
00584
00585     /* End Critical Region
00586      */
00587     FORTIFY_UNLOCK();
00588
00589     /* actually free the memory
00590      */
00591     free (ptr);
00592     return;
00593   }
00594
00595 #ifdef FORTIFY_PARANOID_DEALLOCATE
00596   if (!st_IsOnAllocatedList(h))
00597   {
00598 #ifdef FORTIFY_TRACK_DEALLOCATED_MEMORY
00599     if (st_IsOnDeallocatedList(h))
00600     {
00601       message (1, "\"%s\" twice of %s detected at %s.%lu\n",
00602                st_DeallocatorName[deallocator],
00603                st_MemoryBlockString(h), file, line);
00604
00605       sprintf (st_Buffer, "         Memory block was deallocated by \"%s\" at %s.%lu\n",
00606                st_DeallocatorName[h->Deallocator], h->FreedFile, h->FreedLine);
00607       ST_OUTPUT (st_Buffer);
00608       st_OutputDeleteTrace();
00609       return;
00610     }
00611 #endif
00612
00613     message (1, "Possible \"%s\" twice of (%08lX) was detected at %s.%lu\n",
00614              st_DeallocatorName[deallocator], (DWORD)uptr, file, line);
00615
00616     st_OutputDeleteTrace();
00617     return;
00618   }
00619 #endif /* FORTIFY_PARANOID_DEALLOCATE */
00620
00621   /*
00622    * Make sure the block is okay before we free it.
00623    * If it's not okay, don't free it - it might not
00624    * be a real memory block. Or worse still, someone
00625    * might still be writing to it
00626    */
00627   if (!st_CheckBlock(h, file, line))
00628   {
00629     st_OutputDeleteTrace();
00630     return;
00631   }
00632
00633 #ifdef FORTIFY_TRACK_DEALLOCATED_MEMORY
00634   /*
00635    * Make sure the block hasn't been freed already
00636    * (we can get to here if FORTIFY_PARANOID_DELETE
00637    * is off, but FORTIFY_TRACK_DEALLOCATED_MEMORY
00638    * is on).
00639    */
00640   if (h->Deallocator != Fortify_Deallocator_nobody)
00641   {
00642     message (1, "\"%s\" twice of %s detected at %s.%lu\n",
00643              st_DeallocatorName[deallocator], st_MemoryBlockString(h),
00644              file, line);
00645
00646     sprintf (st_Buffer, "         Memory block was deallocated by \"%s\" at %s.%lu\n",
00647              st_DeallocatorName[h->Deallocator], h->FreedFile, h->FreedLine);
00648     ST_OUTPUT (st_Buffer);
00649     st_OutputDeleteTrace();
00650     return;
00651   }
00652 #endif
00653
00654   /* Make sure the block is being freed with a valid
00655    * deallocator. If not, complain. (but free it anyway)
00656    */
00657   if ((st_ValidDeallocator[h->Allocator] & (1 << deallocator)) == 0)
00658   {
00659     message (1, "Incorrect deallocator \"%s\" detected at %s.%lu\n",
00660              st_DeallocatorName[deallocator], file, line);
00661     sprintf (st_Buffer,   "         %s was allocated with \"%s\"\n",
00662              st_MemoryBlockString(h), st_AllocatorName[h->Allocator]);
00663     ST_OUTPUT (st_Buffer);
00664     st_OutputDeleteTrace();
00665   }
00666
00667   /* Begin critical region
00668    */
00669   FORTIFY_LOCK();
00670
00671   /* Remove the block from the list
00672    */
00673   if (h->Prev)
00674   {
00675     if (!st_CheckBlock(h->Prev, file, line))
00676     {
00677       FORTIFY_UNLOCK();
00678       st_OutputDeleteTrace();
00679       return;
00680     }
00681     h->Prev->Next = h->Next;
00682     st_MakeHeaderValid (h->Prev);
00683   }
00684   else
00685     st_AllocatedHead = h->Next;
00686
00687   if (h->Next)
00688   {
00689     if (!st_CheckBlock(h->Next, file, line))
00690     {
00691       FORTIFY_UNLOCK();
00692       st_OutputDeleteTrace();
00693       return;
00694     }
00695     h->Next->Prev = h->Prev;
00696     st_MakeHeaderValid (h->Next);
00697   }
00698
00699   /* End Critical Region
00700    */
00701   FORTIFY_UNLOCK();
00702
00703   /* update the statistics
00704    */
00705   st_Frees++;
00706   st_CurBlocks--;
00707   st_CurAllocation -= h->Size;
00708
00709 #ifdef FORTIFY_TRACK_DEALLOCATED_MEMORY
00710   if (st_Scope > 0)
00711   {
00712     /*
00713      * Don't _actually_ free the memory block, just yet.
00714      * Place it onto the deallocated list, instead, so
00715      * we can check later to see if it's been written to.
00716      */
00717   #ifdef FORTIFY_FILL_ON_DEALLOCATE
00718     /*
00719      * Nuke out all user memory that is about to be freed
00720      */
00721     st_SetFortification (ptr + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE,
00722                          FORTIFY_FILL_ON_DEALLOCATE_VALUE, h->Size);
00723   #endif
00724
00725     /* Begin critical region
00726      */
00727     FORTIFY_LOCK();
00728
00729     /* Place the block on the deallocated list
00730      */
00731     if (st_DeallocatedHead)
00732     {
00733       st_DeallocatedHead->Prev = (struct Header*) ptr;
00734       st_MakeHeaderValid (st_DeallocatedHead);
00735     }
00736
00737     h = (struct Header *)ptr;
00738     h->FreedFile   = file;
00739     h->FreedLine   = line;
00740     h->Deallocator = deallocator;
00741     h->Next        = st_DeallocatedHead;
00742     h->Prev        = 0;
00743     st_MakeHeaderValid (h);
00744     st_DeallocatedHead = h;
00745
00746     if (!st_DeallocatedTail)
00747        st_DeallocatedTail = h;
00748
00749     st_TotalDeallocated += h->Size;
00750
00751   #ifdef FORTIFY_DEALLOCATED_MEMORY_LIMIT
00752     /*
00753      * If we've got too much on the deallocated list; free some
00754      */
00755     if (st_TotalDeallocated > FORTIFY_DEALLOCATED_MEMORY_LIMIT)
00756        st_PurgeDeallocatedBlocks (st_TotalDeallocated -
00757                                   FORTIFY_DEALLOCATED_MEMORY_LIMIT, file, line);
00758   #endif
00759
00760     /* End critical region
00761      */
00762     FORTIFY_UNLOCK();
00763   }
00764   else
00765 #endif /* FORTIFY_TRACK_DEALLOCATED_MEMORY */
00766   {
00767     /* Free the User Label
00768      */
00769     if (h->Label)
00770        free(h->Label);
00771
00772 #ifdef FORTIFY_FILL_ON_DEALLOCATE
00773     /* Nuke out all memory that is about to be freed, including the header
00774      */
00775     st_SetFortification (ptr, FORTIFY_FILL_ON_DEALLOCATE_VALUE,
00776                          FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE +
00777                          h->Size + FORTIFY_AFTER_SIZE);
00778 #endif
00779     /* And do the actual free
00780      */
00781     free(ptr);
00782   }
00783 }
00784
00785
00786 /*
00787  * Fortify_LabelPointer() - Labels the memory block
00788  * with a string provided by the user. This function
00789  * takes a copy of the passed in string.
00790  * The pointer MUST be one returned by a Fortify
00791  * allocation function.
00792  */
00793 /*@-redef@*/
00794 void
00795 Fortify_LabelPointer (void *uptr, const char *label, const char *file, DWORD line)
00796 {
00797   if (!st_Disabled)
00798   {
00799     BYTE *ptr = (BYTE*) uptr - FORTIFY_HEADER_SIZE -
00800                 FORTIFY_ALIGNED_BEFORE_SIZE;
00801     struct Header *h = (struct Header*) ptr;
00802
00803     /* make sure the pointer is okay
00804      */
00805     Fortify_CheckPointer (uptr, file, line);
00806
00807     /* free the previous label
00808      */
00809     if (h->Label)
00810        free (h->Label);
00811
00812     h->Label = label ? strdup (label) : NULL;
00813
00814     /* update the checksum
00815      */
00816     st_MakeHeaderValid (h);
00817   }
00818 }
00819
00820 /*
00821  * Fortify_CheckPointer() - Returns true if the uptr
00822  * points to a valid piece of Fortify_Allocated()'d
00823  * memory. The memory must be on the allocated list,
00824  * and it's fortifications must be intact.
00825  * Always returns TRUE if Fortify is disabled.
00826  */
00827 int FORTIFY_STORAGE
00828 Fortify_CheckPointer (void *uptr, const char *file, DWORD line)
00829 {
00830   BYTE *ptr = (BYTE*) uptr - FORTIFY_HEADER_SIZE -
00831               FORTIFY_ALIGNED_BEFORE_SIZE;
00832   struct Header *h = (struct Header*) ptr;
00833   int    r;
00834
00835   if (st_Disabled)
00836      return (1);
00837
00838   FORTIFY_LOCK();
00839
00840   if (!st_IsOnAllocatedList(h))
00841   {
00842     message (1, "Invalid pointer (%08lX) detected at %s.%lu\n",
00843              (DWORD) uptr, file, line);
00844     FORTIFY_UNLOCK();
00845     return (0);
00846   }
00847
00848 #ifdef FORTIFY_TRACK_DEALLOCATED_MEMORY
00849   if (st_IsOnDeallocatedList(h))
00850   {
00851     message (1, "Deallocated pointer (%08lX) detected at %s.%lu\n",
00852              (DWORD) uptr, file, line);
00853
00854     sprintf (st_Buffer, "         Memory block was deallocated by \"%s\" at %s.%lu\n",
00855              st_DeallocatorName[h->Deallocator], h->FreedFile, h->FreedLine);
00856     ST_OUTPUT (st_Buffer);
00857     FORTIFY_UNLOCK();
00858     return (0);
00859   }
00860 #endif
00861
00862   r = st_CheckBlock (h, file, line);
00863   FORTIFY_UNLOCK();
00864   return (r);
00865 }
00866
00867 /*
00868  * Fortify_SetOutputFunc(Fortify_OutputFuncPtr Output) -
00869  * Sets the function used to output all error and
00870  * diagnostic messages. The output function  takes
00871  * a single const BYTE * argument, and must be
00872  * able to handle newlines. This function returns the
00873  * old output function.
00874  */
00875 Fortify_OutputFuncPtr FORTIFY_STORAGE
00876 Fortify_SetOutputFunc (Fortify_OutputFuncPtr Output)
00877 {
00878   Fortify_OutputFuncPtr Old = st_Output;
00879
00880   st_Output = Output;
00881   return (Old);
00882 }
00883
00884 /*
00885  * Fortify_SetAllocateFailRate(int Percent) -
00886  * Fortify_Allocate() will "fail" this Percent of
00887  * the time, even if the memory is available.
00888  * Useful to "stress-test" an application.
00889  * Returns the old value.
00890  * The fail rate defaults to 0 (a good default I think).
00891  */
00892 int FORTIFY_STORAGE Fortify_SetAllocateFailRate (int Percent)
00893 {
00894   int Old = st_AllocateFailRate;
00895
00896   Percent = max (0, Percent);
00897   Percent = min (100, Percent);
00898   st_AllocateFailRate = Percent;
00899   return (Old);
00900 }
00901
00902 /*
00903  * Fortify_CheckAllMemory() - Checks the fortifications
00904  * of all memory on the allocated list. And, if
00905  * FORTIFY_DEALLOCATED_MEMORY is enabled, all the
00906  * known deallocated memory as well.
00907  * Returns the number of blocks that failed.
00908  * Always returns 0 if Fortify is disabled.
00909  */
00910 DWORD FORTIFY_STORAGE Fortify_CheckAllMemory (const char *file, DWORD line)
00911 {
00912   struct Header *curr = st_AllocatedHead;
00913   DWORD  count = 0;
00914
00915   if (st_Disabled)
00916      return (DWORD)-1;
00917
00918   FORTIFY_LOCK();
00919
00920   /* Check the allocated memory
00921    */
00922   while (curr)
00923   {
00924     if (!st_CheckBlock(curr, file, line))
00925     {
00926       count++;
00927       break;    /* !! added, GV 13/7-98 */
00928     }
00929     curr = curr->Next;
00930   }
00931
00932   /* Check the deallocated memory while you're at it
00933    */
00934 #ifdef FORTIFY_TRACK_DEALLOCATED_MEMORY
00935   curr = st_DeallocatedHead;
00936   while (curr)
00937   {
00938     if (!st_CheckDeallocatedBlock(curr, file, line))
00939     {
00940       count++;
00941       break;    /* !! added, GV 13/7-98 */
00942     }
00943     curr = curr->Next;
00944   }
00945 #endif
00946
00947   /* If we know where we are, and everything is cool,
00948    * remember that. It might be important.
00949    */
00950   if (file && count == 0)
00951   {
00952     st_LastVerifiedFile = file;
00953     st_LastVerifiedLine = line;
00954   }
00955   FORTIFY_UNLOCK();
00956   return (count);
00957 }
00958
00959
00960 /*
00961  * Fortify_EnterScope() - enters a new Fortify scope
00962  * level. Returns the new scope level.
00963  */
00964 BYTE FORTIFY_STORAGE Fortify_EnterScope (const char *file, DWORD line)
00965 {
00966   ARGSUSED (file);
00967   ARGSUSED (line);
00968   return (++st_Scope);
00969 }
00970
00971 /* Fortify_LeaveScope - leaves a Fortify scope level,
00972  * also prints a memory dump of all non-freed memory
00973  * that was allocated during the scope being exited.
00974  * Does nothing and returns 0 if Fortify is disabled.
00975  */
00976 BYTE FORTIFY_STORAGE Fortify_LeaveScope (const char *file, DWORD line)
00977 {
00978   struct Header *curr = st_AllocatedHead;
00979   DWORD size = 0, count = 0;
00980
00981   if (st_Disabled)
00982      return (0);
00983
00984   FORTIFY_LOCK();
00985
00986   st_Scope--;
00987   while (curr)
00988   {
00989     if (curr->Scope > st_Scope)
00990     {
00991       if (count == 0)
00992       {
00993         message (1, "Memory leak detected leaving scope at %s.%lu\n",
00994                  file, line);
00995         sprintf (st_Buffer, "%8s %8s %s\n", "Address", "Size", "Allocator");
00996         ST_OUTPUT (st_Buffer);
00997       }
00998       if (!st_OutputHeader(curr))
00999          break;
01000       count++;
01001       size += curr->Size;
01002     }
01003     curr = curr->Next;
01004   }
01005
01006   if (count)
01007   {
01008     sprintf (st_Buffer,"%8s %8lu bytes in %lu blocks with %lu bytes overhead\n",
01009              "total", size, count, count * FORTIFY_OVERHEAD);
01010     ST_OUTPUT (st_Buffer);
01011   }
01012
01013 #ifdef FORTIFY_TRACK_DEALLOCATED_MEMORY
01014   /*
01015    * Quietly free all the deallocated memory
01016    * that was allocated in this scope that
01017    * we are still tracking
01018    */
01019   st_PurgeDeallocatedScope (st_Scope, file, line);
01020 #endif
01021
01022   FORTIFY_UNLOCK();
01023   return (st_Scope);
01024 }
01025
01026 /*
01027  * Fortify_ListAllMemory() - Outputs the entire
01028  * list of currently allocated memory. For each block
01029  * is output it's Address, Size, and the SourceFile and
01030  * Line that allocated it.
01031  *
01032  * If there is no memory on the list, this function
01033  * outputs nothing.
01034  *
01035  * It returns the number of blocks on the list, unless
01036  * Fortify has been disabled, in which case it always
01037  * returns 0.
01038  */
01039 DWORD FORTIFY_STORAGE Fortify_ListAllMemory (const char *file, DWORD line)
01040 {
01041   struct Header *curr = st_AllocatedHead;
01042   DWORD  size = 0, count = 0;
01043
01044   if (st_Disabled)
01045   {
01046     ST_OUTPUT ("Fortify: disabled\n");
01047     return (0);
01048   }
01049
01050   Fortify_CheckAllMemory (file, line);
01051
01052   FORTIFY_LOCK();
01053
01054   if (curr)
01055   {
01056     sprintf (st_Buffer, "\n\nFortify: Memory List at %s.%lu\n", file, line);
01057     ST_OUTPUT (st_Buffer);
01058     sprintf (st_Buffer, "%8s %8s %s\n", "Address", "Size", "Allocator");
01059     ST_OUTPUT (st_Buffer);
01060
01061     while (curr)
01062     {
01063       if (!st_OutputHeader (curr))
01064          break;
01065       count++;
01066       size += curr->Size;
01067       curr = curr->Next;
01068     }
01069     sprintf (st_Buffer, "%8s %8lu bytes in %lu blocks and %lu bytes overhead\n",
01070              "total", size, count, count * FORTIFY_OVERHEAD);
01071     ST_OUTPUT (st_Buffer);
01072   }
01073   FORTIFY_UNLOCK();
01074   return (count);
01075 }
01076
01077 /*
01078  * Fortify_DumpAllMemory() - Outputs the entire list of
01079  * currently allocated memory. For each allocated block
01080  * is output it's Address, Size, the SourceFile and Line
01081  * that allocated it, a hex dump of the contents of the
01082  * memory and an ascii dump of printable characters.
01083  *
01084  * If there is no memory on the list, this function outputs nothing.
01085  */
01086 DWORD FORTIFY_STORAGE Fortify_DumpAllMemory (const char *file, DWORD line)
01087 {
01088   struct Header *curr = st_AllocatedHead;
01089   DWORD  count = 0;
01090
01091   if (st_Disabled)
01092      return (0);
01093
01094   Fortify_CheckAllMemory (file, line);
01095
01096   FORTIFY_LOCK();
01097
01098   while (curr)
01099   {
01100     message (1, "Hex Dump of %s at %s.%lu\n",
01101              st_MemoryBlockString(curr), file, line);
01102     st_OutputMemory (curr);
01103     ST_OUTPUT ("\n");
01104     count++;
01105     curr = curr->Next;
01106   }
01107   FORTIFY_UNLOCK();
01108   return (count);
01109 }
01110
01111 /* Fortify_OutputStatistics() - displays statistics
01112  * about the maximum amount of memory that was
01113  * allocated at any one time.
01114  */
01115 void FORTIFY_STORAGE Fortify_OutputStatistics (const char *file, DWORD line)
01116 {
01117   if (st_Disabled)
01118      return;
01119
01120   message (1, "Statistics at %s.%lu\n", file, line);
01121
01122   sprintf (st_Buffer, "         Memory currently allocated: %lu bytes in %lu blocks\n",
01123            st_CurAllocation, st_CurBlocks);
01124   ST_OUTPUT (st_Buffer);
01125
01126   sprintf (st_Buffer, "         Maximum memory allocated at one time: %lu bytes in %lu blocks\n",
01127            st_MaxAllocation, st_MaxBlocks);
01128   ST_OUTPUT (st_Buffer);
01129
01130   sprintf (st_Buffer, "         There have been %lu allocations and %lu deallocations\n",
01131            st_Allocations, st_Frees);
01132   ST_OUTPUT (st_Buffer);
01133
01134   sprintf (st_Buffer, "         There was a total of %lu bytes allocated\n",
01135            st_TotalAllocation);
01136   ST_OUTPUT (st_Buffer);
01137
01138   if (st_Allocations > 0)
01139   {
01140     sprintf (st_Buffer, "         The average allocation was %lu bytes\n",
01141              st_TotalAllocation / st_Allocations);
01142     ST_OUTPUT (st_Buffer);
01143   }
01144 }
01145
01146 /* Fortify_GetCurrentAllocation() - returns the number of
01147  * bytes currently allocated.
01148  */
01149 DWORD FORTIFY_STORAGE Fortify_GetCurrentAllocation (const char *file, DWORD line)
01150 {
01151   ARGSUSED (file);
01152   ARGSUSED (line);
01153
01154   if (st_Disabled)
01155      return (0);
01156
01157   return (st_CurAllocation);
01158 }
01159
01160 /* Fortify_SetAllocationLimit() - set a limit on the total
01161  * amount of memory allowed for this application.
01162  */
01163 void FORTIFY_STORAGE
01164 Fortify_SetAllocationLimit (DWORD NewLimit, const char *file, DWORD line)
01165 {
01166   ARGSUSED (file);
01167   ARGSUSED (line);
01168   st_AllocationLimit = NewLimit;
01169 }
01170
01171 /*
01172  * Fortify_Disable() - Run time method of disabling Fortify.
01173  * Useful if you need to turn off Fortify without recompiling
01174  * everything. Not as effective as compiling out, of course.
01175  * The less memory allocated by Fortify when it is disabled
01176  * the better.
01177  * (Previous versions of Fortify did not allow it to be
01178  * disabled if there was any memory allocated at the time,
01179  * but since in C++ memory is often allocated before main
01180  * is even entered, this was useless so Fortify is now
01181  * able to cope).
01182  */
01183 void FORTIFY_STORAGE Fortify_Disable (const char *file, DWORD line)
01184 {
01185 #ifdef FORTIFY_TRACK_DEALLOCATED_MEMORY
01186   /* free all deallocated memory we might be tracking */
01187   if (file && line)
01188      st_PurgeDeallocatedScope (0, file, line);
01189 #endif
01190
01191   st_Disabled = 1;
01192 }
01193
01194 /*
01195  * st_CheckBlock - Check a block's header and fortifications.
01196  * Returns true if the block is happy.
01197  */
01198 static int st_CheckBlock (struct Header *h, const char *file, DWORD line)
01199 {
01200   BYTE *ptr = (BYTE *)h;
01201   int  result = 1;
01202
01203   if (!st_IsHeaderValid(h))
01204   {
01205     message (1, "Invalid pointer (%08lX) or corrupted header detected at %s.%lu\n",
01206              (DWORD)(ptr + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE), file, line);
01207     st_OutputLastVerifiedPoint();
01208     return (0);
01209   }
01210
01211   if (!st_CheckFortification(ptr + FORTIFY_HEADER_SIZE,
01212                              FORTIFY_BEFORE_VALUE, FORTIFY_ALIGNED_BEFORE_SIZE))
01213   {
01214     message (1, "Underwrite detected before block %s at %s.%lu\n",
01215              st_MemoryBlockString(h), file, line);
01216
01217     st_OutputLastVerifiedPoint();
01218     st_OutputFortification (ptr + FORTIFY_HEADER_SIZE,
01219                             FORTIFY_BEFORE_VALUE, FORTIFY_ALIGNED_BEFORE_SIZE);
01220     result = 0;
01221
01222 #ifdef FORTIFY_FILL_ON_CORRUPTION
01223     st_SetFortification (ptr + FORTIFY_HEADER_SIZE, FORTIFY_BEFORE_VALUE,
01224                          FORTIFY_ALIGNED_BEFORE_SIZE);
01225 #endif
01226   }
01227
01228   if (!st_CheckFortification(ptr + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE +
01229                              h->Size, FORTIFY_AFTER_VALUE, FORTIFY_AFTER_SIZE))
01230   {
01231     message (1, "Overwrite detected after block %s at %s.%lu\n",
01232              st_MemoryBlockString(h), file, line);
01233
01234     st_OutputLastVerifiedPoint();
01235     st_OutputFortification (ptr + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE +
01236                             h->Size, FORTIFY_AFTER_VALUE, FORTIFY_AFTER_SIZE);
01237     result = 0;
01238
01239 #ifdef FORTIFY_FILL_ON_CORRUPTION
01240     st_SetFortification (ptr + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE +
01241                          h->Size, FORTIFY_AFTER_VALUE, FORTIFY_AFTER_SIZE);
01242 #endif
01243   }
01244   return (result);
01245 }
01246
01247 #ifdef FORTIFY_TRACK_DEALLOCATED_MEMORY
01248
01249 /*
01250  * st_CheckDeallocatedBlock - Check a deallocated block's header and fortifications.
01251  * Returns true if the block is happy.
01252  */
01253 static int
01254 st_CheckDeallocatedBlock (struct Header *h, const char *file, DWORD line)
01255 {
01256   BYTE *ptr = (BYTE *)h;
01257   int result = 1;
01258
01259   if (!st_IsHeaderValid(h))
01260   {
01261     message (1, "Invalid deallocated pointer (%08lX) or corrupted header detected at %s.%lu\n",
01262              (DWORD)(ptr + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE),
01263              file, line);
01264     st_OutputLastVerifiedPoint();
01265     return (0);
01266   }
01267
01268   if (!st_CheckFortification(ptr + FORTIFY_HEADER_SIZE,
01269           FORTIFY_BEFORE_VALUE, FORTIFY_ALIGNED_BEFORE_SIZE))
01270   {
01271     message (1, "Underwrite detected before deallocated block %s at %s.%lu\n",
01272              st_MemoryBlockString(h), file, line);
01273
01274     sprintf (st_Buffer, "         Memory block was deallocated by \"%s\" at %s.%lu\n",
01275              st_DeallocatorName[h->Deallocator], h->FreedFile, h->FreedLine);
01276     ST_OUTPUT (st_Buffer);
01277
01278     st_OutputLastVerifiedPoint();
01279     st_OutputFortification (ptr + FORTIFY_HEADER_SIZE,
01280                             FORTIFY_BEFORE_VALUE, FORTIFY_ALIGNED_BEFORE_SIZE);
01281
01282 #ifdef FORTIFY_FILL_ON_CORRUPTION
01283     st_SetFortification (ptr + FORTIFY_HEADER_SIZE, FORTIFY_BEFORE_VALUE,
01284                          FORTIFY_ALIGNED_BEFORE_SIZE);
01285 #endif
01286     result = 0;
01287   }
01288
01289   if (!st_CheckFortification(ptr + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE +
01290                              h->Size, FORTIFY_AFTER_VALUE, FORTIFY_AFTER_SIZE))
01291   {
01292     message (1, "Overwrite detected after deallocated block %s at %s.%lu\n",
01293              st_MemoryBlockString(h), file, line);
01294
01295     sprintf (st_Buffer, "         Memory block was deallocated by \"%s\" at %s.%lu\n",
01296              st_DeallocatorName[h->Deallocator], h->FreedFile, h->FreedLine);
01297     ST_OUTPUT (st_Buffer);
01298
01299     st_OutputLastVerifiedPoint();
01300     st_OutputFortification (ptr + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE +
01301                             h->Size, FORTIFY_AFTER_VALUE, FORTIFY_AFTER_SIZE);
01302
01303 #ifdef FORTIFY_FILL_ON_CORRUPTION
01304     st_SetFortification (ptr + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE +
01305                          h->Size, FORTIFY_AFTER_VALUE, FORTIFY_AFTER_SIZE);
01306 #endif
01307     result = 0;
01308   }
01309
01310 #ifdef FORTIFY_FILL_ON_DEALLOCATE
01311   if (!st_CheckFortification (ptr + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE,
01312                              FORTIFY_FILL_ON_DEALLOCATE_VALUE, h->Size))
01313   {
01314     message (1, "Write to deallocated block %s detected at %s.%lu\n",
01315              st_MemoryBlockString(h), file, line);
01316
01317     sprintf (st_Buffer, "         Memory block was deallocated by \"%s\" at %s.%lu\n",
01318              st_DeallocatorName[h->Deallocator], h->FreedFile, h->FreedLine);
01319     ST_OUTPUT (st_Buffer);
01320     st_OutputLastVerifiedPoint();
01321
01322     st_OutputFortification (ptr + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE,
01323                             FORTIFY_FILL_ON_DEALLOCATE_VALUE, h->Size);
01324
01325 #ifdef FORTIFY_FILL_ON_CORRUPTION
01326     st_SetFortification (ptr + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE,
01327                          FORTIFY_FILL_ON_DEALLOCATE_VALUE, h->Size);
01328 #endif
01329     result = 0;
01330   }
01331 #endif
01332   return (result);
01333 }
01334 #endif /* FORTIFY_TRACK_DEALLOCATED_MEMORY */
01335
01336
01337 /*
01338  * st_CheckFortification - Checks if the _size_
01339  * bytes from _ptr_ are all set to _value_
01340  * Returns true if all is happy.
01341  */
01342 static int
01343 st_CheckFortification (BYTE *ptr, BYTE value, size_t size)
01344 {
01345   while (size--)
01346         if (*ptr++ != value)
01347            return (0);
01348   return (1);
01349 }
01350
01351 /*
01352  * st_SetFortification - Set the _size_ bytes from _ptr_ to _value_.
01353  */
01354 static void
01355 st_SetFortification (BYTE *ptr, BYTE value, size_t size)
01356 {
01357   memset (ptr, value, size);
01358 }
01359
01360 /*
01361  * st_OutputFortification - Output the corrupted section of the fortification
01362  */
01363 static void
01364 st_OutputFortification (BYTE *ptr, BYTE value, size_t size)
01365 {
01366   size_t offset = 0, skipped, advance;
01367
01368   sprintf (st_Buffer, "   Address   Offset Data (%02x)", value);
01369   ST_OUTPUT (st_Buffer);
01370
01371   while (offset < size)
01372   {
01373     /* Skip 3 or more 'correct' lines
01374      */
01375     if ((size - offset) < 3 * 16)
01376          advance = size - offset;
01377     else advance = 3 * 16;
01378
01379     if (advance > 0 && st_CheckFortification(ptr+offset, value, advance))
01380     {
01381       offset += advance;
01382       skipped = advance;
01383
01384       if (size - offset < 16)
01385            advance = size - offset;
01386       else advance = 16;
01387
01388       while (advance > 0 && st_CheckFortification(ptr+offset, value, advance))
01389       {
01390         offset  += advance;
01391         skipped += advance;
01392         if (size - offset < 16)
01393              advance = size - offset;
01394         else advance = 16;
01395       }
01396       sprintf (st_Buffer, "\n                        ...%lu bytes skipped...",
01397                (DWORD)skipped);
01398       ST_OUTPUT (st_Buffer);
01399       continue;
01400     }
01401
01402     if (size - offset < 16)
01403          st_HexDump (ptr, offset, size-offset, 0);
01404     else st_HexDump (ptr, offset, 16, 0);
01405     offset += 16;
01406   }
01407   ST_OUTPUT ("\n");
01408 }
01409
01410 /*
01411  * st_HexDump - output a nice hex dump of "size" bytes, starting at
01412  * "ptr" + "offset"
01413  */
01414 static void st_HexDump (BYTE *ptr, size_t offset, size_t size, int title)
01415 {
01416   char   ascii[17];
01417   int    column;
01418   size_t output;
01419
01420   if (title)
01421      ST_OUTPUT ("   Address   Offset Data");
01422
01423   column = 0;
01424   ptr += offset;
01425   output = 0;
01426
01427   while (output < size)
01428   {
01429     if (column == 0)
01430        message (0, "\n%08lX %8lu ", (DWORD)ptr, (DWORD)offset);
01431
01432     message (0, "%02x%s", *ptr, ((column % 4) == 3) ? " " : "");
01433
01434     ascii [column]   = isprint(*ptr) ? (char)*ptr : '.';
01435     ascii [column+1] = '\0';
01436
01437     ptr++;
01438     offset++;
01439     output++;
01440     column++;
01441
01442     if (column == 16)
01443     {
01444       ST_OUTPUT ("   \"");
01445       ST_OUTPUT (ascii);
01446       ST_OUTPUT ("\"");
01447       column = 0;
01448     }
01449   }
01450
01451   if (column != 0)
01452   {
01453     while  (column < 16)
01454     {
01455       if (column % 4 == 3)
01456            ST_OUTPUT ("   ");
01457       else ST_OUTPUT ("  ");
01458       column++;
01459     }
01460     ST_OUTPUT ("   \"");
01461     ST_OUTPUT (ascii);
01462     ST_OUTPUT ("\"");
01463   }
01464 }
01465
01466 /*
01467  * st_IsHeaderValid - Returns true if the
01468  * supplied pointer does indeed point to a
01469  * real Header
01470  */
01471 static int st_IsHeaderValid (const struct Header *h)
01472 {
01473   return (st_ChecksumHeader(h) == FORTIFY_CHECKSUM_VALUE);
01474 }
01475
01476 /*
01477  * st_MakeHeaderValid - Updates the checksum
01478  * to make the header valid
01479  */
01480 static void st_MakeHeaderValid (struct Header *h)
01481 {
01482   h->Checksum = 0;
01483   h->Checksum = (WORD)(FORTIFY_CHECKSUM_VALUE - st_ChecksumHeader(h));
01484 }
01485
01486 /*
01487  * st_ChecksumHeader - Calculate (and return)
01488  * the checksum of the header. (Including the
01489  * Checksum field itself. If all is well, the
01490  * checksum returned by this function should
01491  * be FORTIFY_CHECKSUM_VALUE
01492  */
01493 static WORD st_ChecksumHeader (const struct Header *h)
01494 {
01495   WORD  c, checksum;
01496   WORD *p = (WORD*)h;
01497
01498   for (c = checksum = 0; c < FORTIFY_HEADER_SIZE/sizeof(WORD); c++)
01499       checksum += *p++;
01500   return (checksum);
01501 }
01502
01503 /*
01504  * st_IsOnAllocatedList - Examines the allocated
01505  * list to see if the given header is on it.
01506  */
01507 static int st_IsOnAllocatedList (const struct Header *h)
01508 {
01509   const struct Header *curr;
01510
01511   for (curr = st_AllocatedHead; curr; curr = curr->Next)
01512       if (curr == h)
01513          return (1);
01514   return (0);
01515 }
01516
01517 #ifdef FORTIFY_TRACK_DEALLOCATED_MEMORY
01518 /*
01519  * st_IsOnDeallocatedList - Examines the deallocated
01520  * list to see if the given header is on it.
01521  */
01522 static int st_IsOnDeallocatedList (const struct Header *h)
01523 {
01524   struct Header *curr;
01525
01526   for (curr = st_DeallocatedHead; curr; curr = curr->Next)
01527       if (curr == h)
01528          return (1);
01529   return (0);
01530 }
01531
01532 /*
01533  * st_PurgeDeallocatedBlocks - free at least "Bytes"
01534  * worth of deallocated memory, starting at the
01535  * oldest deallocated block.
01536  * Returns true if any blocks were freed.
01537  */
01538 static int st_PurgeDeallocatedBlocks (DWORD Bytes, const char *file, DWORD line)
01539 {
01540   DWORD FreedBytes = 0;
01541   DWORD FreedBlocks = 0;
01542
01543 #ifdef FORTIFY_WARN_WHEN_DISCARDING_DEALLOCATED_MEMORY
01544   message (1, "Warning - Discarding deallocated memory at %s.%lu\n", file, line);
01545 #endif
01546
01547   while (st_DeallocatedTail && FreedBytes < Bytes)
01548   {
01549     st_CheckDeallocatedBlock (st_DeallocatedTail, file, line);
01550     FreedBytes += st_DeallocatedTail->Size;
01551     FreedBlocks++;
01552
01553 #ifdef FORTIFY_WARN_WHEN_DISCARDING_DEALLOCATED_MEMORY
01554 #ifdef FORTIFY_VERBOSE_WARN_WHEN_DISCARDING_DEALLOCATED_MEMORY
01555     sprintf (st_Buffer, "                %s\n",
01556              st_DeallocatedMemoryBlockString(st_DeallocatedTail));
01557     ST_OUTPUT (st_Buffer);
01558 #endif
01559 #endif
01560     st_FreeDeallocatedBlock(st_DeallocatedTail, file, line);
01561   }
01562   return (FreedBlocks != 0);
01563 }
01564
01565 /*
01566  * st_PurgeDeallocatedScope - free all deallocated
01567  * memory blocks that were allocated within "Scope"
01568  */
01569 static int st_PurgeDeallocatedScope (BYTE Scope, const char *file, DWORD line)
01570 {
01571   struct Header *curr = st_DeallocatedHead;
01572   struct Header *next;
01573   DWORD  FreedBlocks  = 0;
01574
01575   while (curr)
01576   {
01577     next = curr->Next;
01578     if (curr->Scope >= Scope)
01579     {
01580       st_FreeDeallocatedBlock (curr, file, line);
01581       FreedBlocks++;
01582     }
01583     curr = next;
01584   }
01585   return (FreedBlocks != 0);
01586 }
01587
01588 /*
01589  * st_FreeDeallocatedBlock - actually remove
01590  * a deallocated block from the deallocated
01591  * list, and actually free it's memory.
01592  */
01593 static void st_FreeDeallocatedBlock (struct Header *h, const char *file, DWORD line)
01594 {
01595   st_CheckDeallocatedBlock (h, file, line);
01596
01597  /* Begin Critical region
01598   */
01599   FORTIFY_LOCK();
01600
01601   st_TotalDeallocated -= h->Size;
01602
01603   if (st_DeallocatedHead == h)
01604       st_DeallocatedHead = h->Next;
01605
01606   if (st_DeallocatedTail == h)
01607       st_DeallocatedTail = h->Prev;
01608
01609   if (h->Prev)
01610   {
01611     st_CheckDeallocatedBlock (h->Prev, file, line);
01612     h->Prev->Next = h->Next;
01613     st_MakeHeaderValid (h->Prev);
01614   }
01615
01616   if (h->Next)
01617   {
01618     st_CheckDeallocatedBlock (h->Next, file, line);
01619     h->Next->Prev = h->Prev;
01620     st_MakeHeaderValid (h->Next);
01621   }
01622
01623   /* Free the label
01624    */
01625   if (h->Label)
01626      free (h->Label);
01627
01628   /* Nuke out all memory that is about to be freed, including the header
01629    */
01630   st_SetFortification ((BYTE*)h, FORTIFY_FILL_ON_DEALLOCATE_VALUE,
01631                        FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE +
01632                        h->Size + FORTIFY_AFTER_SIZE);
01633
01634   /* And do the actual free
01635    */
01636   free (h);
01637
01638   /* End critical region
01639    */
01640   FORTIFY_UNLOCK();
01641 }
01642 #endif /* FORTIFY_TRACK_DEALLOCATED_MEMORY */
01643
01644 /*
01645  * st_OutputMemory - Hex and ascii dump the
01646  * user memory of a block.
01647  */
01648 static void st_OutputMemory (struct Header *h)
01649 {
01650   int hlen = FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE;
01651
01652   if (!VALIDATE (h, hlen, sprintf(st_Buffer, "Invalid header %p",h)))
01653        ST_OUTPUT (st_Buffer);
01654   else st_HexDump ((BYTE*)h + hlen, 0, h->Size, 1);
01655 }
01656
01657
01658 /*
01659  * st_OutputHeader - Output the header
01660  */
01661 static int st_OutputHeader (struct Header *h)
01662 {
01663   int   hlen = FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE;
01664   BYTE *addr = (BYTE*)h + hlen;
01665   char *p    = st_Buffer;
01666
01667   if (!VALIDATE(h, hlen, sprintf(st_Buffer, "Invalid header %p",h)))
01668   {
01669     ST_OUTPUT (st_Buffer);
01670     return (0);
01671   }
01672
01673   p += sprintf (p, "%08lX %8lu ", (DWORD)addr, (DWORD)h->Size);
01674
01675   if (VALIDATE (h->File, 13, p += sprintf(p, "file?.")))
01676      p += sprintf (p, "%s.", h->File);
01677
01678   p += sprintf (p, "%lu  ", h->Line);
01679
01680   if (h->Label)
01681   {
01682     if (VALIDATE (h->Label, 50, p += sprintf(p, "label?")))
01683        p += sprintf (p, "%s", h->Label);
01684   }
01685   *p++ = '\n';
01686   *p = '\0';
01687
01688   ST_OUTPUT (st_Buffer);
01689   return (1);
01690 }
01691
01692 /*
01693  * st_OutputLastVerifiedPoint - output the last
01694  * known point where everything was hoopy.
01695  */
01696 static void st_OutputLastVerifiedPoint (void)
01697 {
01698   sprintf (st_Buffer, "         Memory integrity was last verified at %s.%lu\n",
01699            st_LastVerifiedFile, st_LastVerifiedLine);
01700   ST_OUTPUT (st_Buffer);
01701 }
01702
01703 /*
01704  * st_MemoryBlockString - constructs a string that
01705  * desribes a memory block. (pointer,size,allocator,label)
01706  */
01707 static const char *st_MemoryBlockString (struct Header *h)
01708 {
01709   static char st_BlockString[512];
01710
01711   if (!VALIDATE (h, sizeof(*h),
01712                  sprintf (st_BlockString, "(invalid header %p)", h)))
01713      return (st_BlockString);
01714
01715   if (h->Label == 0)
01716        sprintf (st_BlockString, "(%08lX,%lu,%s.%lu)",
01717                 (DWORD)h + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE,
01718                 (DWORD)h->Size, h->File, h->Line);
01719   else sprintf (st_BlockString, "(%08lX,%lu,%s.%lu,%s)",
01720                 (DWORD)h + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE,
01721                 (DWORD)h->Size, h->File, h->Line, h->Label);
01722   return (st_BlockString);
01723 }
01724
01725 #ifdef FORTIFY_TRACK_DEALLOCATED_MEMORY
01726 #ifdef FORTIFY_WARN_WHEN_DISCARDING_DEALLOCATED_MEMORY
01727 #ifdef FORTIFY_VERBOSE_WARN_WHEN_DISCARDING_DEALLOCATED_MEMORY
01728
01729 /*
01730  * st_DeallocatedMemoryBlockString - constructs
01731  * a string that desribes a deallocated memory
01732  * block. (pointer,size,allocator,deallocator)
01733  */
01734 static const char *st_DeallocatedMemoryBlockString (struct Header *h)
01735 {
01736   static char st_BlockString[256];
01737
01738   if (h->Label == 0)
01739        sprintf (st_BlockString,"(%08lX,%lu,%s.%lu,%s.%lu)",
01740                 (DWORD)h + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE,
01741                 (DWORD)h->Size, h->File, h->Line, h->FreedFile, h->FreedLine);
01742   else sprintf (st_BlockString,"(%08lX,%lu,%s.%lu,%s.%lu,%s)",
01743                 (DWORD)h + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE,
01744                 (DWORD)h->Size, h->File, h->Line, h->FreedFile, h->FreedLine,
01745                 h->Label);
01746
01747   return (st_BlockString);
01748 }
01749 #endif
01750 #endif
01751 #endif
01752
01753
01754 /*
01755  * st_DefaultOutput - the default output function
01756  */
01757 static void st_DefaultOutput (const char *String)
01758 {
01759   fprintf (stdout, String);
01760   fflush (stdout);
01761 }
01762
01763 /*
01764  * Fortify_malloc - Fortify's replacement malloc()
01765  */
01766 void *FORTIFY_STORAGE
01767 Fortify_malloc (size_t size, const char *file, DWORD line)
01768 {
01769   return Fortify_Allocate (size, Fortify_Allocator_malloc, 0, file, line);
01770 }
01771
01772 /*
01773  * Fortify_realloc - Fortify's replacement realloc()
01774  */
01775 void *Fortify_realloc (void *uptr, size_t new_size, const char *file, DWORD line)
01776 {
01777   BYTE          *ptr = (BYTE*) uptr - FORTIFY_HEADER_SIZE - FORTIFY_ALIGNED_BEFORE_SIZE;
01778   struct Header *h   = (struct Header*) ptr;
01779   void          *new_ptr;
01780
01781   /* If Fortify is disabled, we gotta do this a little differently.
01782    */
01783   if (!st_Disabled)
01784   {
01785     if (!uptr)
01786        return Fortify_Allocate (new_size, Fortify_Allocator_realloc, 0, file, line);
01787
01788     if (!st_IsOnAllocatedList(h))
01789     {
01790 #ifdef FORTIFY_TRACK_DEALLOCATED_MEMORY
01791       if (st_IsOnDeallocatedList(h))
01792       {
01793         message (1, "Deallocated memory block passed to \"%s\" at %s.%lu\n",
01794                  st_AllocatorName[Fortify_Allocator_realloc], file, line);
01795
01796         sprintf (st_Buffer,   "         Memory block %s was deallocated by \"%s\" at %s.%lu\n",
01797                  st_MemoryBlockString(h),
01798                  st_DeallocatorName[h->Deallocator], h->FreedFile, h->FreedLine);
01799         ST_OUTPUT (st_Buffer);
01800         return (0);
01801       }
01802 #endif
01803       message (1, "Invalid pointer (%08lX) passed to realloc at %s.%lu\n",
01804                (DWORD)ptr, file, line);
01805       return (0);
01806     }
01807
01808     if (!st_CheckBlock(h, file, line))
01809        return (0);
01810
01811     new_ptr = Fortify_Allocate (new_size, Fortify_Allocator_realloc, 0, file, line);
01812     if (!new_ptr)
01813        return (0);
01814
01815     if (h->Size < new_size)
01816          memcpy (new_ptr, uptr, h->Size);
01817     else memcpy (new_ptr, uptr, new_size);
01818
01819     Fortify_Deallocate (uptr, Fortify_Deallocator_realloc, file, line);
01820     return (new_ptr);
01821   }
01822
01823   /* If the old block was fortified, we can't use normal realloc.
01824    */
01825   if (st_IsOnAllocatedList(h))
01826   {
01827     new_ptr = Fortify_Allocate (new_size, Fortify_Allocator_realloc, 0, file, line);
01828     if (!new_ptr)
01829        return (0);
01830
01831     if (h->Size < new_size)
01832          memcpy (new_ptr, uptr, h->Size);
01833     else memcpy (new_ptr, uptr, new_size);
01834
01835     Fortify_Deallocate (uptr, Fortify_Deallocator_realloc, file, line);
01836     return (new_ptr);
01837   }
01838   return realloc (uptr, new_size);
01839 }
01840
01841 /*
01842  * Fortify_calloc - Fortify's replacement calloc
01843  */
01844 void *Fortify_calloc (size_t num, size_t size, const char *file, DWORD line)
01845 {
01846   if (!st_Disabled)
01847   {
01848     void *ptr = Fortify_Allocate (size * num, Fortify_Allocator_calloc,
01849                                   0, file, line);
01850     if (ptr)
01851        memset (ptr, 0, size*num);
01852     return (ptr);
01853   }
01854   return calloc (num, size);
01855 }
01856
01857 /*
01858  * Fortify_free - Fortify's replacement free
01859  */
01860 void Fortify_free (void *uptr, const char *file, DWORD line)
01861 {
01862   if (!uptr)
01863        message (1, "freeing of NULL ptr at %s.%lu\n", file, line);
01864   else Fortify_Deallocate (uptr, Fortify_Deallocator_free, file, line);
01865 }
01866
01867
01868 #if defined(_WIN32) || defined(WIN32) && defined(FORTIFY_GLOBAL_REPLACE)
01869
01870 HGLOBAL Fortify_GlobalAlloc (UINT flags, DWORD size, const char *file, DWORD line)
01871 {
01872   void *ptr = GlobalAlloc (flags, size);
01873
01874   if (size == 0)
01875      message (1, "A \"%s\" of 0 bytes attempted at %s.%lu\n",
01876               st_AllocatorName[Fortify_Allocator_GlobalAlloc], file, line);
01877   if (!ptr)
01878      message (1, "A \"%s\" of %lu bytes failed at %s.%lu\n",
01879               st_AllocatorName[Fortify_Allocator_GlobalAlloc], file, line);
01880   return (ptr ? GlobalLock(ptr) : NULL);
01881 }
01882
01883 BOOL Fortify_GlobalFree (void *ptr, const char *file, DWORD line)
01884 {
01885   HGLOBAL hnd;
01886
01887   if (!ptr)
01888   {
01889     message (1, "A \"%s\" freeing of NULL ptr at %s.%lu\n",
01890              st_DeallocatorName[Fortify_Allocator_GlobalFree], file, line);
01891     hnd = NULL;
01892   }
01893   else
01894   {
01895     GlobalUnlockPtr (ptr);
01896     hnd = GlobalFree (GlobalPtrHandle(ptr));
01897   }
01898   return (hnd ? TRUE : FALSE);
01899 }
01900 #endif
01901
01902 /*
01903  * Fortify_strdup - Fortify's replacement strdup. Since strdup isn't
01904  * ANSI, it is only provided if FORTIFY_STRDUP is defined.
01905  */
01906 #ifdef FORTIFY_STRDUP
01907 char *FORTIFY_STORAGE Fortify_strdup (const char *oldStr, const char *file, DWORD line)
01908 {
01909   if (!st_Disabled)
01910   {
01911     char *newStr = (char*) Fortify_Allocate (strlen(oldStr)+1, Fortify_Allocator_strdup,
01912                                              0, file, line);
01913     if (newStr)
01914        strcpy (newStr, oldStr);
01915     return (newStr);
01916   }
01917   return strdup (oldStr);
01918 }
01919 #endif /* FORTIFY_STRDUP */
01920
01921
01922 static void st_OutputDeleteTrace (void)
01923 {
01924 #ifdef __cplusplus
01925   if (st_DeleteStackTop > 1)
01926   {
01927     message (0, "Delete Trace: %s.%lu\n",
01928              st_DeleteFile[st_DeleteStackTop-1],
01929              st_DeleteLine[st_DeleteStackTop-1]);
01930     for (int c = st_DeleteStackTop-2; c >= 0; c--)
01931         message (0, "              %s.%lu\n",
01932                  st_DeleteFile[c], st_DeleteLine[c]);
01933   }
01934 #endif
01935 }
01936
01937 #ifdef __cplusplus
01938
01939 /*
01940  * st_NewHandler() - there is no easy way to get
01941  * the new handler function. And isn't it great
01942  * how the new handler doesn't take a parameter
01943  * giving the size of the request that failed.
01944  * Thanks Bjarne!
01945  */
01946 Fortify_NewHandlerFunc st_NewHandler (void)
01947 {
01948   /* get the current handler
01949    */
01950   Fortify_NewHandlerFunc handler = set_new_handler (0);
01951
01952   /* and set it back (since we cant
01953    * get it without changing it)
01954    */
01955   set_new_handler (handler);
01956   return (handler);
01957 }
01958
01959 /*
01960  * operator new - Fortify's replacement new,
01961  * without source-code information.
01962  */
01963 void *FORTIFY_STORAGE operator new (size_t size)
01964 {
01965   void *p;
01966
01967   while ((p = Fortify_Allocate(size, Fortify_Allocator_new,
01968               0, st_AllocatorName[Fortify_Allocator_new], 0)) == 0)
01969   {
01970     if (st_NewHandler())
01971          (*st_NewHandler())();
01972     else return (0);
01973   }
01974   return (p);
01975 }
01976
01977 /*
01978  * operator new - Fortify's replacement new,
01979  * with source-code information
01980  */
01981 void *FORTIFY_STORAGE
01982 operator new (size_t size, const char *file, DWORD line)
01983 {
01984   void *p;
01985
01986   while ((p = Fortify_Allocate(size, Fortify_Allocator_new, 0, file, line)) == 0)
01987   {
01988     if (st_NewHandler())
01989          (*st_NewHandler())();
01990     else return (0);
01991   }
01992   return (p);
01993 }
01994
01995 #ifdef FORTIFY_PROVIDE_ARRAY_NEW
01996 /*
01997  * operator new[], without source-code info
01998  */
01999 void *FORTIFY_STORAGE operator new[] (size_t size)
02000 {
02001   void *p;
02002
02003   while ((p = Fortify_Allocate(size, Fortify_Allocator_array_new,
02004               0, st_AllocatorName[Fortify_Allocator_array_new], 0)) == 0)
02005   {
02006     if (st_NewHandler())
02007          (*st_NewHandler())();
02008     else return (0);
02009   }
02010   return (p);
02011 }
02012
02013 /*
02014  * operator new[], with source-code info
02015  */
02016 void *FORTIFY_STORAGE operator new[] (size_t size, const char *file, DWORD line)
02017 {
02018   void *p;
02019
02020   while ((p = Fortify_Allocate(size, Fortify_Allocator_array_new, 0, file, line)) == 0)
02021   {
02022     if (st_NewHandler())
02023          (*st_NewHandler())();
02024     else return (0);
02025   }
02026   return (p);
02027 }
02028 #endif /* FORTIFY_PROVIDE_ARRAY_NEW */
02029
02030 /*
02031  * Fortify_PreDelete - C++ does not allow overloading
02032  * of delete, so the delete macro calls Fortify_PreDelete
02033  * with the source-code info, and then calls delete.
02034  */
02035 void FORTIFY_STORAGE Fortify_PreDelete (const char *file, DWORD line)
02036 {
02037   FORTIFY_LOCK();
02038
02039   /* Push the source code info for the delete onto the delete stack
02040    * (if we have enough room, of course)
02041    */
02042   if (st_DeleteStackTop < FORTIFY_DELETE_STACK_SIZE)
02043   {
02044     st_DeleteFile[st_DeleteStackTop] = file;
02045     st_DeleteLine[st_DeleteStackTop] = line;
02046   }
02047   st_DeleteStackTop++;
02048 }
02049
02050 /*
02051  * Fortify_PostDelete() - Pop the delete source-code info
02052  * off the source stack.
02053  */
02054 void FORTIFY_STORAGE Fortify_PostDelete (void)
02055 {
02056   st_DeleteStackTop--;
02057
02058   FORTIFY_UNLOCK();
02059 }
02060
02061 /*
02062  * operator delete - fortify's replacement delete
02063  */
02064 void FORTIFY_STORAGE operator delete (void *uptr)
02065 {
02066   const char *file;
02067   DWORD line;
02068
02069   /* It is defined to be harmless to delete 0
02070    */
02071   if (uptr == 0)
02072      return;
02073
02074   /* find the source-code info
02075    */
02076   if (st_DeleteStackTop)
02077   {
02078     if (st_DeleteStackTop < FORTIFY_DELETE_STACK_SIZE)
02079     {
02080       file = st_DeleteFile[st_DeleteStackTop-1];
02081       line = st_DeleteLine[st_DeleteStackTop-1];
02082     }
02083     else
02084     {
02085       file = st_DeleteFile[FORTIFY_DELETE_STACK_SIZE-1];
02086       line = st_DeleteLine[FORTIFY_DELETE_STACK_SIZE-1];
02087     }
02088   }
02089   else
02090   {
02091     file = st_DeallocatorName[Fortify_Deallocator_delete];
02092     line = 0;
02093   }
02094   Fortify_Deallocate (uptr, Fortify_Deallocator_delete, file, line);
02095 }
02096
02097 #ifdef FORTIFY_PROVIDE_ARRAY_DELETE
02098
02099 /*
02100  * operator delete[] - fortify's replacement delete[]
02101  */
02102 void FORTIFY_STORAGE operator delete[] (void *uptr)
02103 {
02104   const char *file;
02105   DWORD line;
02106
02107   /* It is defined to be harmless to delete 0
02108    */
02109   if (uptr == 0)
02110      return;
02111
02112   /* find the source-code info
02113    */
02114   if (st_DeleteStackTop)
02115   {
02116     if (st_DeleteStackTop < FORTIFY_DELETE_STACK_SIZE)
02117     {
02118       file = st_DeleteFile[st_DeleteStackTop-1];
02119       line = st_DeleteLine[st_DeleteStackTop-1];
02120     }
02121     else
02122     {
02123       file = st_DeleteFile[FORTIFY_DELETE_STACK_SIZE-1];
02124       line = st_DeleteLine[FORTIFY_DELETE_STACK_SIZE-1];
02125     }
02126   }
02127   else
02128   {
02129     file = st_DeallocatorName[Fortify_Deallocator_array_delete];
02130     line = 0;
02131   }
02132   Fortify_Deallocate (uptr, Fortify_Deallocator_array_delete, file, line);
02133 }
02134 #endif /* FORTIFY_PROVIDE_ARRAY_DELETE */
02135
02136
02137 #ifdef FORTIFY_AUTOMATIC_LOG_FILE
02138 /*
02139  * Automatic log file stuff!
02140  *
02141  * AutoLogFile class. There can only ever be ONE of these
02142  * instantiated! It is a static class, which means that
02143  * it's constructor will be called at program initialization,
02144  * and it's destructor will be called at program termination.
02145  * We don't know if the other static class objects have been
02146  * constructed/destructed yet, but this pretty much the best
02147  * we can do with standard C++ language features.
02148  */
02149 class Fortify_AutoLogFile {
02150       static FILE *fp;
02151       static int   written_something;
02152       static char *init_string, *term_string;
02153
02154 public:
02155       Fortify_AutoLogFile (void)
02156       {
02157         written_something = 0;
02158         Fortify_SetOutputFunc (Fortify_AutoLogFile::Output);
02159         Fortify_EnterScope (init_string, 0);
02160       }
02161
02162       static void Output(const char *s)
02163       {
02164         if (written_something == 0)
02165         {
02166           FORTIFY_FIRST_ERROR_FUNCTION;
02167           fp = fopen (FORTIFY_LOG_FILENAME, "w");
02168           if (fp)
02169           {
02170             time_t t;
02171             time (&t);
02172             fprintf (fp, "Fortify log started at %s\n", ctime(&t));
02173             written_something = 1;
02174           }
02175         }
02176         if (fp)
02177         {
02178           fputs (s, fp);
02179           fflush (fp);
02180         }
02181       }
02182
02183       ~Fortify_AutoLogFile (void)
02184       {
02185         Fortify_LeaveScope (term_string, 0);
02186         Fortify_CheckAllMemory (term_string, 0);
02187         if (fp)
02188         {
02189           time_t t;
02190           time (&t);
02191           fprintf (fp, "\nFortify log closed at %s\n", ctime(&t));
02192           fclose (fp);
02193           fp = 0;
02194         }
02195       }
02196 };
02197
02198 FILE *Fortify_AutoLogFile::fp = 0;
02199 int   Fortify_AutoLogFile::written_something = 0;
02200 char *Fortify_AutoLogFile::init_string = "Program Initialization";
02201 char *Fortify_AutoLogFile::term_string = "Program Termination";
02202
02203 static Fortify_AutoLogFile Abracadabra;
02204
02205 #endif /* FORTIFY_AUTOMATIC_LOG_FILE */
02206 #endif /* __cplusplus */
02207 #endif /* USE_FORTIFY && !USE_CRTDBG */
02208
Generated on Wed Jan 25 15:42:34 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/FORTIFY.H Source File

SRC/FORTIFY.H

Go to the documentation of this file.
00001
00006 /*
00007  *   This  software  is not public domain.  All material in
00008  * this  archive  is (C) Copyright 1995 Simon P.  Bullen.  The
00009  * software  is  freely distributable, with the condition that
00010  * no   more   than  a  nominal  fee  is  charged  for  media.
00011  * Everything  in  this distribution must be kept together, in
00012  * original, unmodified form.
00013  *     The software may be modified for your own personal use,
00014  * but modified files may not be distributed.
00015  *     The  material  is  provided "as is" without warranty of
00016  * any  kind.  The author accepts no responsibility for damage
00017  * caused by this software.
00018  *     This  software  may not be used in any way by Microsoft
00019  * Corporation  or  its  subsidiaries, or current employees of
00020  * Microsoft Corporation or its subsidiaries.
00021  *     This  software  may  not  be used for the construction,
00022  * development,  production,  or  testing of weapon systems of
00023  * any kind.
00024  *     This  software  may  not  be used for the construction,
00025  * development,  production,  or  use  of plants/installations
00026  * which  include  the  processing  of radioactive/fissionable
00027  * material.
00028  */
00029
00030 /*
00031  *     If  you use this software at all, I'd love to hear from
00032  * you.   All  questions,  criticisms, suggestions, praise and
00033  * postcards are most welcome.
00034  *
00035  *            email:    sbullen@cybergraphic.com.au
00036  *
00037  *            snail:    Simon P. Bullen
00038  *                      PO BOX 12138
00039  *                      A'Beckett St.
00040  *                      Melbourne 3000
00041  *                      Australia
00042  */
00043
00044 #ifndef __FORTIFY_H__
00045 #define __FORTIFY_H__
00046
00047 #include <stdlib.h>
00048 #include <string.h>
00049
00050 #undef malloc
00051 #undef realloc
00052 #undef calloc
00053 #undef free
00054 #undef strdup
00055
00056
00057 #if (defined(_MSC_VER) && (_MSC_VER <= 600)) || defined(__CCDL__)
00058   /*
00059    * MSC <= 6.0 has a identifier length of 32. Don't bother
00060    * rewriting to supress warnings. LadSoft doesn't handle this either.
00061    */
00062   #undef USE_FORTIFY
00063 #else   /* rest of file */
00064
00065 /* the user's options */
00066 #include "ufortify.h"
00067
00068 /* Ensure the configuration parameters have sensible defaults */
00069 #ifndef FORTIFY_STORAGE
00070     #define FORTIFY_STORAGE
00071 #endif
00072
00073 #ifndef FORTIFY_ALIGNMENT
00074     #define FORTIFY_ALIGNMENT                    sizeof(double)
00075 #endif
00076
00077 #ifndef FORTIFY_BEFORE_SIZE
00078     #define FORTIFY_BEFORE_SIZE                  32
00079 #endif
00080 #ifndef FORTIFY_BEFORE_VALUE
00081     #define FORTIFY_BEFORE_VALUE                 0xA3
00082 #endif
00083
00084 #ifndef FORTIFY_AFTER_SIZE
00085     #define FORTIFY_AFTER_SIZE                   32
00086 #endif
00087
00088 #ifndef FORTIFY_AFTER_VALUE
00089     #define FORTIFY_AFTER_VALUE                  0xA5
00090 #endif
00091
00092 #ifndef FORTIFY_FILL_ON_ALLOCATE_VALUE
00093     #define FORTIFY_FILL_ON_ALLOCATE_VALUE       0xA7
00094 #endif
00095
00096 #ifndef FORTIFY_FILL_ON_DEALLOCATE_VALUE
00097     #define FORTIFY_FILL_ON_DEALLOCATE_VALUE     0xA9
00098 #endif
00099
00100 #ifndef FORTIFY_LOCK
00101     #define FORTIFY_LOCK()
00102 #endif
00103
00104 #ifndef FORTIFY_UNLOCK
00105     #define FORTIFY_UNLOCK()
00106 #endif
00107
00108 #ifndef FORTIFY_CHECKSUM_VALUE
00109     #define FORTIFY_CHECKSUM_VALUE               0x0AD0
00110 #endif
00111
00112 #ifndef FORTIFY_DELETE_STACK_SIZE
00113     #define FORTIFY_DELETE_STACK_SIZE    256
00114 #endif
00115
00116 #ifndef FORTIFY_NEW_HANDLER_FUNC
00117     typedef void (*Fortify_NewHandlerFunc)(void);
00118     #define FORTIFY_NEW_HANDLER_FUNC Fortify_NewHandlerFunc
00119 #endif
00120
00121 /*
00122  * Code to detect and configure for various compilers lives here.
00123  */
00124
00125 #ifdef __GNUG__
00126     /* GCC configuration */
00127     #define FORTIFY_PROVIDE_ARRAY_NEW
00128     #define FORTIFY_PROVIDE_ARRAY_DELETE
00129 #endif
00130
00131 #ifdef __HIGHC__
00132     /* Metaware HighC configuration */
00133     #define FORTIFY_PROVIDE_ARRAY_NEW
00134     #define FORTIFY_PROVIDE_ARRAY_DELETE
00135 #endif
00136
00137 #ifdef __BC45__
00138     /* Borland C++ 4.5 configuration */
00139     #define FORTIFY_PROVIDE_ARRAY_NEW
00140     #define FORTIFY_PROVIDE_ARRAY_DELETE
00141     #define FORTIFY_FAIL_ON_ZERO_MALLOC
00142 #endif
00143
00144 #ifdef __SASC
00145   /* SAS configuration */
00146   #define FORTIFY_FAIL_ON_ZERO_MALLOC
00147 #endif
00148
00149 /* Allocators */
00150 #define Fortify_Allocator_malloc            0    /* ANSI C   */
00151 #define Fortify_Allocator_calloc            1    /* ANSI C   */
00152 #define Fortify_Allocator_realloc           2    /* ANSI C   */
00153 #define Fortify_Allocator_strdup            3    /*      C   */
00154 #define Fortify_Allocator_new               4    /* ANSI C++ */
00155 #define Fortify_Allocator_array_new         5    /* Some C++ */
00156 #define Fortify_Allocator_GlobalAlloc       6    /* Win32    */
00157
00158 /* Deallocators */
00159 #define Fortify_Deallocator_nobody          0
00160 #define Fortify_Deallocator_free            1    /* ANSI C   */
00161 #define Fortify_Deallocator_realloc         2    /* ANSI C   */
00162 #define Fortify_Deallocator_delete          3    /* ANSI C++ */
00163 #define Fortify_Deallocator_array_delete    4    /* Some C++ */
00164 #define Fortify_Allocator_GlobalFree        5    /* Win32    */
00165
00166 /* Public Fortify Types */
00167 typedef void (*Fortify_OutputFuncPtr)(const char *);
00168
00169 #ifdef __cplusplus
00170 extern "C" {
00171 #endif
00172
00173 /* Core Fortify Functions */
00174 void         *Fortify_Allocate  (size_t size, unsigned char allocator, unsigned long flags, const char *file, unsigned long line);
00175 void          Fortify_Deallocate(void *uptr,  unsigned char deallocator, const char *file, unsigned long line);
00176 unsigned long Fortify_CheckAllMemory(const char *file, unsigned long line);
00177 unsigned long Fortify_ListAllMemory (const char *file, unsigned long line);
00178 unsigned long Fortify_DumpAllMemory (const char *file, unsigned long line);
00179 int           Fortify_CheckPointer(void *uptr, const char *file, unsigned long line);
00180 void          Fortify_LabelPointer(void *uptr, const char *label, const char *file, unsigned long line);
00181 unsigned char Fortify_EnterScope(const char *file, unsigned long line);
00182 unsigned char Fortify_LeaveScope(const char *file, unsigned long line);
00183 void          Fortify_OutputStatistics(const char *file, unsigned long line);
00184 unsigned long Fortify_GetCurrentAllocation(const char *file, unsigned long line);
00185 void          Fortify_SetAllocationLimit(unsigned long Limit, const char *file, unsigned long line);
00186 int           Fortify_SetFailRate(int Percent);
00187 void          Fortify_Disable(const char *file, unsigned long line);
00188 int           Fortify_SetAllocateFailRate (int Percent);
00189 Fortify_OutputFuncPtr Fortify_SetOutputFunc(Fortify_OutputFuncPtr Output);
00190
00191 /* Fortify versions of the ANSI C memory allocation functions */
00192 void *Fortify_malloc(size_t size, const char *file, unsigned long line);
00193 void *Fortify_realloc(void *ptr, size_t new_size, const char *file, unsigned long line);
00194 void *Fortify_calloc(size_t num, size_t size, const char *file, unsigned long line);
00195 void  Fortify_free(void *uptr, const char *file, unsigned long line);
00196
00197 /* Fortify versions of some non-ANSI C memory allocation functions */
00198 #ifdef FORTIFY_STRDUP
00199     char *Fortify_strdup(const char *oldStr, const char *file, unsigned long line);
00200 #endif
00201
00202
00203 #ifdef __cplusplus
00204     /* Magic global variable */
00205     extern int gbl_FortifyMagic;
00206     };
00207
00208     #include <new>
00209
00210     /* Fortify versions of new and delete */
00211     void *operator new(size_t size);
00212     void *operator new(size_t size, const char *file, unsigned long line);
00213     void  operator delete(void *pointer);
00214     void  Fortify_PreDelete(const char *file, unsigned long line);
00215     void  Fortify_PostDelete();
00216
00217     /* Some compilers use a different new operator for newing arrays.
00218      * This includes GNU G++ (2.6.0) and Borland C++ (4.02)
00219      */
00220     #ifdef FORTIFY_PROVIDE_ARRAY_NEW
00221         void *operator new[](size_t size);
00222         void *operator new[](size_t size, const char *file, unsigned long line);
00223     #endif
00224
00225     /* Some compilers provide a different delete operator for deleting arrays.
00226      * This incldues GNU G++ (2.6.0)
00227      */
00228     #ifdef FORTIFY_PROVIDE_ARRAY_DELETE
00229         void  operator delete[](void *pointer);
00230     #endif
00231 #endif /* __cplusplus */
00232
00233 #ifndef __FORTIFY_C__ /* Only define the macros if we're NOT in fortify.c */
00234
00235 /* Add file and line information to the fortify calls */
00236 #if defined(USE_FORTIFY)
00237     /* Core Fortify Functions */
00238     #define Fortify_CheckAllMemory()       Fortify_CheckAllMemory(__FILE__, __LINE__)
00239     #define Fortify_ListAllMemory()        Fortify_ListAllMemory (__FILE__, __LINE__)
00240     #define Fortify_DumpAllMemory()        Fortify_DumpAllMemory (__FILE__, __LINE__)
00241     #define Fortify_CheckPointer(ptr)      Fortify_CheckPointer(ptr, __FILE__, __LINE__)
00242     #define Fortify_LabelPointer(ptr,str)  Fortify_LabelPointer(ptr, str, __FILE__, __LINE__)
00243     #define Fortify_EnterScope()           Fortify_EnterScope(__FILE__, __LINE__)
00244     #define Fortify_LeaveScope()           Fortify_LeaveScope(__FILE__, __LINE__)
00245     #define Fortify_OutputStatistics()     Fortify_OutputStatistics(__FILE__, __LINE__)
00246     #define Fortify_GetCurrentAllocation() Fortify_GetCurrentAllocation(__FILE__, __LINE__)
00247     #define Fortify_SetAllocationLimit(x)  Fortify_SetAllocationLimit(x, __FILE__, __LINE__)
00248     #define Fortify_Disable()              Fortify_Disable(__FILE__, __LINE__)
00249
00250     /* Fortify versions of the ANSI C memory allocation functions */
00251     #define malloc(size)                   Fortify_malloc(size, __FILE__, __LINE__)
00252     #define realloc(ptr,new_size)          Fortify_realloc(ptr, new_size, __FILE__, __LINE__)
00253     #define calloc(num,size)               Fortify_calloc(num, size, __FILE__, __LINE__)
00254     #define free(ptr)                      Fortify_free(ptr, __FILE__, __LINE__)
00255
00256     /* Fortify versions of some non-ANSI C memory allocation functions */
00257     #ifdef FORTIFY_STRDUP
00258         #define strdup(ptr)                Fortify_strdup(ptr, __FILE__, __LINE__)
00259     #endif
00260
00261     #if (defined(_WIN32) || defined(WIN32)) && defined(FORTIFY_GLOBAL_REPLACE)
00262
00263         void *Fortify_GlobalAlloc (UINT flags, DWORD size, const char *file, DWORD line);
00264         BOOL  Fortify_GlobalFree (void *ptr, const char *file, DWORD line);
00265
00266         #undef  GlobalAllocPtr
00267         #define GlobalAllocPtr(flags, size) \
00268                                Fortify_GlobalAlloc(flags, size, __FILE__, __LINE__)
00269         #undef  GlobalFreePtr
00270         #define GlobalFreePtr(ptr) \
00271                               Fortify_GlobalFree (ptr, __FILE__, __LINE__)
00272     #endif
00273
00274     /* Fortify versions of new and delete */
00275     #ifdef __cplusplus
00276         #define Fortify_New                new(__FILE__, __LINE__)
00277         #define Fortify_Delete             for(gbl_FortifyMagic = 1, \
00278                                                Fortify_PreDelete(__FILE__, __LINE__); \
00279                                                gbl_FortifyMagic; Fortify_PostDelete()) \
00280                                                        gbl_FortifyMagic = 0, delete
00281         #define new                        Fortify_New
00282         #define delete                     Fortify_Delete
00283     #endif
00284
00285 #else /* Define the special fortify functions away to nothing */
00286
00287     #define Fortify_CheckAllMemory()       ((void)0)
00288     #define Fortify_ListAllMemory()        ((void)0)
00289     #define Fortify_DumpAllMemory()        ((void)0)
00290     #define Fortify_CheckPointer(ptr)      1
00291     #define Fortify_LabelPointer(ptr,str)  ((void)0)
00292     #define Fortify_SetOutputFunc(func)    ((void)0)
00293     #define Fortify_SetMallocFailRate(p)   ((void)0)
00294     #define Fortify_EnterScope()           ((void)0)
00295     #define Fortify_LeaveScope()           ((void)0)
00296     #define Fortify_OutputStatistics()     ((void)0)
00297     #define Fortify_GetCurrentAllocation() ((void)0)
00298     #define Fortify_SetAllocationLimit(x)  ((void)0)
00299     #define Fortify_Disable()              ((void)0)
00300
00301     #ifdef __cplusplus
00302         #define Fortify_New                    new
00303         #define Fortify_Delete                 delete
00304     #endif
00305
00306 #endif /* USE_FORTIFY */
00307 #endif /* __FORTIFY_C__ */
00308 #endif /* __FORTIFY_H__ */
00309 #endif /* _MSC_VER <= 6.0 || __CCDL__ */
Generated on Wed Jan 25 15:42:34 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/FSEXT.C Source File

SRC/FSEXT.C

Go to the documentation of this file.
00001
00005 /*  BSD sockets functionality for Waterloo TCP/IP
00006  *
00007  *  Copyright (c) 1997-2002 Gisle Vanem <giva@bgnett.no>
00008  *
00009  *  Redistribution and use in source and binary forms, with or without
00010  *  modification, are permitted provided that the following conditions
00011  *  are met:
00012  *  1. Redistributions of source code must retain the above copyright
00013  *     notice, this list of conditions and the following disclaimer.
00014  *  2. Redistributions in binary form must reproduce the above copyright
00015  *     notice, this list of conditions and the following disclaimer in the
00016  *     documentation and/or other materials provided with the distribution.
00017  *  3. All advertising materials mentioning features or use of this software
00018  *     must display the following acknowledgement:
00019  *       This product includes software developed by Gisle Vanem
00020  *       Bergen, Norway.
00021  *
00022  *  THIS SOFTWARE IS PROVIDED BY ME (Gisle Vanem) AND CONTRIBUTORS ``AS IS''
00023  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00024  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00025  *  ARE DISCLAIMED.  IN NO EVENT SHALL I OR CONTRIBUTORS BE LIABLE FOR ANY
00026  *  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00027  *  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00028  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00029  *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00030  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00031  *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00032  *
00033  *  Version
00034  *
00035  *  0.5 : Jan 21, 1998 : G. Vanem - created
00036  *  0.6 : Apr 28, 2003 : G. Vanem - updates for djgpp 2.04
00037  */
00038
00039 #include "socket.h"
00040
00041 #if defined(__DJGPP__) && defined(USE_BSD_API) && defined(USE_FSEXT)
00042
00043 #include <sys/fsext.h>
00044 #include <sys/stat.h>
00045 #include <fcntl.h>
00046 #include <unistd.h>
00047
00048 #define S_IFSOCK 0x10000
00049
00050 #if (DJGPP_MINOR < 4)
00051 #define blksize_t off_t
00052 #endif
00053
00054 struct wstat {
00055        time_t    st_atime;
00056        time_t    st_ctime;
00057        dev_t     st_dev;
00058        gid_t     st_gid;
00059        ino_t     st_ino;
00060        mode_t    st_mode;
00061        time_t    st_mtime;
00062        nlink_t   st_nlink;
00063        off_t     st_size;
00064        blksize_t st_blksize;
00065        uid_t     st_uid;
00066        dev_t     st_rdev;
00067      };
00068
00069
00070 #if defined(USE_DEBUG)
00071 /*
00072  * Handle printing of function names
00073  */
00074 static struct search_list fs_func[] = {
00075                       { __FSEXT_nop,   "nop"    },
00076                       { __FSEXT_open,  "open"   },
00077                       { __FSEXT_creat, "creat"  },
00078                       { __FSEXT_read,  "read"   },
00079                       { __FSEXT_write, "write"  },
00080                       { __FSEXT_ready, "ready"  },
00081                       { __FSEXT_close, "close"  },
00082                       { __FSEXT_fcntl, "fcntl"  },
00083                       { __FSEXT_ioctl, "ioctl"  },
00084                       { __FSEXT_lseek, "lseek"  },
00085                       { __FSEXT_link,  "link"   },
00086                       { __FSEXT_unlink,"unlink" },
00087 #if (DJGPP_MINOR >= 2)
00088                       { __FSEXT_dup,   "dup"    },
00089                       { __FSEXT_dup2,  "dup2"   },
00090                       { __FSEXT_fstat, "fstat"  },
00091                       { __FSEXT_stat,  "stat"   },
00092 #endif
00093 #if (DJGPP_MINOR >= 4)
00094                       { __FSEXT_llseek,  "llseek"   },
00095                       { __FSEXT_readlink,"readlink" },
00096                       { __FSEXT_symlink, "symlink"  },
00097                       { __FSEXT_fchown,  "fchown"   },
00098                       { __FSEXT_chmod,   "chmod",   },
00099                       { __FSEXT_chown,   "chown",   },
00100                       { __FSEXT_fchmod,  "fchmod"   }
00101 #endif
00102                     };
00103 #endif /* USE_DEBUG */
00104
00105 /*
00106  * Filesystem extensions for BSD-sockets and djgpp 2.x
00107  */
00108 int _fsext_demux (__FSEXT_Fnumber func, int *rv, va_list _args)
00109 {
00110   int     fd   = va_arg (_args, int);
00111   int     cmd  = va_arg (_args, int);
00112   int     arg  = va_arg (_args, int);
00113   Socket *sock = __FSEXT_get_data (fd); /* same as _socklist_find(fd) */
00114
00115   SOCK_DEBUGF (("\n_fsext_demux: fd %d%c, func %d = \"%s\", cmd %08lX, arg %08lX",
00116                 fd, sock ? 's' : 'f', func,
00117                 list_lookup (func, fs_func, DIM(fs_func)),
00118                 (DWORD)cmd, (DWORD)arg));
00119
00120   /* fd is not a valid socket, pass on to lower layer
00121    */
00122   if (!sock)
00123      return (0);
00124
00125   switch (func)
00126   {
00127     case __FSEXT_read:                        /* read (fd,&buf,len) */
00128          *rv = read_s (fd, (char*)cmd, arg);
00129          return (1);
00130
00131     case __FSEXT_write:                       /* write (fd,&buf,len) */
00132          *rv = write_s (fd, (char*)cmd, arg);
00133          return (1);
00134
00135     case __FSEXT_close:                       /* close (fd) */
00136          if (sock->fd_duped == 0)
00137             *rv = close_s (fd);
00138          else
00139          {
00140            sock->fd_duped--;
00141            *rv = 0;
00142          }
00143          return (1);
00144
00145     case __FSEXT_ioctl:   /* ioctl (fd,cmd,...) */
00146          *rv = ioctlsocket (fd, cmd, (char*)arg);
00147          return (1);
00148
00149     case __FSEXT_fcntl:   /* 'fcntl (fd,cmd)' or 'fcntl (fd,cmd,arg)' */
00150          *rv = fcntlsocket (fd, cmd, (long)arg);
00151          return (1);
00152
00153     case __FSEXT_ready:   /* ready (fd) called from select() */
00154          {
00155            struct  timeval tv;
00156            fd_set  fd_read, fd_write, fd_err;
00157
00158            FD_ZERO (&fd_read);
00159            FD_ZERO (&fd_write);
00160            FD_ZERO (&fd_err);
00161            FD_SET (fd, &fd_read);
00162            FD_SET (fd, &fd_write);
00163            FD_SET (fd, &fd_err);
00164            tv.tv_sec  = 0;
00165            tv.tv_usec = 0L;
00166            *rv = 0;
00167
00168            if (select_s (fd+1, &fd_read, &fd_write, &fd_err, &tv) >= 0)
00169            {
00170              if (FD_ISSET(fd,&fd_read))
00171                 *rv |= __FSEXT_ready_read;
00172              if (FD_ISSET(fd,&fd_write))
00173                 *rv |= __FSEXT_ready_write;
00174              if (FD_ISSET(fd,&fd_err))
00175                 *rv |= __FSEXT_ready_error;
00176            }
00177            else
00178              *rv = -1;
00179          }
00180          return (1);
00181
00182     case __FSEXT_creat:
00183          return (0);
00184
00185 #if (DJGPP_MINOR >= 2)    /* functions added in v2.02 */
00186     case __FSEXT_dup:     /* dup (fd) */
00187          *rv = fd;
00188          if (sock->fd_duped < UINT_MAX)
00189             sock->fd_duped++;
00190          return (1);
00191
00192     case __FSEXT_dup2:    /* dup2 (oldfd,newfd) */
00193          {
00194            int family = sock->so_family;
00195            int type   = sock->so_type;
00196            int proto  = sock->so_proto;
00197
00198            close (cmd);   /* close (newd) */
00199            *rv = socket (family, type, proto);
00200          }
00201          return (1);
00202
00203     case __FSEXT_fstat:
00204 #if defined(USE_STATISTICS)
00205          {
00206            struct wstat *stat = (struct wstat*) cmd;
00207            int    size;
00208
00209            *rv = 0;
00210            stat->st_mode = S_IFSOCK;
00211
00212            /* Hmm. If user really want this, lets return it */
00213            switch (sock->so_proto)
00214            {
00215              case IPPROTO_TCP:
00216                   size = min (sizeof(tcpstats), sizeof(struct stat));
00217                   memcpy (rv, &tcpstats, size);
00218                   break;
00219              case IPPROTO_UDP:
00220                   size = min (sizeof(udpstats), sizeof(struct stat));
00221                   memcpy (rv, &udpstats, size);
00222                   break;
00223              case IPPROTO_ICMP:
00224                   size = min (sizeof(icmpstats), sizeof(struct stat));
00225                   memcpy (rv, &icmpstats, size);
00226                   break;
00227              case IPPROTO_IGMP:
00228                   size = min (sizeof(igmpstats), sizeof(struct stat));
00229                   memcpy (rv, &igmpstats, size);
00230                   break;
00231              case IPPROTO_IP:
00232                   size = min (sizeof(ip4stats), sizeof(struct stat));
00233                   memcpy (rv, &ip4stats, size);
00234                   break;
00235 #if defined(IPPROTO_IP6)
00236              case IPPROTO_IP6:
00237                   size = min (sizeof(ip6stats), sizeof(struct stat));
00238                   memcpy (rv, &ip6stats, size);
00239                   break;
00240 #endif
00241              default:
00242                  *rv = -1;
00243            }
00244          }
00245          return (1);
00246 #else
00247          return (0);
00248 #endif  /* USE_STATISTICS */
00249
00250 #endif  /* DJGPP_MINOR >= 2 */
00251
00252     default:
00253          SOCK_DEBUGF ((" unhandled FSext function"));
00254          break;
00255   }
00256   return (0);    /* unhandled, pass on to lower layer */
00257 }
00258
00259 #endif /* __DJGPP__ && USE_BSD_API && USE_FSEXT */
00260
Generated on Wed Jan 25 15:42:34 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/GET_AI.C Source File

SRC/GET_AI.C

Go to the documentation of this file.
00001
00005 /* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
00006  * All rights reserved.
00007  *
00008  * Redistribution and use in source and binary forms, with or without
00009  * modification, are permitted provided that the following conditions
00010  * are met:
00011  * 1. Redistributions of source code must retain the above copyright
00012  *    notice, this list of conditions and the following disclaimer.
00013  * 2. Redistributions in binary form must reproduce the above copyright
00014  *    notice, this list of conditions and the following disclaimer in the
00015  *    documentation and/or other materials provided with the distribution.
00016  * 3. Neither the name of the project nor the names of its contributors
00017  *    may be used to endorse or promote products derived from this software
00018  *    without specific prior written permission.
00019  *
00020  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
00021  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00022  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00023  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
00024  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00025  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00026  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00027  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00028  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00029  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00030  * SUCH DAMAGE.
00031  */
00032
00033 /*
00034  * "FAITH" part is local hack for supporting IPv4-v6 translator.
00035  *
00036  * Issues to be discussed:
00037  * - Thread safe-ness must be checked.
00038  * - Return values.  There are nonstandard return values defined and used
00039  *   in the source code. This is because RFC2553 is silent about which error
00040  *   code must be returned for which situation.
00041  * Note:
00042  * - The code filters out AFs that are not supported by the kernel,
00043  *   when globbing NULL hostname (to loopback, or wildcard). Is it the right
00044  *   thing to do? What is the relationship with post-RFC2553 AI_ADDRCONFIG
00045  *   in ai_flags?
00046  *
00047  * Adapted for Watt-32 tcp/ip stack by G. Vanem <giva@bgnett.no>, Aug 2002.
00048  */
00049
00050 #if 0
00051 static const char rcsid[] = "@(#) $Header: /tcpdump/master/tcpdump/missing/"
00052                             "getaddrinfo.c,v 1.10 2000/10/24 00:56:53 fenner Exp $";
00053 #endif
00054
00055 #include "socket.h"
00056 #include "udp_dom.h"
00057
00058 #if defined(USE_BSD_API)
00059
00060 #define ANY       0
00061 #define YES       1
00062 #define NO        0
00063 #define PTON_MAX  16
00064
00065 /* Addresss family descriptor
00066  */
00067 struct afd {
00068        int         a_af;
00069        int         a_addrlen;
00070        int         a_socklen;
00071        int         a_off;
00072        const char *a_addrany;
00073        const char *a_loopback;
00074        int         a_scoped;
00075      };
00076
00077 struct explore {
00078        int         e_af;
00079        int         e_socktype;
00080        int         e_protocol;
00081        const char *e_protostr;
00082        int         e_wild;
00083 #define WILD_AF(ex)        ((ex)->e_wild & 0x01)
00084 #define WILD_SOCKTYPE(ex)  ((ex)->e_wild & 0x02)
00085 #define WILD_PROTOCOL(ex)  ((ex)->e_wild & 0x04)
00086       };
00087
00088 static struct explore explore[] = {
00089      { AF_INET6, SOCK_DGRAM,  IPPROTO_UDP, "udp", 7 },
00090      { AF_INET6, SOCK_STREAM, IPPROTO_TCP, "tcp", 7 },
00091      { AF_INET6, SOCK_RAW,    ANY,         NULL,  5 },
00092      { AF_INET,  SOCK_DGRAM,  IPPROTO_UDP, "udp", 7 },
00093      { AF_INET,  SOCK_STREAM, IPPROTO_TCP, "tcp", 7 },
00094      { AF_INET,  SOCK_RAW,    ANY,         NULL,  5 },
00095      { -1,       0,           0,           NULL,  0 }
00096    };
00097
00098 BOOL called_from_getai = FALSE;
00099
00100 static struct afd afd_list [3];
00101
00102 static int str_isnumber (const char *);
00103 static int explore_fqdn (const struct addrinfo *, const char *, const char *,
00104                          struct addrinfo **res);
00105
00106 static int explore_null (const struct addrinfo *, const char *,
00107                          struct addrinfo **);
00108
00109 static int explore_numeric (const struct addrinfo *, const char *, const char *,
00110                             struct addrinfo **);
00111
00112 static int explore_numeric_scope (const struct addrinfo *, const char *,
00113                                   const char *, struct addrinfo **);
00114
00115 static int get_name (const char *, const struct afd *, struct addrinfo **,
00116                      char *, const struct addrinfo *, const char *);
00117
00118 static int get_canonname (const struct addrinfo *, struct addrinfo *,
00119                           const char *);
00120
00121 static struct addrinfo *get_ai (const struct addrinfo *, const struct afd *,
00122                                 const char *);
00123
00124 static int get_portmatch (const struct addrinfo *, const char *);
00125 static int get_port (struct addrinfo *, const char *, int);
00126 static const struct afd *find_afd (int);
00127
00128 static char *ai_errlist[] = {
00129   "Success",
00130   "Address family for hostname not supported",    /* EAI_ADDRFAMILY */
00131   "Temporary failure in name resolution",         /* EAI_AGAIN      */
00132   "Invalid value for ai_flags",                   /* EAI_BADFLAGS   */
00133   "Non-recoverable failure in name resolution",   /* EAI_FAIL       */
00134   "ai_family not supported",                      /* EAI_FAMILY     */
00135   "Memory allocation failure",                    /* EAI_MEMORY     */
00136   "No address associated with hostname",          /* EAI_NODATA     */
00137   "hostname nor servname provided, or not known", /* EAI_NONAME     */
00138   "servname not supported for ai_socktype",       /* EAI_SERVICE    */
00139   "ai_socktype not supported",                    /* EAI_SOCKTYPE   */
00140   "System error returned in errno",               /* EAI_SYSTEM     */
00141   "Invalid value for hints",                      /* EAI_BADHINTS   */
00142   "Resolved protocol is unknown",                 /* EAI_PROTOCOL   */
00143   "Unknown error",                                /* EAI_MAX        */
00144 };
00145
00146 /* XXX macros that make external reference is BAD. */
00147
00148 #define GET_AI(ai, afd, addr) do {                       \
00149         /* external reference: pai, error and free_it */ \
00150         (ai) = get_ai (pai, (afd), (addr));              \
00151         if ((ai) == NULL) {                              \
00152            error = EAI_MEMORY;                           \
00153            goto free_it;                                 \
00154         }                                                \
00155       } while (0)
00156
00157 #define GET_PORT(ai, serv) do {                          \
00158         /* external reference: error and free_it */      \
00159         error = get_port ((ai), (serv), 0);              \
00160         if (error != 0)                                  \
00161            goto free_it;                                 \
00162       } while (0)
00163
00164 #define GET_CANONNAME(ai, str) do {                      \
00165         /* external reference: pai, error and free_it */ \
00166         error = get_canonname (pai, (ai), (str));        \
00167         if (error != 0)                                  \
00168            goto free_it;                                 \
00169       } while (0)
00170
00171 #define ERR(err) do {                                    \
00172         /* external reference: error, and label bad */   \
00173         error = (err);                                   \
00174         goto bad;                                        \
00175       } while (0)
00176
00177 #define MATCH_FAMILY(x, y, w) \
00178         ((x) == (y) || ((w) && ((x) == AF_UNSPEC || (y) == AF_UNSPEC)))
00179
00180 #define MATCH(x, y, w) \
00181         ((x) == (y) || ((w) && ((x) == ANY || (y) == ANY)))
00182
00183 char * W32_CALL gai_strerror (int ecode)
00184 {
00185   if (ecode < 0 || ecode > EAI_MAX)
00186      ecode = EAI_MAX;
00187   return (ai_errlist[ecode]);
00188 }
00189
00190 /*
00191  * We only have 1 interface.
00192  * Size of 'if_name' must be >= IF_NAMESIZE.
00193  * Assume __get_ifname() returns name with trailing digit.
00194  */
00195 int W32_CALL if_nametoindex (const char *if_name)
00196 {
00197   char name [IF_NAMESIZE];
00198   char id;
00199
00200   __get_ifname (name);
00201   id = name [strlen(name)] - '0';
00202   if (!stricmp(if_name,name))
00203      return (id+1);
00204   return (0);
00205 }
00206
00207 char * W32_CALL if_indextoname (int if_id, char *if_name)
00208 {
00209   char name [IF_NAMESIZE];
00210   int  id;
00211
00212   __get_ifname (name);
00213   id = name [strlen(name)] - '0';
00214   if (if_id != id+1)
00215   {
00216     SOCK_ERRNO (ENXIO);
00217     return (NULL);
00218   }
00219   return strcpy (if_name, name);
00220 }
00221
00222 int __scope_ascii_to_id (const char *str)
00223 {
00224   if (!isdigit(*str))
00225      return (0);
00226   return (*str - '0');
00227 }
00228
00229 int __scope_id_to_ascii (int scope)
00230 {
00231   scope += '0';
00232   if (!isdigit(scope))
00233      return (0);
00234   return (scope);
00235 }
00236
00237 static void free_addrinfo (struct addrinfo *ai)
00238 {
00239   struct addrinfo *next;
00240
00241   for ( ; ai; ai = next)
00242   {
00243     next = ai->ai_next;
00244     if (ai->ai_canonname)
00245        free (ai->ai_canonname);
00246     free (ai);
00247   }
00248 }
00249
00250 void W32_CALL freeaddrinfo (struct addrinfo *ai)
00251 {
00252   SOCK_DEBUGF (("\nfreeaddrinfo: %08lX", (DWORD)ai));
00253   free_addrinfo (ai);
00254 }
00255
00256 static int str_isnumber (const char *p)
00257 {
00258   char *q = (char *) p;
00259
00260   while (*q)
00261   {
00262     if (!isdigit((int)*q))
00263        return (NO);
00264     q++;
00265   }
00266   return (YES);
00267 }
00268
00273 static void afd_list_init (BOOL ip6_prio)
00274 {
00275   static const char in4addr_loopback[] = { 127, 0, 0, 1 };
00276   static const char in4addr_addrany[]  = { 0, 0, 0, 0 };
00277 #if !defined(USE_IPV6)
00278   static const struct in6_addr in6addr_loopback = {{ 0,0,0,0,0,0,0,0,
00279                                                      0,0,0,0,0,0,0,1 }};
00280   static const struct in6_addr in6addr_any      = {{ 0,0,0,0,0,0,0,0,
00281                                                      0,0,0,0,0,0,0,0 }};
00282 #endif
00283
00284
00285   int    i = (ip6_prio ? 0 : 1);
00286
00287   memset (&afd_list, 0, sizeof(afd_list));
00288
00289   afd_list[i].a_af       = AF_INET6;
00290   afd_list[i].a_addrlen  = sizeof (struct in6_addr);
00291   afd_list[i].a_socklen  = sizeof (struct sockaddr_in6);
00292   afd_list[i].a_off      = offsetof (struct sockaddr_in6, sin6_addr);
00293   afd_list[i].a_addrany  = (const char*) &in6addr_any;
00294   afd_list[i].a_loopback = (const char*) &in6addr_loopback;
00295   afd_list[i].a_scoped   = 1;
00296
00297   i ^= 1;
00298   afd_list[i].a_af       = AF_INET;
00299   afd_list[i].a_addrlen  = sizeof (struct in_addr);
00300   afd_list[i].a_socklen  = sizeof (struct sockaddr_in);
00301   afd_list[i].a_off      = offsetof (struct sockaddr_in, sin_addr);
00302   afd_list[i].a_addrany  = in4addr_addrany;
00303   afd_list[i].a_loopback = in4addr_loopback;
00304   afd_list[i].a_scoped   = 0;
00305
00306   if (!ip6_prio)
00307   {
00308     explore[0].e_af = explore[1].e_af = explore[2].e_af = AF_INET;
00309     explore[3].e_af = explore[4].e_af = explore[5].e_af = AF_INET6;
00310   }
00311 }
00312
00313 int W32_CALL getaddrinfo (const char *hostname, const char *servname,
00314                           const struct addrinfo *hints, struct addrinfo **res)
00315 {
00316   static BOOL init = FALSE;
00317   struct addrinfo      *cur, *pai, ai, ai0, sentinel;
00318   const struct afd     *afd;
00319   const struct explore *ex;
00320   int   error = 0;
00321
00322   if (!init)
00323      afd_list_init (TRUE);  /* Give IPv6 highest priority */
00324   init = TRUE;
00325
00326   sentinel.ai_next = NULL;
00327   cur = &sentinel;
00328   pai = &ai;
00329   pai->ai_flags     = 0;
00330   pai->ai_family    = AF_UNSPEC;
00331   pai->ai_socktype  = ANY;
00332   pai->ai_protocol  = ANY;
00333   pai->ai_addrlen   = 0;
00334   pai->ai_canonname = NULL;
00335   pai->ai_addr      = NULL;
00336   pai->ai_next      = NULL;
00337
00338   SOCK_DEBUGF (("\ngetaddrinfo: `%s', `%s'",
00339                 hostname, servname));
00340
00341   if (!hostname && !servname)
00342      ERR (EAI_NONAME);
00343
00344   if (hints)
00345   {
00346     /* error check for hints */
00347     if (hints->ai_addrlen || hints->ai_canonname ||
00348         hints->ai_addr    || hints->ai_next)
00349        ERR (EAI_BADHINTS);       /* xxx */
00350
00351     if (hints->ai_flags & ~AI_MASK)
00352        ERR (EAI_BADFLAGS);
00353
00354     switch (hints->ai_family)
00355     {
00356       case AF_UNSPEC:
00357       case AF_INET:
00358       case AF_INET6:
00359            break;
00360       default:
00361            ERR (EAI_FAMILY);
00362     }
00363     *pai = *hints;
00364
00365     /* if both socktype/protocol are specified, check if they
00366      * are meaningful combination.
00367      */
00368     if (pai->ai_socktype != ANY && pai->ai_protocol != ANY)
00369     {
00370       for (ex = explore; ex->e_af >= 0; ex++)
00371       {
00372         if (pai->ai_family != ex->e_af ||
00373             ex->e_socktype == ANY ||
00374             ex->e_protocol == ANY)
00375            continue;
00376
00377         if (pai->ai_socktype == ex->e_socktype &&
00378             pai->ai_protocol != ex->e_protocol)
00379            ERR (EAI_BADHINTS);
00380       }
00381     }
00382   }
00383
00384   /* Check for special cases:
00385    *  (1) numeric servname is disallowed if socktype/protocol are left
00386    *      unspecified.
00387    *  (2) servname is disallowed for raw and other inet{,6} sockets.
00388    */
00389   if (MATCH_FAMILY (pai->ai_family, AF_INET, 1) ||
00390       MATCH_FAMILY (pai->ai_family, AF_INET6, 1))
00391   {
00392     ai0 = *pai;
00393
00394     if (pai->ai_family == AF_UNSPEC)
00395         pai->ai_family = AF_INET6;
00396     error = get_portmatch (pai, servname);
00397     if (error)
00398        ERR (error);
00399     *pai = ai0;
00400   }
00401
00402   ai0 = *pai;
00403
00404   /* NULL hostname, or numeric hostname
00405    */
00406   for (ex = explore; ex->e_af >= 0; ex++)
00407   {
00408     *pai = ai0;
00409
00410     if (!MATCH_FAMILY(pai->ai_family, ex->e_af, WILD_AF(ex)))
00411        continue;
00412     if (!MATCH(pai->ai_socktype, ex->e_socktype, WILD_SOCKTYPE(ex)))
00413        continue;
00414     if (!MATCH(pai->ai_protocol, ex->e_protocol, WILD_PROTOCOL(ex)))
00415        continue;
00416
00417     if (pai->ai_family == AF_UNSPEC)
00418         pai->ai_family = ex->e_af;
00419     if (pai->ai_socktype == ANY && ex->e_socktype != ANY)
00420         pai->ai_socktype = ex->e_socktype;
00421     if (pai->ai_protocol == ANY && ex->e_protocol != ANY)
00422         pai->ai_protocol = ex->e_protocol;
00423
00424     if (!hostname)
00425          error = explore_null (pai, servname, &cur->ai_next);
00426     else error = explore_numeric_scope (pai, hostname, servname, &cur->ai_next);
00427
00428     if (error)
00429        goto free_it;
00430
00431     while (cur && cur->ai_next)
00432       cur = cur->ai_next;
00433   }
00434
00435   /* If numeric representation of AF1 can be interpreted as FQDN
00436    * representation of AF2, we need to think again about the code below.
00437    */
00438   if (sentinel.ai_next)
00439      goto good;
00440
00441   if (pai->ai_flags & AI_NUMERICHOST)
00442      ERR (EAI_NONAME);
00443
00444   if (!hostname)
00445      ERR (EAI_NONAME);
00446
00447   /* hostname as alphabetical name.
00448    * we would like to prefer AF_INET6 than AF_INET, so we'll make a
00449    * outer loop by AFs.
00450    */
00451   for (afd = afd_list; afd->a_af; afd++)
00452   {
00453     *pai = ai0;
00454
00455     if (!MATCH_FAMILY (pai->ai_family, afd->a_af, 1))
00456        continue;
00457
00458     for (ex = explore; ex->e_af >= 0; ex++)
00459     {
00460       *pai = ai0;
00461
00462       if (pai->ai_family == AF_UNSPEC)
00463           pai->ai_family = afd->a_af;
00464
00465       if (!MATCH_FAMILY (pai->ai_family, ex->e_af, WILD_AF(ex)))
00466          continue;
00467
00468       if (!MATCH (pai->ai_socktype, ex->e_socktype, WILD_SOCKTYPE(ex)))
00469          continue;
00470
00471       if (!MATCH (pai->ai_protocol, ex->e_protocol, WILD_PROTOCOL(ex)))
00472          continue;
00473
00474       if (pai->ai_family == AF_UNSPEC)
00475           pai->ai_family = ex->e_af;
00476       if (pai->ai_socktype == ANY && ex->e_socktype != ANY)
00477           pai->ai_socktype = ex->e_socktype;
00478       if (pai->ai_protocol == ANY && ex->e_protocol != ANY)
00479           pai->ai_protocol = ex->e_protocol;
00480
00481       error = explore_fqdn (pai, hostname, servname, &cur->ai_next);
00482
00483       if (_resolve_exit)  /* interrupted or other fail */
00484       {
00485         error = EAI_MAX;
00486         goto free_it;
00487       }
00488       while (cur && cur->ai_next)
00489         cur = cur->ai_next;
00490     }
00491   }
00492
00493 good:
00494   if (sentinel.ai_next)
00495      error = 0;
00496
00497   if (error == 0)
00498   {
00499     if (sentinel.ai_next)
00500     {
00501       if (res)
00502          *res = sentinel.ai_next;
00503       // dump_addrinfo (*res);
00504       return (0);   /* success */
00505     }
00506     error = EAI_FAIL;
00507   }
00508
00509 free_it:
00510 bad:
00511   free_addrinfo (sentinel.ai_next);
00512   if (res)
00513      *res = NULL;
00514   SOCK_DEBUGF ((": %s", ai_errlist[error]));
00515   return (error);
00516 }
00517
00518 /*
00519  * FQDN hostname, DNS lookup
00520  */
00521 static int explore_fqdn (const struct addrinfo *pai, const char *hostname,
00522                          const char *servname, struct addrinfo **res)
00523 {
00524   const struct afd *afd;
00525   struct hostent   *hp;
00526   struct addrinfo sentinel, *cur;
00527   int    error, af, i;
00528   char  *ap;
00529
00530 #ifdef TEST_PROG
00531   SOCK_DEBUGF (("\nexplore_fqdn"));
00532 #endif
00533
00534   error = 0;
00535   *res = NULL;
00536   cur  = &sentinel;
00537   sentinel.ai_next = NULL;
00538
00539   /* Do not filter unsupported AFs here. We need to honor content of
00540    * databases (/etc/hosts, DNS and others). Otherwise we cannot
00541    * replace gethostbyname() by getaddrinfo().
00542    */
00543
00544   /* if the servname does not match socktype/protocol, ignore it.
00545    */
00546   if (get_portmatch (pai, servname) != 0)
00547      return (0);
00548
00549   afd = find_afd (pai->ai_family);
00550
00551   /* Post-RFC2553: should look at (pai->ai_flags & AI_ADDRCONFIG)
00552    * rather than hardcoding it. We may need to add AI_ADDRCONFIG
00553    * handling code by ourselves.
00554    */
00555   SOCK_ENTER_SCOPE();
00556   hp = gethostbyname2 (hostname, pai->ai_family);
00557   SOCK_LEAVE_SCOPE();
00558
00559   if (!hp)
00560   {
00561     switch (h_errno)
00562     {
00563       case HOST_NOT_FOUND:
00564       case NO_DATA:
00565            error = EAI_NODATA;
00566            break;
00567       case TRY_AGAIN:
00568            error = EAI_AGAIN;
00569            break;
00570       case NO_RECOVERY:
00571       case NETDB_INTERNAL:
00572       default:
00573            error = EAI_FAIL;
00574            break;
00575     }
00576
00577   }
00578   else if (!hp->h_name || !hp->h_name[0] || !hp->h_addr_list[0])
00579   {
00580     hp = NULL;
00581     error = EAI_FAIL;
00582   }
00583
00584   if (!hp)
00585      goto free_it;
00586
00587   /* Perform a shallow copy of 'hp'. Since 'hp' is returned from
00588    * fill_hostent(), the contents will be destroyed in below
00589    * get_name() otherwise.
00590    */
00591   {
00592     struct hostent copy;
00593     struct in6_addr addr [MAX_ADDRESSES+1];
00594     char           *list [MAX_ADDRESSES+1];
00595
00596     copy = *hp;
00597     memset (&addr, 0, sizeof(addr));
00598     memset (&list, 0, sizeof(list));
00599     for (i = 0; hp->h_addr_list[i]; i++)
00600     {
00601       memcpy (&addr[i], hp->h_addr_list[i], hp->h_length);
00602       list[i] = (char*) &addr[i];
00603     }
00604     list[i]          = NULL;
00605     copy.h_addr_list = list;
00606     hp = &copy;
00607   }
00608
00609   for (i = 0; hp->h_addr_list[i]; i++)
00610   {
00611     af = hp->h_addrtype;
00612     ap = hp->h_addr_list[i];
00613     if (af == AF_INET6 && IN6_IS_ADDR_V4MAPPED(ap))
00614     {
00615       af = AF_INET;
00616       ap += sizeof(struct in6_addr) - sizeof(struct in_addr);
00617     }
00618
00619     if (af != pai->ai_family)
00620        continue;
00621
00622     if (!(pai->ai_flags & AI_CANONNAME))
00623     {
00624       GET_AI (cur->ai_next, afd, ap);
00625       GET_PORT (cur->ai_next, servname);
00626     }
00627     else
00628     {
00629       /* if AI_CANONNAME and if reverse lookup fail, return ai anyway
00630        * to pacify calling application.
00631        *
00632        * XXX getaddrinfo() is a name to address translation function,
00633        * and it looks strange that we do addr to name translation here.
00634        */
00635       get_name (ap, afd, &cur->ai_next, ap, pai, servname);
00636     }
00637     while (cur && cur->ai_next)
00638       cur = cur->ai_next;
00639   }
00640   *res = sentinel.ai_next;
00641   return (0);
00642
00643 free_it:
00644   free_addrinfo (sentinel.ai_next);
00645   return (error);
00646 }
00647
00648 /*
00649  * hostname == NULL.
00650  * passive socket -> anyaddr (0.0.0.0 or ::)
00651  * non-passive socket -> localhost (127.0.0.1 or ::1)
00652  */
00653 static int explore_null (const struct addrinfo *pai, const char *servname,
00654                          struct addrinfo **res)
00655 {
00656   const struct afd *afd;
00657   struct addrinfo  *cur, sentinel;
00658   int    s, error;
00659
00660 #ifdef TEST_PROG
00661   SOCK_DEBUGF (("\nexplore_null"));
00662 #endif
00663
00664   *res = NULL;
00665   sentinel.ai_next = NULL;
00666   cur = &sentinel;
00667
00668   /* filter out AFs that are not supported
00669    */
00670   SOCK_ENTER_SCOPE();
00671   s = socket (pai->ai_family, SOCK_DGRAM, 0);
00672   if (s >= 0)
00673      close_s (s);
00674   SOCK_LEAVE_SCOPE();
00675
00676   if (s < 0)
00677      return (0);
00678
00679   /* if the servname does not match socktype/protocol, ignore it.
00680    */
00681   if (get_portmatch (pai, servname) != 0)
00682      return (0);
00683
00684   afd = find_afd (pai->ai_family);
00685
00686   if (pai->ai_flags & AI_PASSIVE)
00687   {
00688     GET_AI (cur->ai_next, afd, afd->a_addrany);
00689     /* xxx meaningless?
00690      * GET_CANONNAME(cur->ai_next, "anyaddr");
00691      */
00692     GET_PORT (cur->ai_next, servname);
00693   }
00694   else
00695   {
00696     GET_AI (cur->ai_next, afd, afd->a_loopback);
00697     /* xxx meaningless?
00698      * GET_CANONNAME(cur->ai_next, "localhost");
00699      */
00700     GET_PORT (cur->ai_next, servname);
00701   }
00702
00703   *res = sentinel.ai_next;
00704   return (0);
00705
00706 free_it:
00707   free_addrinfo (sentinel.ai_next);
00708   return (error);
00709 }
00710
00711 /*
00712  * numeric hostname
00713  */
00714 static int explore_numeric (const struct addrinfo *pai, const char *hostname,
00715                             const char *servname, struct addrinfo **res)
00716 {
00717   const struct afd *afd;
00718   struct addrinfo  *cur, sentinel;
00719   char   pton [PTON_MAX];
00720   int    error, flags;
00721
00722 #ifdef TEST_PROG
00723   SOCK_DEBUGF (("\nexplore_numeric"));
00724 #endif
00725
00726   *res = NULL;
00727   sentinel.ai_next = NULL;
00728   cur = &sentinel;
00729
00730   /* if the servname does not match socktype/protocol, ignore it.
00731    */
00732   if (get_portmatch (pai, servname) != 0)
00733      return (0);
00734
00735   afd   = find_afd (pai->ai_family);
00736   flags = pai->ai_flags;
00737
00738   if (inet_pton (afd->a_af, hostname, pton) == 1)
00739   {
00740     DWORD v4a;
00741     BYTE  pfx;
00742
00743     switch (afd->a_af)
00744     {
00745       case AF_INET:
00746            v4a = (DWORD) ntohl (((struct in_addr*)pton)->s_addr);
00747            if (IN_MULTICAST (v4a) || IN_EXPERIMENTAL(v4a))
00748               flags &= ~AI_CANONNAME;
00749            v4a >>= IN_CLASSA_NSHIFT;
00750            if (v4a == 0 || v4a == IN_LOOPBACKNET)
00751               flags &= ~AI_CANONNAME;
00752            break;
00753
00754       case AF_INET6:
00755            pfx = ((struct in6_addr*)pton)->s6_addr[0];
00756            if (pfx == 0 || pfx == 0xfe || pfx == 0xff)
00757               flags &= ~AI_CANONNAME;
00758            break;
00759     }
00760
00761     if (pai->ai_family == afd->a_af || pai->ai_family == AF_UNSPEC)
00762     {
00763       if (!(flags & AI_CANONNAME))
00764       {
00765         GET_AI (cur->ai_next, afd, pton);
00766         GET_PORT (cur->ai_next, servname);
00767       }
00768       else
00769       {
00770         /* if AI_CANONNAME and if reverse lookup fail, return ai anyway
00771          * to pacify calling application.
00772          *
00773          * XXX getaddrinfo() is a name to address translation function,
00774          * and it looks strange that we do addr to name translation here.
00775          */
00776         get_name (pton, afd, &cur->ai_next, pton, pai, servname);
00777       }
00778       while (cur && cur->ai_next)
00779         cur = cur->ai_next;
00780     }
00781     else
00782       ERR (EAI_FAMILY);         /* xxx */
00783   }
00784   *res = sentinel.ai_next;
00785   return (0);
00786
00787 free_it:
00788 bad:
00789   free_addrinfo (sentinel.ai_next);
00790   return (error);
00791 }
00792
00793 /*
00794  * numeric hostname with scope
00795  */
00796 static int explore_numeric_scope (const struct addrinfo *pai,
00797                                   const char *hostname, const char *servname,
00798                                   struct addrinfo **res)
00799 {
00800   const struct afd    *afd;
00801   struct addrinfo     *cur;
00802   struct sockaddr_in6 *sin6;
00803   char *cp, hostname2 [MAX_HOSTLEN];
00804   int   error, scope = 0;
00805
00806 #ifdef TEST_PROG
00807   SOCK_DEBUGF (("\nexplore_numeric_scope"));
00808 #endif
00809
00810   /* if the servname does not match socktype/protocol, ignore it.
00811    */
00812   if (get_portmatch (pai, servname) != 0)
00813      return (0);
00814
00815   afd = find_afd (pai->ai_family);
00816   if (!afd->a_scoped)
00817      return explore_numeric (pai, hostname, servname, res);
00818
00819   cp = strchr (hostname, SCOPE_DELIMITER);
00820   if (!cp || (cp - hostname) >= SIZEOF(hostname2))
00821      return explore_numeric (pai, hostname, servname, res);
00822
00823   /* Handle special case of <scoped_address>%<scope id>
00824    * 'scope id' is numeric "1..x".
00825    */
00826   StrLcpy (hostname2, hostname, sizeof(hostname2));
00827
00828   /* terminate at the delimiter
00829    */
00830   hostname2 [cp-hostname] = '\0';
00831
00832   switch (pai->ai_family)
00833   {
00834     case AF_INET6:
00835          scope = __scope_ascii_to_id (cp+1);
00836          if (scope == 0)
00837             return (EAI_NONAME);
00838          break;
00839   }
00840
00841   error = explore_numeric (pai, hostname2, servname, res);
00842   if (error == 0)
00843   {
00844     for (cur = *res; cur; cur = cur->ai_next)
00845     {
00846       if (cur->ai_family != AF_INET6)
00847          continue;
00848
00849       sin6 = (struct sockaddr_in6*) cur->ai_addr;
00850       if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr) ||
00851           IN6_IS_ADDR_MC_LINKLOCAL(&sin6->sin6_addr))
00852         sin6->sin6_scope_id = scope;
00853     }
00854   }
00855   return (error);
00856 }
00857
00858 static int get_name (const char *addr, const struct afd *afd,
00859                      struct addrinfo **res, char *numaddr,
00860                      const struct addrinfo *pai, const char *servname)
00861 {
00862   struct hostent  *hp;
00863   struct addrinfo *cur = NULL;
00864   int    error = 0;
00865
00866   SOCK_ENTER_SCOPE();
00867   called_from_getai = TRUE;
00868   hp = gethostbyaddr (addr, afd->a_addrlen, afd->a_af);
00869   called_from_getai = FALSE;
00870   SOCK_LEAVE_SCOPE();
00871
00872   if (hp && hp->h_name && hp->h_name[0] && hp->h_addr_list[0])
00873   {
00874     GET_AI (cur, afd, hp->h_addr);
00875     GET_PORT (cur, servname);
00876     GET_CANONNAME (cur, hp->h_name);
00877   }
00878   else
00879   {
00880     GET_AI (cur, afd, numaddr);
00881     GET_PORT (cur, servname);
00882   }
00883
00884   *res = cur;
00885   return (0);  /* success */
00886
00887 free_it:
00888   free_addrinfo (cur);
00889   *res = NULL;
00890   return (error);
00891 }
00892
00893 static int get_canonname (const struct addrinfo *pai, struct addrinfo *ai,
00894                           const char *str)
00895 {
00896   if (pai->ai_flags & AI_CANONNAME)
00897   {
00898     ai->ai_canonname = strdup (str);
00899     if (!ai->ai_canonname)
00900        return (EAI_MEMORY);
00901   }
00902   return (0);
00903 }
00904
00905 static struct addrinfo *get_ai (const struct addrinfo *pai,
00906                                 const struct afd      *afd,
00907                                 const char            *addr)
00908 {
00909   struct addrinfo *ai;
00910   char  *p;
00911
00912   ai = calloc (sizeof(*ai) + afd->a_socklen, 1);
00913   if (!ai)
00914      return (NULL);
00915
00916   *ai = *pai;
00917   ai->ai_addr            = (struct sockaddr*) (ai + 1);
00918   ai->ai_addrlen         = afd->a_socklen;
00919   ai->ai_addr->sa_family = ai->ai_family = afd->a_af;
00920
00921   p = (char*)ai->ai_addr + afd->a_off;
00922   memcpy (p, addr, afd->a_addrlen);
00923   return (ai);
00924 }
00925
00926 static int get_portmatch (const struct addrinfo *ai, const char *servname)
00927 {
00928   /* get_port does not touch first argument. when matchonly == 1. */
00929   return get_port ((struct addrinfo*)ai, servname, 1);
00930 }
00931
00932 static int get_port (struct addrinfo *ai, const char *servname, int matchonly)
00933 {
00934   struct servent *sp;
00935   const  char    *proto;
00936   WORD   port;
00937   BOOL   allownumeric;
00938
00939   if (!servname ||
00940       (ai->ai_family != AF_INET && ai->ai_family != AF_INET6))
00941      return (0);
00942
00943   switch (ai->ai_socktype)
00944   {
00945     case SOCK_RAW:
00946     case SOCK_PACKET:
00947          return (EAI_SERVICE);
00948     case SOCK_DGRAM:
00949     case SOCK_STREAM:
00950     case ANY:
00951          allownumeric = TRUE;
00952          break;
00953     default:
00954          return (EAI_SOCKTYPE);
00955   }
00956
00957   if (str_isnumber(servname))
00958   {
00959     if (!allownumeric)
00960        return (EAI_SERVICE);
00961     port = htons (ATOI(servname));
00962   }
00963   else
00964   {
00965     switch (ai->ai_socktype)
00966     {
00967       case SOCK_DGRAM:
00968            proto = "udp";
00969            break;
00970       case SOCK_STREAM:
00971            proto = "tcp";
00972            break;
00973       default:
00974            proto = NULL;
00975            break;
00976     }
00977
00978     SOCK_ENTER_SCOPE();
00979     sp = getservbyname (servname, proto);
00980     SOCK_LEAVE_SCOPE();
00981
00982     if (!sp)
00983        return (EAI_SERVICE);
00984     port = sp->s_port;
00985   }
00986
00987   if (!matchonly)
00988   {
00989     switch (ai->ai_family)
00990     {
00991       case AF_INET:
00992            ((struct sockaddr_in*)ai->ai_addr)->sin_port = port;
00993            break;
00994       case AF_INET6:
00995            ((struct sockaddr_in6*)ai->ai_addr)->sin6_port = port;
00996            break;
00997     }
00998   }
00999   return (0);
01000 }
01001
01002 static const struct afd *find_afd (int af)
01003 {
01004   const struct afd *afd;
01005
01006   if (af == AF_UNSPEC)
01007      return (NULL);
01008
01009   for (afd = afd_list; afd->a_af; afd++)
01010       if (afd->a_af == af)
01011          return (afd);
01012   return (NULL);
01013 }
01014
01015 #if defined(TEST_PROG)
01016 static void dump_addrinfo (const struct addrinfo *ai)
01017 {
01018   for (; ai; ai = ai->ai_next)
01019   {
01020     const struct sockaddr_in  *sa4 = (const struct sockaddr_in*)ai->ai_addr;
01021     const struct sockaddr_in6 *sa6 = (const struct sockaddr_in6*)ai->ai_addr;
01022     int   af = ai->ai_family;
01023     char  buf [INET6_ADDRSTRLEN];
01024
01025     printf ("    family %2d, CNAME %s, ",
01026             af, ai->ai_canonname ? ai->ai_canonname : "<none>");
01027     printf ("%s\n",
01028             af == AF_INET  ? inet_ntop(af, &sa4->sin_addr, buf, sizeof(buf)) :
01029             af == AF_INET6 ? inet_ntop(af, &sa6->sin6_addr, buf, sizeof(buf)) :
01030             "??");
01031   }
01032 }
01033
01034 int main (void)
01035 {
01036   struct addrinfo hints, *res = NULL;
01037   int rc;
01038
01039   dbug_init();
01040   sock_init();
01041   memset (&hints, 0, sizeof(hints));
01042   hints.ai_family   = AF_UNSPEC;
01043   hints.ai_socktype = SOCK_STREAM;
01044   hints.ai_flags    = AI_CANONNAME;
01045
01046   rc = getaddrinfo ("ubr3-ca3-0-sec.landg1.lb.home.nl", "http",
01047                     &hints, &res);
01048   if (res)
01049        dump_addrinfo (res);
01050   else printf ("fail; %s\n", gai_strerror(rc));
01051
01052   if (res)
01053      freeaddrinfo (res);
01054   return (0);
01055 }
01056 #endif /* TEST_PROG */
01057 #endif /* USE_BSD_API */
01058
Generated on Wed Jan 25 15:42:34 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/GET_IP.C Source File

SRC/GET_IP.C

Go to the documentation of this file.
00001
00006 /*
00007  * Copyright (C) 1999-2001  Internet Software Consortium.
00008  *
00009  * Permission to use, copy, modify, and distribute this software for any
00010  * purpose with or without fee is hereby granted, provided that the above
00011  * copyright notice and this permission notice appear in all copies.
00012  *
00013  * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
00014  * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
00015  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
00016  * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
00017  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
00018  * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
00019  * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
00020  * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
00021  */
00022
00023 /* $Id: getipnode.c,v 1.30 2001/07/18 02:37:08 mayer Exp $ */
00024
00025 /* Originally from ISC's BIND 9.21; lightweigth resolver library (lwres).
00026  * Rewritten an simplified for Watt-32 by <giva@bgnett.no>  Nov-2003.
00027  */
00028
00029 #include "socket.h"
00030 #include "get_xby.h"
00031 #include "udp_dom.h"
00032
00033 #if defined(USE_BSD_API)
00034
00035 static struct hostent *copyandmerge (const struct hostent *he1,
00036                                      const struct hostent *he2,
00037                                      int af, int *err);
00038
00039 static __inline void scan_interface (BOOL *have_v4, BOOL *have_v6)
00040 {
00041   if (have_v4)
00042      *have_v4 = TRUE;
00043
00044   if (have_v6)
00045 #if defined(USE_IPV6)
00046     *have_v6 = dns_do_ipv6;
00047 #else
00048     *have_v6 = FALSE;
00049 #endif
00050 }
00051
00052 /*
00053  * AI_V4MAPPED + AF_INET6
00054  * If no IPv6 address then a query for IPv4 and map returned values.
00055  *
00056  * AI_ALL + AI_V4MAPPED + AF_INET6
00057  * Return IPv6 and IPv4 mapped.
00058  *
00059  * AI_ADDRCONFIG
00060  * Only return IPv6 / IPv4 address if there is an interface of that
00061  * type active.
00062  */
00063 struct hostent * W32_CALL
00064 getipnodebyname (const char *name, int af, int flags, int *error)
00065 {
00066   struct hostent *he1 = NULL;
00067   struct hostent *he2 = NULL;
00068   struct in_addr  in4;
00069   struct in6_addr in6;
00070   BOOL   have_v4 = TRUE, have_v6 = TRUE;
00071   BOOL   v4 = FALSE, v6 = FALSE;
00072   int    tmp_err;
00073
00074   SOCK_DEBUGF (("\ngetipnodebyname: %s ", name));
00075
00076   /* If we care about active interfaces then check.
00077    */
00078   if (flags & AI_ADDRCONFIG)
00079      scan_interface (&have_v4, &have_v6);
00080
00081   /* Check for literal address.
00082    */
00083   v4 = inet_pton (AF_INET, name, &in4);
00084   if (!v4)
00085      v6 = inet_pton (AF_INET6, name, &in6);
00086
00087   /* Impossible combination?
00088    */
00089   if ((af == AF_INET6 && !(flags & AI_V4MAPPED) && v4) ||
00090       (af == AF_INET && v6) ||
00091       (!have_v4 && v4) ||
00092       (!have_v6 && v6) ||
00093       (!have_v4 && af == AF_INET) ||
00094       ((!have_v6 && af == AF_INET6) && ((flags & AI_V4MAPPED) && have_v4)) ||
00095       !(flags & AI_V4MAPPED))
00096   {
00097     *error = HOST_NOT_FOUND;
00098     return (NULL);
00099   }
00100
00101   /* Literal address?
00102    */
00103   if (v4 || v6)
00104   {
00105     struct hostent he;
00106     char  *addr_list[2];
00107     char  *aliases[1];
00108
00109     he.h_name         = (char*) name;
00110     he.h_addr_list    = addr_list;
00111     he.h_addr_list[0] = (v4 ? (char*)&in4 : (char*)&in6);
00112     he.h_addr_list[1] = NULL;
00113     he.h_aliases      = aliases;
00114     he.h_aliases[0]   = NULL;
00115     he.h_length       = (v4 ? INADDRSZ : IN6ADDRSZ);
00116     he.h_addrtype     = (v4 ? AF_INET  : AF_INET6);
00117     return copyandmerge (&he, NULL, af, error);
00118   }
00119
00120   tmp_err = NO_RECOVERY;
00121   if (have_v6 && af == AF_INET6)
00122   {
00123 #if defined(USE_IPV6)
00124     he1 = gethostbyname6 (name);
00125 #else
00126     he1 = NULL;
00127 #endif
00128     if (!he1)
00129        tmp_err = HOST_NOT_FOUND;
00130   }
00131
00132   if (have_v4 &&
00133       (af == AF_INET ||
00134        (af == AF_INET6 &&
00135         (flags & AI_V4MAPPED) && (!he1 || (flags & AI_ALL)))))
00136   {
00137     SOCK_ENTER_SCOPE();
00138     he2 = gethostbyname (name);
00139     SOCK_LEAVE_SCOPE();
00140     if (!he2 || !he1)
00141     {
00142       *error = HOST_NOT_FOUND;
00143       return (NULL);
00144     }
00145   }
00146   else
00147     *error = tmp_err;
00148
00149   return copyandmerge (he1, he2, af, error);
00150 }
00151
00152 struct hostent * W32_CALL
00153 getipnodebyaddr (const void *src, size_t len, int af, int *error)
00154 {
00155   struct hostent *he1, *he2;
00156   const  BYTE *cp = (const BYTE*) src;
00157
00158   SOCK_DEBUGF (("\ngetipnodebyaddr: "));
00159
00160   if (!src)
00161   {
00162     *error = NO_RECOVERY;
00163     return (NULL);
00164   }
00165
00166   switch (af)
00167   {
00168     case AF_INET:
00169          if (len < INADDRSZ)
00170          {
00171            *error = NO_RECOVERY;
00172            return (NULL);
00173          }
00174          break;
00175 #if defined(USE_IPV6)
00176     case AF_INET6:
00177          if (len < IN6ADDRSZ)
00178          {
00179            *error = NO_RECOVERY;
00180            return (NULL);
00181          }
00182          break;
00183 #endif
00184     default:
00185          *error = NO_RECOVERY;
00186          return (NULL);
00187   }
00188
00189   /* Look up IPv4 and IPv4 mapped/compatible addresses.
00190    */
00191   if ((af == AF_INET6 && IN6_IS_ADDR_V4COMPAT(cp)) ||
00192       (af == AF_INET6 && IN6_IS_ADDR_V4MAPPED(cp)) ||
00193       (af == AF_INET))
00194   {
00195     if (af == AF_INET6)
00196        cp += 12;
00197
00198     SOCK_ENTER_SCOPE();
00199     he1 = gethostbyaddr ((const char*)cp, 4, AF_INET);
00200     SOCK_LEAVE_SCOPE();
00201
00202     if (af == AF_INET)
00203        goto ret_copy;
00204
00205     /* Convert from AF_INET to AF_INET6.
00206      */
00207     he2 = copyandmerge (he1, NULL, af, error);
00208     if (he2)
00209     {
00210       memcpy (he2->h_addr, src, len);  /* Restore original address */
00211       SOCK_DEBUGF (("%s", af == AF_INET ?
00212                     inet_ntoa(*(struct in_addr*)&he2->h_addr) :
00213                     _inet6_ntoa(he2->h_addr)));
00214     }
00215     return (he2);
00216   }
00217
00218   he1 = gethostbyaddr (src, len, AF_INET6);   /* Lookup IPv6 address */
00219
00220 ret_copy:
00221   if (!he1)
00222   {
00223     *error = HOST_NOT_FOUND;
00224     return (NULL);
00225   }
00226   return copyandmerge (he1, NULL, af, error);
00227 }
00228
00229 void W32_CALL freehostent (struct hostent *he)
00230 {
00231   char *p;
00232
00233   SOCK_DEBUGF (("\nfreehostent: %s ", he->h_name));
00234
00235   if (!he->h_name)   /* possible double freeing */
00236      return;
00237
00238   free (he->h_name);
00239   he->h_name = NULL;
00240
00241   for (p = he->h_addr_list[0]; p; p++)
00242       free (p);
00243
00244   for (p = he->h_aliases[0]; p; p++)
00245       free (p);
00246
00247   free (he->h_aliases);
00248   free (he->h_addr_list);
00249   free (he);
00250 }
00251
00252 static struct hostent *copyandmerge (const struct hostent *he1,
00253                                      const struct hostent *he2,
00254                                      int af, int *error)
00255 {
00256   struct hostent *he = NULL;
00257   int    addresses = 1;      /* NULL terminator */
00258   int    names = 1;          /* NULL terminator */
00259   char **cpp, **npp;
00260
00261   /* Work out array sizes.
00262    */
00263   if (he1)
00264   {
00265     cpp = he1->h_addr_list;
00266     while (*cpp)
00267     {
00268       addresses++;
00269       cpp++;
00270     }
00271     cpp = he1->h_aliases;
00272     while (*cpp)
00273     {
00274       names++;
00275       cpp++;
00276     }
00277   }
00278
00279   if (he2)
00280   {
00281     cpp = he2->h_addr_list;
00282     while (*cpp)
00283     {
00284       addresses++;
00285       cpp++;
00286     }
00287     if (!he1)
00288     {
00289       cpp = he2->h_aliases;
00290       while (*cpp)
00291       {
00292         names++;
00293         cpp++;
00294       }
00295     }
00296   }
00297
00298   if (addresses == 1)
00299   {
00300     *error = NO_ADDRESS;
00301     return (NULL);
00302   }
00303
00304   he = malloc (sizeof(*he));
00305   if (!he)
00306   {
00307     *error = NO_RECOVERY;
00308     return (NULL);
00309   }
00310
00311   he->h_addr_list = calloc (addresses * sizeof(char*), 1);
00312   if (!he->h_addr_list)
00313      goto cleanup0;
00314
00315   /* Copy addresses.
00316    */
00317   npp = he->h_addr_list;
00318   if (he1)
00319   {
00320     cpp = he1->h_addr_list;
00321     while (*cpp)
00322     {
00323       *npp = malloc (af == AF_INET ? INADDRSZ : IN6ADDRSZ);
00324       if (!*npp)
00325          goto cleanup1;
00326
00327       /* Convert to mapped if required.
00328        */
00329       if (af == AF_INET6 && he1->h_addrtype == AF_INET)
00330       {
00331         memcpy (*npp, in6addr_mapped, sizeof(in6addr_mapped));
00332         memcpy (*npp + sizeof(in6addr_mapped), *cpp, INADDRSZ);
00333       }
00334       else
00335         memcpy (*npp, *cpp, af == AF_INET ? INADDRSZ : IN6ADDRSZ);
00336       cpp++;
00337       npp++;
00338     }
00339   }
00340
00341   if (he2)
00342   {
00343     cpp = he2->h_addr_list;
00344     while (*cpp)
00345     {
00346       *npp = malloc (af == AF_INET ? INADDRSZ : IN6ADDRSZ);
00347       if (!*npp)
00348          goto cleanup1;
00349
00350       /* Convert to mapped if required.
00351        */
00352       if (af == AF_INET6 && he2->h_addrtype == AF_INET)
00353       {
00354         memcpy (*npp, in6addr_mapped, sizeof(in6addr_mapped));
00355         memcpy (*npp + sizeof(in6addr_mapped), *cpp, INADDRSZ);
00356       }
00357       else
00358         memcpy (*npp, *cpp, af == AF_INET ? INADDRSZ : IN6ADDRSZ);
00359       cpp++;
00360       npp++;
00361     }
00362   }
00363
00364   he->h_aliases = calloc (names * sizeof(char*), 1);
00365   if (!he->h_aliases)
00366      goto cleanup1;
00367
00368   /* Copy aliases.
00369    */
00370   npp = he->h_aliases;
00371   cpp = (he1 ? he1->h_aliases : he2->h_aliases);
00372   while (*cpp)
00373   {
00374     *npp = strdup (*cpp);
00375     if (!*npp)
00376        goto cleanup2;
00377     npp++;
00378     cpp++;
00379   }
00380
00381   /* Copy hostname.
00382    */
00383   if (he1)
00384        he->h_name = strdup (he1->h_name);
00385   else he->h_name = strdup (he2->h_name);
00386
00387   if (!he->h_name)
00388      goto cleanup2;
00389
00390   he->h_addrtype = af;
00391   he->h_length   = (af == AF_INET ? INADDRSZ : IN6ADDRSZ);
00392   return (he);
00393
00394 cleanup2:
00395   for (cpp = he->h_aliases; *cpp; *cpp++ = NULL)
00396       free (*cpp);
00397   free (he->h_aliases);
00398
00399 cleanup1:
00400   for (cpp = he->h_addr_list; *cpp; *cpp++ = NULL)
00401       free (*cpp);
00402   free (he->h_addr_list);
00403
00404 cleanup0:
00405   free (he);
00406   *error = NO_RECOVERY;
00407   return (NULL);
00408 }
00409 #endif     /* USE_BSD_API */
Generated on Wed Jan 25 15:42:34 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/GET_NI.C Source File

SRC/GET_NI.C

Go to the documentation of this file.
00001
00005 /* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
00006  * All rights reserved.
00007  *
00008  * Redistribution and use in source and binary forms, with or without
00009  * modification, are permitted provided that the following conditions
00010  * are met:
00011  * 1. Redistributions of source code must retain the above copyright
00012  *    notice, this list of conditions and the following disclaimer.
00013  * 2. Redistributions in binary form must reproduce the above copyright
00014  *    notice, this list of conditions and the following disclaimer in the
00015  *    documentation and/or other materials provided with the distribution.
00016  * 3. Neither the name of the project nor the names of its contributors
00017  *    may be used to endorse or promote products derived from this software
00018  *    without specific prior written permission.
00019  *
00020  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
00021  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00022  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00023  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
00024  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00025  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00026  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00027  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00028  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00029  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00030  * SUCH DAMAGE.
00031  */
00032
00033 /*
00034  * Issues to be discussed:
00035  * - Thread safe-ness must be checked
00036  * - Return values.  There seems to be no standard for return value (RFC2553)
00037  *   but INRIA implementation returns EAI_xxx defined for getaddrinfo().
00038  * - RFC2553 says that we should raise error on short buffer.  X/Open says
00039  *   we need to truncate the result.  We obey RFC2553 (and X/Open should be
00040  *   modified).
00041  *
00042  * Adapted for Watt-32 tcp/ip stack by G. Vanem <giva@bgnett.no>, Aug 2002.
00043  */
00044
00045 #if 0
00046 static const char rcsid[] = "@(#) $Header: /tcpdump/master/tcpdump/missing/"
00047                             "getnameinfo.c,v 1.8 2000/10/24 00:56:53 fenner Exp $";
00048 #endif
00049
00050 #include "socket.h"
00051
00052 #if defined(USE_BSD_API)
00053
00054 #define NI_SUCCESS 0
00055 #define ANY        0
00056 #define YES        1
00057 #define NO         0
00058
00059 #define ENI_NOSOCKET    EINVAL
00060 #define ENI_NOHOSTNAME  EINVAL
00061 #define ENI_MEMORY      ENOMEM
00062 #define ENI_SALEN       EINVAL
00063 #define ENI_FAMILY      EAFNOSUPPORT
00064 #define ENI_SYSTEM      -1
00065
00066 #define GI_RESULT(err)  gi_result (err, #err, __LINE__)
00067
00068 static struct afd {
00069        int  a_af;
00070        int  a_addrlen;
00071        int  a_socklen;
00072        int  a_off;
00073      } afd_list [3];
00074
00075 struct sockinet {
00076        BYTE  si_len;
00077        BYTE  si_family;
00078        WORD  si_port;
00079      };
00080
00081 /*
00082  * Initialise afd_list[] with IPv6 protocol at highest priority.
00083  */
00084 static void afd_list_init (BOOL ip6_prio)
00085 {
00086   int i = (ip6_prio ? 0 : 1);
00087
00088   memset (&afd_list, 0, sizeof(afd_list));
00089   afd_list[i].a_af      = AF_INET6;
00090   afd_list[i].a_addrlen = sizeof (struct in6_addr);
00091   afd_list[i].a_socklen = sizeof (struct sockaddr_in6);
00092   afd_list[i].a_off     = offsetof (struct sockaddr_in6, sin6_addr);
00093
00094   i ^= 1;
00095   afd_list[i].a_af      = AF_INET;
00096   afd_list[i].a_addrlen = sizeof (struct in_addr);
00097   afd_list[i].a_socklen = sizeof (struct sockaddr_in);
00098   afd_list[i].a_off     = offsetof (struct sockaddr_in, sin_addr);
00099 }
00100
00101 static int gi_result (int err, const char *str, unsigned line)
00102 {
00103   SOCK_LEAVE_SCOPE();
00104   if (err)
00105   {
00106     SOCK_DEBUGF ((", %s (%d) at line %u", str, err, line));
00107     if (err > 0)
00108        SOCK_ERRNO (err);
00109   }
00110   else
00111     SOCK_DEBUGF ((", okay"));
00112
00113   ARGSUSED (str);
00114   ARGSUSED (line);
00115   return (err);
00116 }
00117
00118 int W32_CALL getnameinfo (const struct sockaddr *sa, int salen,
00119                           char *host, int hostlen,
00120                           char *serv, int servlen, int flags)
00121 {
00122   static BOOL init = FALSE;
00123   struct afd     *afd;
00124   int    i, family = -1;
00125   DWORD  v4a;
00126   WORD   port;
00127   char   numserv[512];
00128   char   numaddr[512];
00129   char  *addr, *p;
00130
00131   const struct servent      *sp;
00132   const struct hostent      *hp;
00133   const struct sockaddr_in  *a4 = (const struct sockaddr_in *) sa;
00134   const struct sockaddr_in6 *a6 = (const struct sockaddr_in6*) sa;
00135
00136   if (!init)
00137      afd_list_init (TRUE);
00138   init = TRUE;
00139
00140   SOCK_DEBUGF (("\ngetnameinfo: "));
00141
00142   if (!sa)
00143      return GI_RESULT (ENI_NOSOCKET);
00144
00145   family = sa->sa_family;
00146
00147   SOCK_DEBUGF (("name %s, serv %.10s, flags %04X",
00148                 family == AF_INET  ?  inet_ntoa(a4->sin_addr) :
00149                 family == AF_INET6 ? _inet6_ntoa(&a6->sin6_addr) : "??",
00150                 ((flags & NI_NUMERICSERV) || flags == 0) ? "<get>" : serv,
00151                 flags));
00152
00153   for (i = 0; afd_list[i].a_af; i++)
00154       if (afd_list[i].a_af == family)
00155       {
00156         afd = &afd_list[i];
00157         goto found;
00158       }
00159   return GI_RESULT (ENI_FAMILY);
00160
00161 found:
00162   if (salen != afd->a_socklen)
00163      return GI_RESULT (ENI_SALEN);
00164
00165   port = ((struct sockinet*)sa)->si_port; /* network byte order */
00166   addr = (char*) sa + afd->a_off;
00167
00168   SOCK_ENTER_SCOPE();
00169
00170   if (!serv || servlen == 0)
00171   {
00172     /* do nothing in this case.
00173      * in case you are wondering if "&&" is more correct than
00174      * "||" here: RFC2553 says that serv == NULL OR servlen == 0
00175      * means that the caller does not want the result.
00176      */
00177   }
00178   else
00179   {
00180     if (flags & NI_NUMERICSERV)
00181          sp = NULL;
00182     else sp = getservbyport (port, (flags & NI_DGRAM) ? "udp" : "tcp");
00183     if (sp)
00184     {
00185       if ((int)strlen(sp->s_name) + 1 > servlen)
00186          return GI_RESULT (ENI_MEMORY);
00187       strcpy (serv, sp->s_name);
00188     }
00189     else
00190     {
00191       itoa (ntohs(port), numserv, 10);
00192       if ((int)strlen(numserv) + 1 > servlen)
00193          return GI_RESULT (ENI_MEMORY);
00194       strcpy (serv, numserv);
00195     }
00196   }
00197
00198   switch (sa->sa_family)
00199   {
00200     case AF_INET:
00201          v4a = ntohl (((struct sockaddr_in*)sa)->sin_addr.s_addr);
00202          if (IN_MULTICAST (v4a) || IN_EXPERIMENTAL (v4a))
00203             flags |= NI_NUMERICHOST;
00204          v4a >>= IN_CLASSA_NSHIFT;
00205          if (v4a == 0)
00206             flags |= NI_NUMERICHOST;
00207          break;
00208
00209     case AF_INET6:
00210          switch (a6->sin6_addr.s6_addr[0])
00211          {
00212            case 0x00:
00213                 if (IN6_IS_ADDR_V4MAPPED(&a6->sin6_addr))
00214                    ;
00215                 else if (IN6_IS_ADDR_LOOPBACK(&a6->sin6_addr))
00216                    ;
00217                 else
00218                   flags |= NI_NUMERICHOST;
00219                 break;
00220            default:
00221                 if (IN6_IS_ADDR_LINKLOCAL(&a6->sin6_addr))
00222                    flags |= NI_NUMERICHOST;
00223                 else if (IN6_IS_ADDR_MULTICAST(&a6->sin6_addr))
00224                    flags |= NI_NUMERICHOST;
00225                 break;
00226          }
00227          break;
00228   }
00229   if (!host || hostlen == 0)
00230   {
00231     /* do nothing in this case.
00232      * in case you are wondering if "&&" is more correct than
00233      * "||" here: RFC2553 says that host == NULL OR hostlen == 0
00234      * means that the caller does not want the result.
00235      */
00236   }
00237   else if (flags & NI_NUMERICHOST)
00238   {
00239     /* NUMERICHOST and NAMEREQD conflicts with each other
00240      */
00241     if (flags & NI_NAMEREQD)
00242        return GI_RESULT (ENI_NOHOSTNAME);
00243
00244     if (inet_ntop (afd->a_af, addr, numaddr, sizeof(numaddr)) == NULL)
00245        return GI_RESULT (ENI_SYSTEM);
00246
00247     if ((int)strlen(numaddr) + 1 > hostlen)
00248        return GI_RESULT (ENI_MEMORY);
00249
00250     strcpy (host, numaddr);
00251
00252     if (afd->a_af == AF_INET6 &&
00253         (IN6_IS_ADDR_LINKLOCAL(addr) ||
00254          IN6_IS_ADDR_MULTICAST(addr)) &&
00255          ((struct sockaddr_in6*)sa)->sin6_scope_id)
00256     {
00257 #if !defined(ALWAYS_WITHSCOPE)
00258       if (flags & NI_WITHSCOPEID)
00259 #endif
00260       {
00261         char *ep    = strchr (host, '\0');
00262         int   id    = ((struct sockaddr_in6*)sa)->sin6_scope_id;
00263         int   scope = __scope_id_to_ascii (id);  /* '1' ... N */
00264
00265         *ep++ = SCOPE_DELIMITER;
00266         *ep++ = scope ? scope : '?';
00267         *ep = '\0';
00268       }
00269     }
00270   }
00271   else
00272   {
00273     hp = gethostbyaddr (addr, afd->a_addrlen, afd->a_af);
00274     if (hp)
00275     {
00276       if (flags & NI_NOFQDN)
00277       {
00278         p = strchr (hp->h_name, '.');
00279         if (p)
00280            *p = '\0';
00281       }
00282       if ((int)strlen(hp->h_name) + 1 > hostlen)
00283          return GI_RESULT (ENI_MEMORY);
00284       strcpy (host, hp->h_name);
00285     }
00286     else
00287     {
00288       if (flags & NI_NAMEREQD)
00289          return GI_RESULT (ENI_NOHOSTNAME);
00290
00291       if (inet_ntop (afd->a_af, addr, numaddr, sizeof(numaddr)) == NULL)
00292          return GI_RESULT (ENI_NOHOSTNAME);
00293
00294       if ((int)strlen(numaddr) + 1 > hostlen)
00295          return GI_RESULT (ENI_MEMORY);
00296
00297       strcpy (host, numaddr);
00298     }
00299   }
00300   ARGSUSED (a4);
00301   return GI_RESULT (NI_SUCCESS);
00302 }
00303
00304
00305 #if defined(TEST_PROG)
00306
00307 #undef ni_flags  /* <netinet/icmp6.> */
00308
00309 static int ni_flags = NI_NAMEREQD; // NI_NUMERICHOST
00310
00311 static int ip4_resolve (const char *name)
00312 {
00313   struct sockaddr_in a4;
00314   char   buf[40];
00315   int    rc;
00316
00317   printf ("getnameinfo(): ");
00318   fflush (stdout);
00319
00320   a4.sin_family = AF_INET;
00321   inet_pton (AF_INET, "193.69.165.20", &a4.sin_addr);
00322   rc = getnameinfo ((const struct sockaddr*)&a4, sizeof(a4),
00323                     buf, sizeof(buf), NULL, 0, ni_flags);
00324   if (rc)
00325        perror (NULL);
00326   else puts (buf);
00327   return (rc);
00328 }
00329
00330 static int ip6_resolve (const char *name)
00331 {
00332   struct sockaddr_in6 a6;
00333   char   buf[40];
00334   int    rc;
00335
00336   printf ("getnameinfo(): ");
00337   fflush (stdout);
00338
00339   a6.sin6_family = AF_INET6;  /* ftp.deepspace6.net */
00340   inet_pton (AF_INET6, "2001:760:204:10:10:a7ff:fe16:27f4", &a6.sin6_addr);
00341   rc = getnameinfo ((const struct sockaddr*)&a6, sizeof(a6),
00342                     buf, sizeof(buf), NULL, 0, ni_flags);
00343   if (rc)
00344        perror (NULL);
00345   else puts (buf);
00346   return (rc);
00347 }
00348
00349 int main (int argc, char **argv)
00350 {
00351   int af = -1;
00352
00353   if (argc < 2)
00354      goto usage;
00355
00356   if (!stricmp(argv[1],"AF_INET"))
00357      af = AF_INET;
00358
00359   else if (!stricmp(argv[1],"AF_INET6"))
00360      af = AF_INET6;
00361
00362   dbug_init();
00363   sock_init();
00364
00365   if (af == AF_INET6)
00366      return ip6_resolve ("ftp.deepspace6.net");
00367
00368   if (af == AF_INET)
00369      return ip4_resolve ("ftp.deepspace6.net");
00370
00371 usage:
00372   printf ("Usage: <AF_INET | AF_INET6>");
00373   return (1);
00374 }
00375 #endif /* TEST_PROG */
00376 #endif /* USE_BSD_API && USE_IP6 */
00377
Generated on Wed Jan 25 15:42:34 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/GET_XBY.H Source File

SRC/GET_XBY.H

Go to the documentation of this file.
00001
00003 #ifndef _w32_GET_X_BY_Y_H
00004 #define _w32_GET_X_BY_Y_H
00005
00006 #ifndef _REENTRANT
00007 #define _REENTRANT   /* pull in the *_r() prototypes */
00008 #endif
00009
00010 #ifndef __NETDB_H
00011 #include <netdb.h>
00012 #endif
00013
00014 #define MAX_SERV_ALIASES    5
00015 #define MAX_HOST_ALIASES    5
00016 #define MAX_NETENT_ALIASES  5
00017 #define MAX_PROTO_ALIASES   0
00018 #define MAX_CACHE_LIFE      (15*60)
00019
00020 #define ReadHostsFile     NAMESPACE (ReadHostsFile)
00021 #define GetHostsFile      NAMESPACE (GetHostsFile)
00022 #define CloseHostFile     NAMESPACE (CloseHostFile)
00023
00024 #define ReadHosts6File    NAMESPACE (ReadHosts6File)
00025 #define CloseHost6File    NAMESPACE (CloseHost6File)
00026 #define GetHosts6File     NAMESPACE (GetHosts6File)
00027
00028 #define ReadServFile      NAMESPACE (ReadServFile)
00029 #define GetServFile       NAMESPACE (GetServFile)
00030 #define CloseServFile     NAMESPACE (CloseServFile)
00031
00032 #define ReadProtoFile     NAMESPACE (ReadProtoFile)
00033 #define GetProtoFile      NAMESPACE (GetProtoFile)
00034 #define CloseProtoFile    NAMESPACE (CloseProtoFile)
00035
00036 #define ReadNetworksFile  NAMESPACE (ReadNetworksFile)
00037 #define CloseNetworksFile NAMESPACE (CloseNetworksFile)
00038 #define GetNetFile        NAMESPACE (GetNetFile)
00039
00040 #define InitEthersFile    NAMESPACE (InitEthersFile)
00041 #define ReadEthersFile    NAMESPACE (ReadEthersFile)
00042 #define GetEthersFile     NAMESPACE (GetEthersFile)
00043 #define NumEtherEntries   NAMESPACE (NumEtherEntries)
00044
00045 #define gethostbyname6    NAMESPACE (gethostbyname6)
00046 #define gethostbyaddr6    NAMESPACE (gethostbyaddr6)
00047 #define gethostent6       NAMESPACE (gethostent6)
00048
00049 #define DumpHostsCache    NAMESPACE (DumpHostsCache)
00050 #define DumpHosts6Cache   NAMESPACE (DumpHosts6Cache)
00051
00052
00056 struct _hostent {
00057   char            *h_name;                         /* official name of host */
00058   char            *h_aliases[MAX_HOST_ALIASES+1];  /* hostname alias list */
00059   int              h_num_addr;                     /* how many real addr below */
00060   DWORD            h_address[MAX_ADDRESSES+1];     /* addresses (network order) */
00061   DWORD            h_real_ttl;                     /* TTL from udp_dom.c */
00062   time_t           h_timeout;                      /* cached entry expiry time */
00063   struct _hostent *h_next;                         /* next entry (or NULL) */
00064 };
00065
00069 struct _hostent6 {
00070   char             *h_name;                        /* official name of host */
00071   char             *h_aliases[MAX_HOST_ALIASES+1]; /* hostname alias list */
00072   int               h_num_addr;                    /* how many real addr below */
00073   ip6_address       h_address[MAX_ADDRESSES+1];    /* addresses */
00074   DWORD             h_real_ttl;                    /* TTL from udp_dom.c */
00075   time_t            h_timeout;                     /* cached entry expiry time */
00076   struct _hostent6 *h_next;
00077 };
00078
00082 struct _netent {
00083   char           *n_name;                           /* official name of net */
00084   char           *n_aliases [MAX_NETENT_ALIASES+1]; /* alias list */
00085   int             n_addrtype;                       /* net address type */
00086   DWORD           n_net;                            /* network (host order) */
00087   struct _netent *n_next;
00088 };
00089
00093 struct _protoent {
00094   char             *p_name;
00095   char             *p_aliases [MAX_PROTO_ALIASES+1];
00096   int               p_proto;
00097   struct _protoent *p_next;
00098 };
00099
00103 struct _servent {
00104   char            *s_name;
00105   char            *s_aliases [MAX_SERV_ALIASES+1];
00106   int              s_port;
00107   char            *s_proto;
00108   struct _servent *s_next;
00109 };
00110
00111 extern BOOL called_from_getai;
00112
00113 W32_DATA unsigned netdbCacheLife;
00114
00115 W32_FUNC void  ReadHostsFile    (const char *fname);  /* gethost.c */
00116 W32_FUNC void  ReadServFile     (const char *fname);  /* getserv.c */
00117 W32_FUNC void  ReadProtoFile    (const char *fname);  /* getprot.c */
00118 W32_FUNC void  ReadNetworksFile (const char *fname);  /* getnet.c */
00119 W32_FUNC void  ReadEthersFile   (void);               /* geteth.c */
00120 W32_FUNC int   NumEtherEntries  (void);               /* geteth.c */
00121 W32_FUNC void  InitEthersFile   (const char *fname);  /* geteth.c */
00122
00123 W32_FUNC void  CloseHostFile    (void);
00124 W32_FUNC void  CloseServFile    (void);
00125 W32_FUNC void  CloseProtoFile   (void);
00126 W32_FUNC void  CloseNetworksFile(void);
00127
00128 W32_FUNC const char *GetHostsFile (void);
00129 W32_FUNC const char *GetServFile  (void);
00130 W32_FUNC const char *GetProtoFile (void);
00131 W32_FUNC const char *GetNetFile   (void);
00132 W32_FUNC const char *GetEthersFile(void);
00133
00134 W32_FUNC void DumpHostsCache (void);
00135
00136 #if defined(USE_BSD_API) && defined(USE_IPV6)  /* gethost6.c */
00137   W32_FUNC void            ReadHosts6File (const char *fname);
00138   W32_FUNC void            CloseHost6File (void);
00139   W32_FUNC void            DumpHosts6Cache (void);
00140   W32_FUNC const char     *GetHosts6File (void);
00141
00142   W32_FUNC void            sethostent6 (int stayopen);
00143   W32_FUNC void            endhostent6 (void);
00144   W32_FUNC struct hostent *gethostent6 (void);
00145   W32_FUNC struct hostent *gethostbyname6 (const char *name);
00146   W32_FUNC struct hostent *gethostbyaddr6 (const void *addr);
00147 #endif
00148
00149 #endif
Generated on Wed Jan 25 15:42:34 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/GETETH.C Source File

SRC/GETETH.C

Go to the documentation of this file.
00001
00006 /*  Copyright (c) 1997-2002 Gisle Vanem <giva@bgnett.no>
00007  *
00008  *  Redistribution and use in source and binary forms, with or without
00009  *  modification, are permitted provided that the following conditions
00010  *  are met:
00011  *  1. Redistributions of source code must retain the above copyright
00012  *     notice, this list of conditions and the following disclaimer.
00013  *  2. Redistributions in binary form must reproduce the above copyright
00014  *     notice, this list of conditions and the following disclaimer in the
00015  *     documentation and/or other materials provided with the distribution.
00016  *  3. All advertising materials mentioning features or use of this software
00017  *     must display the following acknowledgement:
00018  *       This product includes software developed by Gisle Vanem
00019  *       Bergen, Norway.
00020  *
00021  *  THIS SOFTWARE IS PROVIDED BY ME (Gisle Vanem) AND CONTRIBUTORS ``AS IS''
00022  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00023  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00024  *  ARE DISCLAIMED.  IN NO EVENT SHALL I OR CONTRIBUTORS BE LIABLE FOR ANY
00025  *  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00026  *  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00027  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00028  *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00029  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00030  *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00031  *
00032  *
00033  *  28.apr 2000 - Created
00034  */
00035
00036 #include <stdio.h>
00037 #include <stdlib.h>
00038 #include <string.h>
00039
00040 #include "wattcp.h"
00041 #include "misc.h"
00042 #include "pcarp.h"
00043 #include "pcconfig.h"
00044 #include "udp_dom.h"
00045 #include "strings.h"
00046 #include "netaddr.h"
00047 #include "get_xby.h"
00048
00049 #if defined(USE_BSD_API)
00050
00051 #include <net/if.h>
00052 #include <net/if_arp.h>
00053 #include <net/if_dl.h>
00054 #include <net/if_ether.h>
00055 #include <net/route.h>
00056
00057 struct ethent {
00058        eth_address    eth_addr;  /* ether/MAC address of host */
00059        DWORD          ip_addr;   /* IP-address (host order) */
00060        char          *name;      /* host-name for IP-address */
00061        struct ethent *next;
00062      };
00063
00064 static struct ethent *eth0 = NULL;
00065 static int    num_entries  = -1;
00066 static char   ethersFname [MAX_PATHLEN] = "";
00067
00068 static int  getethent (const char *line, eth_address *e, char *name, size_t max);
00069 static void endethent (void);
00070
00071 #if defined(TEST_PROG)
00072   #define TRACE(s)  printf s
00073 #else
00074   #define TRACE(s)  ((void)0)
00075 #endif
00076
00077 void InitEthersFile (const char *fname)
00078 {
00079   if (fname && *fname)
00080      StrLcpy (ethersFname, fname, sizeof(ethersFname));
00081 }
00082
00083 const char *GetEthersFile (void)
00084 {
00085   return (ethersFname[0] ? ethersFname : NULL);
00086 }
00087
00088 int NumEtherEntries (void)
00089 {
00090   return (num_entries);
00091 }
00092
00093 void ReadEthersFile (void)
00094 {
00095   FILE *file;
00096   char  buf [2*MAX_HOSTLEN];
00097
00098   if (!ethersFname[0])
00099      return;
00100
00101   file = fopen (ethersFname, "rt");
00102   if (!file)
00103   {
00104     netdb_warn (ethersFname);
00105     return;
00106   }
00107
00108   while (fgets(buf,sizeof(buf),file))
00109   {
00110     struct ethent  *e;
00111     struct hostent *h;
00112     char   hostname [MAX_HOSTLEN], *p;
00113     int    save;
00114     eth_address eth;
00115
00116     p = strrtrim (strltrim(buf));
00117     if (memchr ("\r\n#;\0", *p, 5))
00118        continue;
00119
00120     TRACE (("line '%s', ", p));
00121
00122     if (!getethent(p,&eth,hostname,sizeof(hostname)))
00123        continue;
00124
00125     if (num_entries == -1)
00126        num_entries = 0;
00127     num_entries++;
00128     save = called_from_resolve;
00129     called_from_resolve = TRUE;   /* prevent a DNS lookup */
00130     h = gethostbyname (hostname);
00131     called_from_resolve = save;
00132
00133     if (!h)
00134     {
00135       TRACE (("gethostbyname() failed\n"));
00136       continue;
00137     }
00138     TRACE (("\n"));
00139
00140     e = calloc (sizeof(*e), 1);
00141     if (!e)
00142        break;
00143
00144     memcpy (&e->eth_addr, &eth, sizeof(e->eth_addr));
00145     e->ip_addr = ntohl (*(DWORD*)h->h_addr);
00146     _arp_add_cache (e->ip_addr, &e->eth_addr, FALSE);
00147     if (h->h_name)
00148     {
00149       e->name = strdup (h->h_name);
00150       if (!e->name)
00151          break;
00152     }
00153     e->next = eth0;
00154     eth0 = e;
00155   }
00156
00157   fclose (file);
00158   RUNDOWN_ADD (endethent, 250);
00159 }
00160
00161 /*
00162  * Parse a string of text containing an ethernet address and
00163  * hostname/IP-address and separate it into its component parts.
00164  */
00165 static int getethent (const char *line, eth_address *e,
00166                       char *name, size_t name_max)
00167 {
00168   const char *host_ip;
00169   size_t      len, i;
00170   WORD        eth[6];
00171
00172   if (sscanf(line, "%hx:%hx:%hx:%hx:%hx:%hx",
00173              &eth[0], &eth[1], &eth[2],
00174              &eth[3], &eth[4], &eth[5]) != 6)
00175   {
00176     TRACE (("sscanf() failed\n"));
00177     return (0);
00178   }
00179
00180   host_ip = strchr (line, ' ');
00181   if (!host_ip)
00182      return (0);
00183
00184   len = strlen (host_ip);
00185   if (len < 1 || len >= name_max)
00186      return  (0);
00187
00188   sscanf (host_ip, "%s", name);
00189   for (i = 0; i < sizeof(*e); i++)
00190       ((BYTE*)e)[i] = (BYTE) eth[i];
00191   return (1);
00192 }
00193
00194 /*
00195  * Free memory in 'eth0' array
00196  */
00197 static void endethent (void)
00198 {
00199   struct ethent *e, *next;
00200
00201   if (_watt_fatal_error)
00202      return;
00203
00204   for (e = eth0; e; e = next)
00205   {
00206     free (e->name);
00207     next = e->next;
00208     free (e);
00209   }
00210   eth0 = NULL;
00211   num_entries = 0;
00212 }
00213 #endif  /* USE_BSD_API */
00214
00215 #if defined(TEST_PROG)
00216
00217 #include "pcdbug.h"
00218 #include "sock_ini.h"
00219
00220 int main (void)
00221 {
00222 #if defined(USE_BSD_API)
00223   const struct ethent *e;
00224
00225   dbug_init();
00226   sock_init();
00227
00228   if (!ethersFname[0])
00229   {
00230     printf ("No ETHERS line found in WATTCP.CFG\n");
00231     return (-1);
00232   }
00233
00234   printf ("\n%s entries:\n", ethersFname);
00235   for (e = eth0; e; e = e->next)
00236       printf ("%02X:%02X:%02X:%02X:%02X:%02X = %-15.15s (%s)\n",
00237               (int)e->eth_addr[0], (int)e->eth_addr[1],
00238               (int)e->eth_addr[2], (int)e->eth_addr[3],
00239               (int)e->eth_addr[4], (int)e->eth_addr[5],
00240               _inet_ntoa(NULL,e->ip_addr), e->name ? e->name : "none");
00241   fflush (stdout);
00242 #else
00243   puts ("\"USE_BSD_API\" not defined");
00244 #endif /* USE_BSD_API */
00245   return (0);
00246 }
00247 #endif /* TEST_PROG */
00248
Generated on Wed Jan 25 15:42:34 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/GETHOST.C Source File

SRC/GETHOST.C

Go to the documentation of this file.
00001
00006 /*
00007  *  Copyright (c) 1997-2002 Gisle Vanem <giva@bgnett.no>
00008  *
00009  *  Redistribution and use in source and binary forms, with or without
00010  *  modification, are permitted provided that the following conditions
00011  *  are met:
00012  *  1. Redistributions of source code must retain the above copyright
00013  *     notice, this list of conditions and the following disclaimer.
00014  *  2. Redistributions in binary form must reproduce the above copyright
00015  *     notice, this list of conditions and the following disclaimer in the
00016  *     documentation and/or other materials provided with the distribution.
00017  *  3. All advertising materials mentioning features or use of this software
00018  *     must display the following acknowledgement:
00019  *       This product includes software developed by Gisle Vanem
00020  *       Bergen, Norway.
00021  *
00022  *  THIS SOFTWARE IS PROVIDED BY ME (Gisle Vanem) AND CONTRIBUTORS ``AS IS''
00023  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00024  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00025  *  ARE DISCLAIMED.  IN NO EVENT SHALL I OR CONTRIBUTORS BE LIABLE FOR ANY
00026  *  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00027  *  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00028  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00029  *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00030  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00031  *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00032  *
00033  *
00034  *  18.aug 1996 (GV)  - Created
00035  *  02.dec 1997 (GV)  - Integrated with resolve()
00036  *  05.jan 1998 (GV)  - Added host cache functionality
00037  *  18.may 1999 (GV)  - Added timeout of cached values
00038  *
00039  *  todo: support real host aliases as they come from the name server
00040  *  todo: accept "rooted FQDN" strings as normal FQDN strings.
00041  *        Note: "domain_name.com" and "domain_name.com." are equivalent
00042  *        (both are valid forms of fully qualified domain names (FQDNs);
00043  *        with the period, it is referred to as a rooted FQDN). Both forms
00044  *        should work with all mail clients and servers.  However, using the
00045  *        trailing "." is rarely used (except in DNS maintenance).
00046  *
00047  *  Note: if gethostbyname("some.host") returns address a.b.c.d, then
00048  *        a call to gethostbyaddr(a.b.c.d) will return "some.host"
00049  *        immediately (from cached info provided it didn't time out).
00050  *        This is contrary to most Unixes where the calls doesn't share
00051  *        the same information.
00052  */
00053
00054 #include <stdio.h>
00055 #include <stdlib.h>
00056 #include <string.h>
00057 #include <ctype.h>
00058 #include <time.h>
00059 #include <netdb.h>
00060 #include <arpa/inet.h>
00061
00062 #include "wattcp.h"
00063 #include "strings.h"
00064 #include "misc.h"
00065 #include "timer.h"
00066 #include "language.h"
00067 #include "pcconfig.h"
00068 #include "netaddr.h"
00069 #include "pctcp.h"
00070 #include "bsdname.h"
00071 #include "bsddbug.h"
00072 #include "udp_dom.h"
00073 #include "get_xby.h"
00074
00075 int h_errno = 0;
00076
00077 #if defined(USE_BSD_API)   /* Whole file */
00078
00079 unsigned netdbCacheLife = MAX_CACHE_LIFE;
00080
00081 static char            *hostFname  = NULL;
00082 static FILE            *hostFile   = NULL;
00083 static BOOL             hostClose  = FALSE;
00084 static const char      *from_where = NULL;
00085 static struct _hostent *host0      = NULL;
00086
00087 static BOOL did_lookup = FALSE;   /* tried a DNS lookup */
00088
00089 static BOOL gethostbyname_internal (const char *name,
00090                                     const char **alias,
00091                                     struct _hostent *ret);
00092
00093 static BOOL gethostbyaddr_internal (const char *addr_name, int len, int type,
00094                                     struct _hostent *ret);
00095
00096 static struct hostent  *fill_hostent (const struct _hostent *h);
00097
00098 static struct _hostent *add_hostent (struct _hostent *h,
00099                                      const char *name, const char *cname,
00100                                      DWORD *alist, DWORD addr, DWORD ttl);
00101
00102 void ReadHostsFile (const char *fname)
00103 {
00104   static BOOL been_here = FALSE;
00105
00106   if (!fname || !*fname)
00107      return;
00108
00109   if (been_here)  /* loading multiple hosts files */
00110   {
00111     free (hostFname);
00112     fclose (hostFile);
00113     hostFile = NULL;
00114   }
00115
00116   hostFname = strdup (fname);
00117   if (!hostFname)
00118      return;
00119
00120   sethostent (1);
00121   if (!hostFile)
00122      return;
00123
00124   been_here = TRUE;
00125
00126   while (1)
00127   {
00128     struct  hostent *h = gethostent();
00129     struct _hostent *h2;
00130     int     i;
00131
00132     if (!h)
00133        break;
00134
00135     h2 = (struct _hostent*) calloc (sizeof(*h2), 1);
00136     if (!h2)
00137     {
00138       outs (hostFname);
00139       outsnl (_LANG(" too big!"));
00140       break;
00141     }
00142
00143     for (i = 0; h->h_aliases[i]; i++)
00144         h2->h_aliases[i] = strdup (h->h_aliases[i]);
00145     h2->h_name       = strdup (h->h_name);
00146     h2->h_address[0] = *(DWORD*) h->h_addr_list[0];
00147     h2->h_num_addr   = 1;
00148     if (!h2->h_name)
00149        break;
00150     h2->h_next = host0;
00151     host0      = h2;
00152   }
00153
00154 #if 0  /* test !! */
00155   {
00156     const struct _hostent *h;
00157     int   i;
00158
00159     printf ("\n%s entries:\n", hostFname);
00160     for (h = host0; h; h = h->h_next)
00161     {
00162       printf ("address = %-17.17s name = %-30.30s  Aliases:",
00163                inet_ntoa(*(struct in_addr*)&h->h_address[0]), h->h_name);
00164       for (i = 0; h->h_aliases[i]; i++)
00165           printf (" %s,", h->h_aliases[i]);
00166       puts ("");
00167     }
00168     fflush (stdout);
00169   }
00170 #endif
00171   rewind (hostFile);
00172   RUNDOWN_ADD (endhostent, 254);
00173 }
00174
00179 const char *GetHostsFile (void)
00180 {
00181   return (hostFname);
00182 }
00183
00189 void CloseHostFile (void)
00190 {
00191   if (hostFile)
00192      fclose (hostFile);
00193   hostFile = NULL;
00194 }
00195
00200 void ReopenHostFile (void)
00201 {
00202   ReadHostsFile (hostFname);
00203 }
00204
00210 struct hostent * W32_CALL gethostent (void)
00211 {
00212   struct _hostent h;
00213   char  *tok, *ip, *name, *alias;
00214   char   buf [2*MAX_HOSTLEN];
00215   int    i;
00216
00217   if (!netdb_init() || !hostFile)
00218   {
00219     h_errno = NO_RECOVERY;
00220     return (NULL);
00221   }
00222
00223   while (1)
00224   {
00225     if (!fgets(buf,sizeof(buf),hostFile))
00226        return (NULL);
00227
00228     tok = strltrim (buf);
00229     if (*tok == '#' || *tok == ';' || *tok == '\n')
00230        continue;
00231
00232     ip   = strtok (tok, " \t");
00233     name = strtok (NULL, " \t\n");
00234     if (ip && name && isaddr(ip))
00235        break;
00236   }
00237
00238   if (hostClose)
00239      endhostent();
00240
00241   memset (&h, 0, sizeof(h));
00242   if (!strcmp(ip,"0.0.0.0"))   /* inet_addr() maps 0 -> INADDR_NONE */
00243        h.h_address[0] = INADDR_ANY;
00244   else h.h_address[0] = inet_addr (ip);
00245
00246   h.h_num_addr = 1;
00247   h.h_name = name;
00248   alias    = strtok (NULL, " \t\n");
00249
00250   for (i = 0; alias && i < MAX_HOST_ALIASES; i++)
00251   {
00252     static char aliases [MAX_NETENT_ALIASES][MAX_HOSTLEN];
00253
00254     if (*alias == '#' || *alias == ';')
00255        break;
00256
00257     h.h_aliases[i] = StrLcpy (aliases[i], alias, sizeof(aliases[i]));
00258     alias = strtok (NULL, " \t\n");
00259   }
00260   return fill_hostent (&h);
00261 }
00262
00263 /*
00264  * Return a 'struct hostent *' for name.
00265  */
00266 struct hostent * W32_CALL gethostbyname (const char *name)
00267 {
00268   struct _hostent h;
00269   const char *alias;
00270
00271   SOCK_DEBUGF (("\ngethostbyname: `%s'", name));
00272
00273   if (gethostbyname_internal(name, &alias, &h))
00274   {
00275 #if defined(USE_DEBUG)
00276     int i;
00277     for (i = 0; i < h.h_num_addr; i++)
00278         SOCK_DEBUGF ((" %s,", inet_ntoa(*(struct in_addr*)&h.h_address[i])));
00279
00280     if (!did_lookup)
00281        SOCK_DEBUGF ((" %s", h.h_timeout ? "cached" :
00282                      from_where ? from_where : "hosts-file"));
00283
00284     if (alias)
00285        SOCK_DEBUGF ((" (alias %s)", alias));
00286 #endif
00287     return fill_hostent (&h);
00288   }
00289
00290   if (called_from_resolve)
00291        SOCK_DEBUGF ((", unknown (called from resolve)"));
00292   else SOCK_DEBUGF ((", failed (%s)", did_lookup ? dom_strerror(dom_errno) :
00293                       hstrerror(h_errno)));
00294   return (NULL);
00295 }
00296
00297 static BOOL gethostbyname_internal (const char *name, const char **alias,
00298                                     struct _hostent *ret)
00299 {
00300   static char our_name [MAX_HOSTLEN];
00301   struct in_addr  addr;
00302   struct _hostent *h;
00303   time_t now;
00304   DWORD  ip;
00305
00306   h_errno = HOST_NOT_FOUND;
00307   did_lookup = FALSE;
00308   from_where = NULL;
00309
00310   _resolve_exit = _resolve_timeout = 0;
00311   memset (ret, 0, sizeof(*ret));
00312   *alias = NULL;
00313
00314   if (!netdb_init())
00315   {
00316     h_errno = NO_RECOVERY;
00317     return (FALSE);
00318   }
00319
00320   if (inet_aton(name,&addr))
00321   {
00323     ret->h_name       = (char*) name;
00324     ret->h_address[0] = addr.s_addr;
00325     ret->h_num_addr   = 1;
00326     return (TRUE);
00327   }
00328
00329   now = time (NULL);
00330
00331   for (h = host0; h; h = h->h_next)
00332   {
00333     int i;
00334
00335     if (h->h_name && !stricmp(h->h_name,name))
00336     {
00337       /* if cached entry expired, do DNS lookup
00338        */
00339       if (h->h_timeout && now > h->h_timeout)
00340          goto expired;
00341
00342       *ret = *h;
00343       return (h->h_address[0] != INADDR_NONE ? TRUE : FALSE);
00344     }
00345     for (i = 0; h->h_aliases[i] && i < MAX_HOST_ALIASES; i++)
00346         if (!stricmp(name,h->h_aliases[i]))
00347         {
00348           if (h->h_timeout && now > h->h_timeout)
00349              goto expired;
00350
00351           *alias = h->h_aliases[i];
00352           *ret = *h;
00353           return (h->h_address[0] != INADDR_NONE ? TRUE : FALSE);
00354         }
00355   }
00356
00357   /* Not found in linked list (hosts file or cache). Check name
00358    * against our own host-name (short-name or FQDN).
00359    * \todo Should return all our addresses if we're multihomed.
00360    */
00361   if (hostname[0] && !stricmp(name,hostname))
00362   {
00363     ret->h_num_addr   = 1;
00364     ret->h_address[0] = gethostid();
00365     ret->h_name       = hostname;
00366     from_where = "sethostname";
00367     return (TRUE);
00368   }
00369
00370   if (!gethostname(our_name,sizeof(our_name)) && !stricmp(name,our_name))
00371   {
00372     ret->h_num_addr   = 1;
00373     ret->h_address[0] = gethostid();
00374     ret->h_name       = our_name;
00375     from_where = "sethostname";
00376     return (TRUE);
00377   }
00378
00379 expired:
00380
00381   if (called_from_resolve) /* prevent recursion */
00382      return (FALSE);
00383
00384   /* Do a full DNS lookup
00385    */
00386   called_from_ghbn = TRUE;
00387   ip = resolve (name);       /* do a normal lookup */
00388   called_from_ghbn = FALSE;
00389   did_lookup = TRUE;
00390
00391   if (_resolve_exit ||   /* interrupted or other fail */
00392       _resolve_timeout)  /* timed out resolving */
00393      return (FALSE);
00394
00395   if (ip)                /* successfully resolved */
00396   {
00397     h = add_hostent (h, name, dom_cname, dom_a4list, htonl(ip), dom_ttl);
00398     return (h ? *ret = *h, TRUE : FALSE);
00399   }
00400
00401   /* Add the name to the list even if we got a negative DNS reply.
00402    * Thus the next call to gethostbyxx() will return immediately.
00403    */
00404   add_hostent (h, name, NULL, NULL, INADDR_NONE, netdbCacheLife);
00405   return (FALSE);
00406 }
00407
00408 struct hostent *W32_CALL gethostbyname2 (const char *name, int family)
00409 {
00410   if (family == AF_INET)
00411      return gethostbyname (name);
00412
00413 #if defined(USE_IPV6)
00414   if (family == AF_INET6)
00415      return gethostbyname6 (name);
00416 #endif
00417
00418   h_errno = TRY_AGAIN;
00419   return (NULL);
00420 }
00421
00422
00423 /*
00424  * Return a 'struct hostent *' for an address.
00425  */
00426 struct hostent *W32_CALL gethostbyaddr (const char *addr_name, int len, int type)
00427 {
00428   struct _hostent h;
00429
00430   SOCK_DEBUGF (("\ngethostbyaddr: %s",
00431                 (type == AF_INET && addr_name) ?
00432                 inet_ntoa(*(struct in_addr*)addr_name) :
00433                 (type == AF_INET6 && addr_name) ?
00434                 _inet6_ntoa(addr_name) : ""));
00435
00436 #if defined(USE_IPV6)
00437   if (type == AF_INET6 && len == sizeof(struct in6_addr))
00438   {
00439     struct hostent *he;
00440
00441     SOCK_ENTER_SCOPE();
00442     he = gethostbyaddr6 (addr_name);
00443     SOCK_LEAVE_SCOPE();
00444     return (he);
00445   }
00446 #endif
00447
00448   if (gethostbyaddr_internal (addr_name, len, type, &h))
00449   {
00450     SOCK_DEBUGF ((" `%s'", h.h_name));
00451     if (!did_lookup)
00452        SOCK_DEBUGF ((", %s", h.h_timeout ? "cached" : "hosts-file"));
00453     return fill_hostent (&h);
00454   }
00455
00456   SOCK_DEBUGF ((" failed (%s) ", did_lookup ? dom_strerror(dom_errno) :
00457                 hstrerror(h_errno)));
00458   return (NULL);
00459 }
00460
00461
00462 void W32_CALL sethostent (int stayopen)
00463 {
00464   hostClose = (stayopen == 0);
00465   if (!netdb_init() || !hostFname)
00466      return;
00467
00468   if (!hostFile)
00469        hostFile = fopen (hostFname, "rt");
00470   else rewind (hostFile);
00471 }
00472
00473 void W32_CALL endhostent (void)
00474 {
00475   struct _hostent *h, *next = NULL;
00476
00477   if (_watt_fatal_error)
00478      return;
00479
00480   if (hostFname)
00481      free (hostFname);
00482   if (hostFile)
00483      fclose (hostFile);
00484   hostFname = NULL;
00485   hostFile  = NULL;
00486
00487   for (h = host0; h; h = next)
00488   {
00489     int i;
00490     for (i = 0; h->h_aliases[i]; i++)
00491         free (h->h_aliases[i]);
00492     next = h->h_next;
00493     free (h->h_name);
00494     free (h);
00495   }
00496   host0 = NULL;
00497   hostClose = TRUE;
00498 }
00499
00500
00501 static BOOL gethostbyaddr_internal (const char *addr_name, int len, int type,
00502                                     struct _hostent *ret)
00503 {
00504   static char name [MAX_HOSTLEN];
00505   struct _hostent *h = NULL;
00506   DWORD  addr;
00507   BOOL   rc;
00508   time_t now;
00509
00510   h_errno = HOST_NOT_FOUND;
00511   did_lookup = FALSE;
00512   from_where = NULL;
00513   _resolve_exit = _resolve_timeout = 0;
00514   memset (ret, 0, sizeof(*ret));
00515
00516   if (type != AF_INET || len < SIZEOF(addr))
00517   {
00518     h_errno = NO_RECOVERY;
00519     return (FALSE);
00520   }
00521
00522   if (!netdb_init())
00523   {
00524     h_errno = NO_RECOVERY;
00525     return (FALSE);
00526   }
00527
00528   addr = *(DWORD*) addr_name;
00529
00530   if ((addr == INADDR_ANY ||           /* 0.0.0.0 -> my_ip_addr */
00531        addr == gethostid()) &&
00532       gethostname(name,sizeof(name)) == 0)
00533   {
00536     ret->h_num_addr   = 1;
00537     ret->h_address[0] = gethostid();
00538     ret->h_name       = name;
00539     from_where = "sethostname";
00540     return (TRUE);
00541   }
00542
00543   if (addr == INADDR_BROADCAST ||      /* 255.255.255.255    */
00544       (~ntohl(addr) & ~sin_mask) == 0) /* directed broadcast */
00545   {
00546     ret->h_num_addr   = 1;
00547     ret->h_address[0] = addr;
00548     ret->h_name       = "broadcast";
00549     return (TRUE);
00550   }
00551
00552   now = time (NULL);
00553
00554   /* If called from getnameinfo() with AI_CANONNAME, we
00555    * should not search the host0 list. But do a full reeverse
00556    * lookup.
00557    */
00558   if (called_from_getai)
00559      goto expired;
00560
00561   for (h = host0; h; h = h->h_next)
00562   {
00563     int i;
00564
00565     for (i = 0; h->h_address[i] != INADDR_NONE && i < h->h_num_addr; i++)
00566     {
00567       if (addr == h->h_address[i])
00568       {
00569         /* if cached entry expired, do a new reverse lookup
00570          */
00571         if (h->h_timeout && now > h->h_timeout)
00572            goto expired;
00573
00574         *ret = *h;
00575         return (TRUE);
00576       }
00577     }
00578   }
00579
00580 expired:
00581
00582   /* do a reverse ip lookup
00583    */
00584   did_lookup = TRUE;
00585   rc = reverse_resolve_ip4 (addr, name, sizeof(name));
00586
00587   /* interrupted or timedout
00588    */
00589   if (!rc && (_resolve_exit || _resolve_timeout))
00590      return (FALSE);
00591
00592   if (rc)     /* successfully resolved */
00593   {
00594     h = add_hostent (h, name, dom_cname, NULL, addr, dom_ttl);
00596     return (h ? *ret = *h, TRUE : FALSE);
00597   }
00598
00599   /* Add the IP to the list even if reverse lookup failed and not
00600    * interrupted by _resolve_hook(). Thus the next call to gethostbyxx()
00601    * will return immediately.
00602    */
00603   add_hostent (h, "*unknown*", NULL, NULL, addr, 0UL);
00604   return (FALSE);
00605 }
00606
00607
00608 #if defined(NOT_USED)
00609 /*
00610  * Warn about calling 'getXbyY()' functions before calling
00611  * 'watt_sock_init()'. Many other functions will fail if we're not
00612  * initialised, but 'getXbyY()' are often used during application
00613  * startup.
00614  */
00615 void uninit_warn (const char *func)
00616 {
00617   outs ("Warning: function \"");
00618   outs (func);
00619   outsnl ("()\" called before \"sock_init()\".");
00620 }
00621 #endif
00622
00623 int * W32_CALL __h_errno_location (void)
00624 {
00625   return (&h_errno);
00626 }
00627
00628 static struct hostent *fill_hostent (const struct _hostent *h)
00629 {
00630   static struct hostent ret;
00631   static struct in_addr addr [MAX_ADDRESSES+1];
00632   static char  *list [MAX_ADDRESSES+1];
00633   static char   hostnam [MAX_HOSTLEN+1];
00634   static char  *aliases [MAX_HOST_ALIASES+1];
00635   int    i;
00636
00637   if (!h->h_name)
00638      return (NULL);
00639
00640   memset (&addr, 0, sizeof(addr));
00641   memcpy (&aliases, h->h_aliases, sizeof(aliases));
00642
00643   for (i = 0; i < h->h_num_addr && i < MAX_ADDRESSES; i++)
00644   {
00645     addr[i].s_addr = h->h_address[i];
00646     list[i]        = (char*) &addr[i];
00647   }
00648
00649   list[i]         = NULL;
00650   ret.h_addr_list = list;
00651   ret.h_name      = StrLcpy (hostnam, h->h_name, sizeof(hostnam));
00652   ret.h_aliases   = aliases;
00653   ret.h_addrtype  = AF_INET;
00654   ret.h_length    = sizeof (addr[0].s_addr);
00655   h_errno         = NETDB_SUCCESS;
00656   return (&ret);
00657 }
00658
00659 /*
00660  * Modify an expired cached entry or create a new node and
00661  * add it to the linked list. Not used for entries in hosts-file.
00662  */
00663 static struct _hostent  *add_hostent
00664        (struct _hostent *h,
00665         const char      *name,   /* Host name */
00666         const char      *cname,  /* Canonical name (CNAME) */
00667         DWORD           *alist,  /* List of alternate addresses */
00668         DWORD            addr,   /* Main IP-address */
00669         DWORD            ttl)    /* Time-to-live (sec) */
00670 {
00671   DWORD real_ttl = ttl;
00672   int   i;
00673
00674   ttl = min (ttl, netdbCacheLife);  /* clamp the TTL */
00675
00676   if (h)         /* reuse expired entry */
00677   {
00678     if (h->h_name)
00679        free (h->h_name);
00680     if (h->h_aliases[0])
00681        free (h->h_aliases[0]);     /* !! max 1 alias */
00682     memset (&h->h_address[1], 0,   /* clear old alternates */
00683             sizeof(h->h_address)-sizeof(u_long));
00684     h->h_aliases[0] = NULL;
00685   }
00686   else           /* create a new node */
00687   {
00688     h = (struct _hostent*) calloc (sizeof(*h), 1);
00689     if (h)
00690     {
00691       h->h_next = host0;
00692       host0 = h;
00693     }
00694   }
00695
00696   if (!cname || !cname[0])
00697      cname = NULL;
00698
00699   if (addr != INADDR_NONE)
00700      SOCK_DEBUGF ((", CNAME %s, ttl %lus,",
00701                    cname ? cname : "<none>", real_ttl));
00702   if (h)
00703   {
00704     h->h_timeout    = ttl ? time (NULL) + ttl : 0;
00705     h->h_real_ttl   = real_ttl;
00706     h->h_address[0] = addr;
00707     h->h_num_addr   = 1;
00708
00709     for (i = 0; alist; i++)
00710     {
00711       if (alist[i] == INADDR_NONE || alist[i] == INADDR_ANY)
00712          break;
00713       h->h_address[i+1] = alist[i];
00714       h->h_num_addr++;
00715     }
00716     if (cname)    /* swap name with CNAME */
00717     {
00718       h->h_name       = strdup (cname);
00719       h->h_aliases[0] = strdup (name);  /* !! only allow 1 alias */
00720     }
00721     else
00722       h->h_name = strdup (name);
00723   }
00724   else
00725     SOCK_DEBUGF ((" ENOMEM"));
00726
00727 #if defined(TEST_PROG)  /* test updated cache */
00728   if (h)
00729   {
00730     printf ("new entry: name %-30.30s -> address %s ",
00731             h->h_name, inet_ntoa(*(struct in_addr*)&h->h_address[0]));
00732     for (i = 1; i < h->h_num_addr; i++)
00733         printf (", %s",
00734                 inet_ntoa(*(struct in_addr*)&h->h_address[i]));
00735     puts ("");
00736   }
00737   else
00738     printf ("new entry: ENOMEM\n");
00739 #endif
00740
00741   return (h);
00742 }
00743
00744 #if defined(USE_DEBUG)
00745 /*
00746  * Reverse the 'host0' list before printing it. I.e. on same order
00747  * the host-names where put in the list by add_hostent().
00748  */
00749 static BOOL ReverseHostsList (void)
00750 {
00751   struct _hostent *h, **list;
00752   int    i, num_total, num_dynamic;
00753
00754   for (h = host0, num_total = num_dynamic = 0; h; h = h->h_next)
00755   {
00756     num_total++;
00757     if (h->h_timeout > 0)
00758        num_dynamic++;
00759   }
00760   if (num_total == 0 || num_dynamic == 0)
00761      return (FALSE);
00762
00763   list = malloc (num_total * sizeof(*list));
00764   if (!list)
00765      return (FALSE);
00766
00767   for (h = host0, i = 0; h; h = h->h_next)
00768       list[i++] = h;
00769
00770   for (host0 = NULL, i = 0; i < num_total; i++)
00771   {
00772     h         = list[i];
00773     h->h_next = host0;
00774     host0     = h;
00775   }
00776   free (list);
00777   return (TRUE);
00778 }
00779
00780 void DumpHostsCache (void)
00781 {
00782   struct _hostent *h;
00783   time_t now;
00784
00785   if (!ReverseHostsList())
00786      return;
00787
00788   SOCK_DEBUGF ((" \n\nCached IPv4 hosts:                         "
00789                 "Address         TTL       Alias\n"));
00790   now = time (NULL);
00791
00792   for (h = host0; h; h = h->h_next)
00793   {
00794     const char *ip_str, *cache_time;
00795     int   i;
00796
00797     if (h->h_real_ttl == 0)   /* skip fixed hosts-file records */
00798        continue;
00799
00800     cache_time = ((long)(h->h_timeout - now) < 0) ? "timedout" :
00801                   hms_str(h->h_real_ttl);
00802     ip_str     = (h->h_address[0] == INADDR_NONE) ? "<none>" :
00803                   inet_ntoa(*(struct in_addr*)&h->h_address[0]);
00804
00805     SOCK_DEBUGF (("  %-40s %-15s %8s  ", h->h_name, ip_str, cache_time));
00806     for (i = 0; h->h_aliases[i]; i++)
00807         SOCK_DEBUGF (("%s ", h->h_aliases[i]));
00808     if (i == 0)
00809          SOCK_DEBUGF (("<none>\n"));
00810     else SOCK_DEBUGF ((" \n"));
00811
00812     for (i = 1; i < h->h_num_addr; i++)
00813         SOCK_DEBUGF (("%42s %s\n", "",
00814                       inet_ntoa(*(struct in_addr*)&h->h_address[i])));
00815   }
00816 }
00817 #endif
00818
00819
00820 #if defined(TEST_PROG)
00821
00822 #include <conio.h>
00823 #include <unistd.h>
00824
00825 #include "pcdbug.h"
00826 #include "sock_ini.h"
00827
00828 /*
00829  * Print list of hosts unsorted.
00830  */
00831 static void print_hosts (void)
00832 {
00833   const struct _hostent *h;
00834
00835   for (h = host0; h; h = h->h_next)
00836   {
00837     int i;
00838
00839     printf ("address %-17.17s  name %s;",
00840             inet_ntoa(*(struct in_addr*)&h->h_address[0]), h->h_name);
00841
00842     for (i = 0; h->h_aliases[i]; i++)
00843     {
00844       if (i == 0)
00845          printf (" Aliases:");
00846       printf (" %s,", h->h_aliases[i]);
00847     }
00848     puts ("");
00849   }
00850   fflush (stdout);
00851 }
00852
00853 void Sleep (int time)
00854 {
00855   while (time)
00856   {
00857     if (kbhit() && getch() == 27)
00858     {
00859       fputc ('\n', stderr);
00860       return;
00861     }
00862     fprintf (stderr, "%4d", time--);
00863     sleep (1);
00864     fprintf (stderr, "\b\b\b\b");
00865   }
00866 }
00867
00868 int main (void)
00869 {
00870   const struct hostent *h;
00871   const char *host_name = "test-host";
00872   int   wait_time;
00873   DWORD addr_list [MAX_ADDRESSES+1];
00874
00875   dbug_init();
00876   sock_init();
00877   print_hosts();
00878
00879   wait_time = netdbCacheLife + 1;
00880   memset (&addr_list, 0, sizeof(addr_list));
00881   addr_list[0] = htonl (_inet_addr("80.22.33.45"));
00882   addr_list[1] = htonl (_inet_addr("222.22.33.46"));
00883   addr_list[2] = htonl (_inet_addr("217.22.33.47"));
00884   addr_list[3] = htonl (_inet_addr("81.22.33.48"));
00885   addr_list[4] = INADDR_NONE;
00886
00887   SOCK_DEBUGF (("\nadd_hostent: `%s'", host_name));
00888   add_hostent (NULL, host_name, "some.cname.org", &addr_list[1],
00889                addr_list[0], netdbCacheLife);
00890   h = gethostbyname (host_name);
00891   if (!h)
00892   {
00893     fprintf (stderr, "gethostbyname() failed!. h_errno = %d\n", h_errno);
00894     return (1);
00895   }
00896   fprintf (stderr, "Waiting for cache-entry to timeout..");
00897   Sleep (wait_time);
00898
00899   fprintf (stderr, "gethostbyname() should do a DNS lookup now.\n");
00900   h = gethostbyname (host_name);
00901   if (h)
00902      fprintf (stderr, "entry didn't timeout!.\n");
00903
00904 #if defined(USE_FORTIFY)
00905   Fortify_ListAllMemory();
00906   Fortify_OutputStatistics();
00907 #endif
00908   return (0);
00909 }
00910 #endif /* TEST_PROG */
00911 #endif /* USE_BSD_API */
00912
Generated on Wed Jan 25 15:42:34 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/GETHOST6.C Source File

SRC/GETHOST6.C

Go to the documentation of this file.
00001
00006 /*
00007  *  Copyright (c) 1997-2002 Gisle Vanem <giva@bgnett.no>
00008  *
00009  *  Redistribution and use in source and binary forms, with or without
00010  *  modification, are permitted provided that the following conditions
00011  *  are met:
00012  *  1. Redistributions of source code must retain the above copyright
00013  *     notice, this list of conditions and the following disclaimer.
00014  *  2. Redistributions in binary form must reproduce the above copyright
00015  *     notice, this list of conditions and the following disclaimer in the
00016  *     documentation and/or other materials provided with the distribution.
00017  *  3. All advertising materials mentioning features or use of this software
00018  *     must display the following acknowledgement:
00019  *       This product includes software developed by Gisle Vanem
00020  *       Bergen, Norway.
00021  *
00022  *  THIS SOFTWARE IS PROVIDED BY ME (Gisle Vanem) AND CONTRIBUTORS ``AS IS''
00023  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00024  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00025  *  ARE DISCLAIMED.  IN NO EVENT SHALL I OR CONTRIBUTORS BE LIABLE FOR ANY
00026  *  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00027  *  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00028  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00029  *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00030  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00031  *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00032  *
00033  *
00034  *  03.Aug 2002 (GV)  - Created
00035  */
00036
00037 #include <stdio.h>
00038 #include <stdlib.h>
00039 #include <string.h>
00040 #include <ctype.h>
00041 #include <time.h>
00042 #include <netdb.h>
00043 #include <arpa/nameser.h>
00044 #include <arpa/inet.h>
00045 #include <netinet/in.h>
00046 #include <resolv.h>
00047
00048 #include "wattcp.h"
00049 #include "strings.h"
00050 #include "misc.h"
00051 #include "timer.h"
00052 #include "language.h"
00053 #include "ip6_out.h"
00054 #include "pcconfig.h"
00055 #include "pctcp.h"
00056 #include "netaddr.h"
00057 #include "bsdname.h"
00058 #include "bsddbug.h"
00059 #include "udp_dom.h"
00060 #include "get_xby.h"
00061
00062 /* \if USE_IPV6 */
00063 #if defined(USE_BSD_API) && defined(USE_IPV6) /* whole file */
00064
00065 static char             *hostFname = NULL;
00066 static FILE             *hostFile  = NULL;
00067 static BOOL              hostClose = FALSE;
00068 static struct _hostent6 *host0     = NULL;
00069
00070 static BOOL did_lookup = FALSE;   /* tried a DNS lookup */
00071
00072 static BOOL gethostbyname6_internal (const char *name,
00073                                      const char **alias,
00074                                      struct _hostent6 *ret);
00075
00076 static BOOL gethostbyaddr6_internal (const char *addr,
00077                                      struct _hostent6 *ret);
00078
00079 static struct hostent *fill_hostent6 (const struct _hostent6 *h);
00080
00081 static struct _hostent6 *add_hostent6 (struct _hostent6 *h,
00082                                        const char       *name,
00083                                        const char       *cname,
00084                                        const void       *addr_list,
00085                                        const void       *addr,
00086                                        DWORD             ttl);
00087
00088
00089 void ReadHosts6File (const char *fname)
00090 {
00091   static BOOL been_here = FALSE;
00092
00093   if (!fname || !*fname)
00094      return;
00095
00096   if (been_here)  /* loading multiple hosts files */
00097   {
00098     free (hostFname);
00099     fclose (hostFile);
00100     hostFile = NULL;
00101   }
00102
00103   hostFname = strdup (fname);
00104   if (!hostFname)
00105      return;
00106
00107   sethostent6 (1);
00108   if (!hostFile)
00109      return;
00110
00111   been_here = TRUE;
00112
00113   while (1)
00114   {
00115     struct  hostent  *h = gethostent6();
00116     struct _hostent6 *h2;
00117     int     i;
00118
00119     if (!h)
00120        break;
00121
00122     h2 = (struct _hostent6*) calloc (sizeof(*h2), 1);
00123     if (!h2)
00124     {
00125       outs (hostFname);
00126       outsnl (_LANG(" too big!"));
00127       break;
00128     }
00129     for (i = 0; h->h_aliases[i]; i++)
00130         h2->h_aliases[i] = strdup (h->h_aliases[i]);
00131     memcpy (&h2->h_address[0], h->h_addr_list[0], sizeof(h2->h_address[0]));
00132     h2->h_num_addr = 1;
00133     h2->h_name     = strdup (h->h_name);
00134     h2->h_timeout  = 0;      /* don't expire */
00135     h2->h_real_ttl = 0;
00136     if (!h2->h_name)
00137        break;
00138
00139     h2->h_next = host0;
00140     host0      = h2;
00141   }
00142
00143 #if 0  /* test !! */
00144   {
00145     const struct _hostent6 *h;
00146     int   i;
00147
00148     printf ("\n%s entries:\n", hostFname);
00149     for (h = host0; h; h = h->h_next)
00150     {
00151       printf ("address %-40.40s  name %-30.30s  Aliases:",
00152               _inet6_ntoa(&h->h_address[0]), h->h_name);
00153       for (i = 0; h->h_aliases[i]; i++)
00154           printf (" %s,", h->h_aliases[i]);
00155       puts ("");
00156     }
00157     fflush (stdout);
00158   }
00159 #endif
00160
00161   rewind (hostFile);
00162   RUNDOWN_ADD (endhostent6, 256);
00163 }
00164
00165 const char *GetHosts6File (void)
00166 {
00167   return (hostFname);
00168 }
00169
00170 /*
00171  * To prevent running out of file-handles, one should close the
00172  * 'hosts' file before spawning a new shell.
00173  */
00174 void CloseHost6File (void)
00175 {
00176   fclose (hostFile);
00177   hostFile = NULL;
00178 }
00179
00180 void ReopenHost6File (void)
00181 {
00182   ReadHosts6File (hostFname);
00183 }
00184
00185 /*
00186  * Return the next (non-commented) line from the host-file
00187  * Format is:
00188  *  IPv6-address [=] host-name [alias..] {\n | # ..}
00189  */
00190 struct hostent *gethostent6 (void)
00191 {
00192   struct _hostent6 h;
00193   char *tok, *ip, *name, *alias;
00194   char  buf [2*MAX_HOSTLEN];
00195   int   i;
00196
00197   if (!netdb_init() || !hostFile)
00198   {
00199     h_errno = NO_RECOVERY;
00200     return (NULL);
00201   }
00202
00203   memset (&h, 0, sizeof(h));
00204
00205   while (1)
00206   {
00207     if (!fgets(buf,sizeof(buf),hostFile))
00208        return (NULL);
00209
00210     tok = strltrim (buf);
00211     if (*tok == '#' || *tok == ';' || *tok == '\n')
00212        continue;
00213
00214     ip   = strtok (tok, " \t");
00215     name = strtok (NULL, " \t\n");
00216     if (ip && name && inet_pton(AF_INET6, ip, &h.h_address[0]) == 1)
00217        break;
00218   }
00219
00220   if (hostClose)
00221      endhostent6();
00222
00223   h.h_num_addr = 1;
00224   h.h_name = name;
00225   alias    = strtok (NULL, " \t\n");
00226
00227   for (i = 0; alias && i < MAX_HOST_ALIASES; i++)
00228   {
00229     static char aliases [MAX_NETENT_ALIASES][MAX_HOSTLEN];
00230
00231     if (*alias == '#' || *alias == ';')
00232        break;
00233
00234     h.h_aliases[i] = StrLcpy (aliases[i], alias, sizeof(aliases[i]));
00235     alias = strtok (NULL, " \t\n");
00236   }
00237   return fill_hostent6 (&h);
00238 }
00239
00240 /*------------------------------------------------------------------*/
00241
00242 struct hostent *gethostbyname6 (const char *name)
00243 {
00244   struct _hostent6 h;
00245   const char *alias;
00246
00247   SOCK_DEBUGF (("\ngethostbyname6: `%s'", name));
00248
00249   if (gethostbyname6_internal(name, &alias, &h))
00250   {
00251 #if defined(USE_DEBUG)
00252     int i;
00253     for (i = 0; i < h.h_num_addr; i++)
00254         SOCK_DEBUGF ((" %s,", _inet6_ntoa(&h.h_address[i])));
00255
00256     if (!did_lookup)
00257        SOCK_DEBUGF ((" %s", h.h_timeout ? "cached" : "hosts6-file"));
00258
00259     if (alias)
00260        SOCK_DEBUGF ((" (alias %s)", alias));
00261 #endif
00262     return fill_hostent6 (&h);
00263   }
00264
00265   SOCK_DEBUGF ((", failed (%s)", did_lookup ? dom_strerror(dom_errno) :
00266                 hstrerror(h_errno)));
00267   return (NULL);
00268 }
00269
00270 static BOOL gethostbyname6_internal (const char *name, const char **alias,
00271                                      struct _hostent6 *ret)
00272 {
00273   static char our_name[MAX_HOSTLEN];
00274   struct in6_addr  addr;
00275   struct _hostent6 *h;
00276   time_t now;
00277   int    rc;
00278
00279   h_errno = HOST_NOT_FOUND;
00280   did_lookup = FALSE;
00281
00282   _resolve_exit = _resolve_timeout = 0;
00283   memset (ret, 0, sizeof(*ret));
00284   *alias = NULL;
00285
00286   if (!netdb_init() || !name)
00287   {
00288     h_errno = NO_RECOVERY;
00289     return (FALSE);
00290   }
00291
00292   if (inet_pton(AF_INET6,name,&addr) == 1)
00293   {
00294     ret->h_name = (char*) name;
00295     memcpy (&ret->h_address[0], &addr, sizeof(ret->h_address[0]));
00296     return (TRUE);
00297   }
00298
00299   now = time (NULL);
00300
00301   for (h = host0; h; h = h->h_next)
00302   {
00303     int i;
00304
00305     if (h->h_name && !stricmp(h->h_name,name))
00306     {
00307       /* if cached entry expired, do DNS lookup
00308        */
00309       if (h->h_timeout && now > h->h_timeout)
00310          goto expired;
00311
00312       if (IN6_ARE_ADDR_EQUAL(&h->h_address[0], &in6addr_all_1))
00313          return (FALSE);
00314       *ret = *h;
00315       return (TRUE);
00316     }
00317     for (i = 0; h->h_aliases[i] && i < MAX_HOST_ALIASES; i++)
00318         if (!stricmp(name,h->h_aliases[i]))
00319         {
00320           if (h->h_timeout && now > h->h_timeout)
00321              goto expired;
00322
00323           if (IN6_ARE_ADDR_EQUAL(&h->h_address[0], &in6addr_all_1))
00324              return (FALSE);
00325           *alias = h->h_aliases[i];
00326           *ret  = *h;
00327           return (TRUE);
00328         }
00329   }
00330
00331   /* Not found in linked list (hosts6 file or cache). Check name
00332    * against our own host-name (short-name or FQDN)
00333    */
00334   if (hostname[0] && !stricmp(name,hostname))
00335   {
00336     memcpy (&ret->h_address[0], &in6addr_my_ip, sizeof(ret->h_address[0]));
00337     ret->h_num_addr = 1;
00338     ret->h_name     = hostname;
00339     return (TRUE);
00340   }
00341
00342   if (!gethostname(our_name,sizeof(our_name)) && !stricmp(name,our_name))
00343   {
00344     memcpy (&ret->h_address[0], &in6addr_my_ip, sizeof(ret->h_address[0]));
00345     ret->h_num_addr = 1;
00346     ret->h_name     = our_name;
00347     return (TRUE);
00348   }
00349
00350 expired:
00351
00352   /* do a full DNS lookup
00353    */
00354   rc = resolve_ip6 (name, &addr);
00355   did_lookup = TRUE;
00356
00357   if (_resolve_exit ||   /* interrupted by _resolve_hook() */
00358       _resolve_timeout)  /* timed out resolving */
00359      return (FALSE);
00360
00361   if (rc)                /* successfully resolved */
00362   {
00363     h = add_hostent6 (h, name, dom_cname, &dom_a6list, &addr, dom_ttl);
00364     return (h ? *ret = *h, TRUE : FALSE);
00365   }
00366
00367   /* Add the IP to the list even if DNS failed (but not interrupted by
00368    * _resolve_hook() or timedout). Thus the next call to gethostbyxxx6()
00369    * will return immediately.
00370    */
00371   add_hostent6 (h, name, NULL, NULL, &in6addr_all_1, netdbCacheLife);
00372   return (FALSE);
00373 }
00374
00375 /*------------------------------------------------------------------*/
00376
00377 void sethostent6 (int stayopen)
00378 {
00379   hostClose = (stayopen == 0);
00380   if (!netdb_init() || !hostFname)
00381      return;
00382
00383   if (!hostFile)
00384        hostFile = fopen (hostFname, "rt");
00385   else rewind (hostFile);
00386 }
00387
00388 /*------------------------------------------------------------------*/
00389
00390 void endhostent6 (void)
00391 {
00392   struct _hostent6 *h, *next;
00393
00394   if (_watt_fatal_error)
00395      return;
00396
00397   if (hostFname)
00398      free (hostFname);
00399   if (hostFile)
00400      fclose (hostFile);
00401   hostFname = NULL;
00402   hostFile  = NULL;
00403
00404   for (h = host0; h; h = next)
00405   {
00406     int i;
00407     for (i = 0; h->h_aliases[i]; i++)
00408         free (h->h_aliases[i]);
00409     next = h->h_next;
00410     free (h->h_name);
00411     free (h);
00412   }
00413   host0 = NULL;
00414   hostClose = TRUE;
00415 }
00416
00417 /*
00418  * Return a 'struct hostent *' for an IPv6 address.
00419  */
00420 struct hostent *gethostbyaddr6 (const void *addr)
00421 {
00422   struct _hostent6 h;
00423
00424   SOCK_DEBUGF (("\ngethostbyaddr6: %s", _inet6_ntoa(addr)));
00425
00426   if (gethostbyaddr6_internal (addr, &h))
00427   {
00428     SOCK_DEBUGF ((" `%s'", h.h_name));
00429     if (!did_lookup)
00430        SOCK_DEBUGF ((", %s", h.h_timeout ? "cached" : "hosts-file"));
00431     return fill_hostent6 (&h);
00432   }
00433
00434   SOCK_DEBUGF ((", failed (%s) ", did_lookup ? dom_strerror(dom_errno) :
00435                 hstrerror(h_errno)));
00436   return (NULL);
00437 }
00438
00439 static BOOL gethostbyaddr6_internal (const char *addr, struct _hostent6 *ret)
00440 {
00441   static char name [MAX_HOSTLEN];
00442   struct _hostent6 *h;
00443   ip6_address ip;
00444   time_t      now;
00445   int         rc;
00446
00447   h_errno = HOST_NOT_FOUND;
00448   did_lookup = FALSE;
00449   _resolve_exit = _resolve_timeout = 0;
00450   memset (ret, 0, sizeof(*ret));
00451   memcpy (&ip, addr, sizeof(ip));
00452
00453   if (!netdb_init())
00454   {
00455     h_errno = NO_RECOVERY;
00456     return (FALSE);
00457   }
00458
00459   if ((IN6_ARE_ADDR_EQUAL(&ip, &in6addr_any) ||  /* :: -> in6addr_myip */
00460        IN6_IS_ADDR_LINKLOCAL(&ip)) &&            /* FE8/119 */
00461       gethostname(name,sizeof(name)) == 0)
00462   {
00463     memcpy (&ret->h_address[0], &in6addr_my_ip, sizeof(ret->h_address[0]));
00464     ret->h_num_addr = 1;
00465     ret->h_name     = name;
00466     return (TRUE);
00467   }
00468
00469   now = time (NULL);
00470
00471   for (h = host0; h; h = h->h_next)
00474       if (IN6_ARE_ADDR_EQUAL(&h->h_address[0],&ip))
00475       {
00476         /* if cached entry expired, do a new reverse lookup
00477          */
00478         if (h->h_timeout && now > h->h_timeout)
00479            break;
00480
00481         *ret = *h;
00482         return (TRUE);
00483       }
00484
00485   /* do a reverse IPv6 lookup
00486    */
00487   did_lookup = TRUE;
00488   rc = reverse_resolve_ip6 (&ip, name, sizeof(name));
00489
00490   /* interrupted or timedout
00491    */
00492   if (!rc && (_resolve_exit || _resolve_timeout))
00493      return (FALSE);
00494
00495   if (rc)        /* successfully resolved */
00496   {
00497     h = add_hostent6 (h, name, NULL, NULL, &ip, dom_ttl);
00499     return (h ? *ret = *h, TRUE : FALSE);
00500   }
00501
00502   /* Add the IP to the list even if reverse lookup failed and not
00503    * interrupted by _resolve_hook(). Thus the next call to gethostbyxx()
00504    * will return immediately.
00505    */
00506   add_hostent6 (h, "*unknown*", NULL, NULL, &ip, 0UL);
00507   return (FALSE);
00508 }
00509
00510 /*
00511  * Return a 'struct hostent*' from an internal 'struct _hostent6*'
00512  */
00513 static struct hostent *fill_hostent6 (const struct _hostent6 *h)
00514 {
00515   static struct hostent  ret;
00516   static struct in6_addr addr [MAX_ADDRESSES+1];
00517   static char  *list [MAX_ADDRESSES+1];
00518   static char   hostname [MAX_HOSTLEN];
00519   static char  *aliases [MAX_HOST_ALIASES+1];
00520   int    i;
00521
00522   if (!h->h_name)
00523      return (NULL);
00524
00525   memset (&addr, 0, sizeof(addr));
00526   memcpy (&aliases, h->h_aliases, sizeof(aliases));
00527
00528   for (i = 0; i < h->h_num_addr && i < MAX_ADDRESSES; i++)
00529   {
00530     memcpy (&addr[i].s6_addr, &h->h_address[i], sizeof(addr[i].s6_addr));
00531     list[i] = (char*) &addr[i];
00532   }
00533
00534   list[i]         = NULL;
00535   ret.h_addr_list = list;
00536   ret.h_name      = StrLcpy (hostname, h->h_name, sizeof(hostname));
00537   ret.h_aliases   = aliases;
00538   ret.h_addrtype  = AF_INET6;
00539   ret.h_length    = sizeof (addr[0].s6_addr);
00540   h_errno         = NETDB_SUCCESS;
00541   return (&ret);
00542 }
00543
00544 /*
00545  * Modify an expired cached entry or add a new node to
00546  * the linked list. Not used for entries in hosts-file.
00547  */
00548 static struct _hostent6 *add_hostent6 (
00549        struct _hostent6 *h,
00550        const char       *name,
00551        const char       *cname,  /* Canonical name (CNAME) */
00552        const void       *alist,  /* List of alternate addr */
00553        const void       *addr,   /* Main IP6-address */
00554        DWORD             ttl)    /* Time-to-live (sec) */
00555 {
00556   DWORD real_ttl = ttl;
00557   int   i;
00558
00559   ttl = min (ttl, netdbCacheLife);  /* clamp the TTL */
00560
00561   if (h)         /* reuse expired entry */
00562   {
00563     if (h->h_name)
00564        free (h->h_name);
00565     if (h->h_aliases[0])
00566        free (h->h_aliases[0]);     /* !! max 1 alias */
00567     memset (&h->h_address[1], 0,   /* clear old addresses */
00568             sizeof(h->h_address)-sizeof(ip6_address));
00569     h->h_aliases[0] = NULL;
00570   }
00571   else           /* create a new node */
00572   {
00573     h = (struct _hostent6*) calloc (sizeof(*h), 1);
00574     if (h)
00575     {
00576       h->h_next = host0;
00577       host0 = h;
00578     }
00579   }
00580
00581   if (!cname || !cname[0])
00582      cname = NULL;
00583
00584   if (addr != &in6addr_all_1)
00585      SOCK_DEBUGF ((", CNAME %s, ttl %lus,",
00586                    cname ? cname : "<none>", real_ttl));
00587   if (h)
00588   {
00589     const ip6_address *a6list = (const ip6_address*) alist;
00590
00591     h->h_timeout  = ttl ? time (NULL) + ttl : 0;
00592     h->h_real_ttl = real_ttl;
00593     h->h_num_addr = 1;
00594     memcpy (&h->h_address[0], addr, sizeof(h->h_address[0]));
00595     for (i = 0; a6list && !IN6_IS_ADDR_UNSPECIFIED(a6list[i]); i++)
00596     {
00597       memcpy (&h->h_address[i+1], a6list[i], sizeof(ip6_address));
00598       h->h_num_addr++;
00599     }
00600     if (cname)        /* swap name with CNAME */
00601     {
00602       h->h_name = strdup (cname);
00603       h->h_aliases[0] = strdup (name);  /* !! only allow 1 alias */
00604     }
00605     else
00606       h->h_name = strdup (name);
00607   }
00608   else
00609     SOCK_DEBUGF ((" ENOMEM"));
00610
00611   return (h);
00612 }
00613
00614 #if defined(USE_DEBUG)
00615 /*
00616  * Reverse the 'host0' list before printing it (a bit nicer and intuitive).
00617  * I.e. on same order the host-names where put in the list by add_hostent().
00618  */
00619 static BOOL ReverseHosts6List (void)
00620 {
00621   struct _hostent6 *h, **list;
00622   int    i, num_total, num_dynamic;
00623
00624   for (h = host0, num_total = num_dynamic = 0; h; h = h->h_next)
00625   {
00626     num_total++;
00627     if (h->h_timeout > 0)
00628        num_dynamic++;
00629   }
00630   if (num_total == 0 || num_dynamic == 0)
00631      return (FALSE);
00632
00633   list = malloc (num_total * sizeof(*list));
00634   if (!list)
00635      return (FALSE);
00636
00637   for (h = host0, i = 0; h; h = h->h_next)
00638       list[i++] = h;
00639
00640   for (host0 = NULL, i = 0; i < num_total; i++)
00641   {
00642     h         = list[i];
00643     h->h_next = host0;
00644     host0     = h;
00645   }
00646   free (list);
00647   return (TRUE);
00648 }
00649
00650 void DumpHosts6Cache (void)
00651 {
00652   struct _hostent6 *h;
00653   time_t now;
00654
00655   if (!ReverseHosts6List())
00656      return;
00657
00658   SOCK_DEBUGF ((" \n\nCached IPv6 hosts:                         "
00659                 "Address                                  TTL       Alias\n"));
00660   now = time (NULL);
00661
00662   for (h = host0; h; h = h->h_next)
00663   {
00664     const char *addr;
00665     int   i;
00666     long  dT;
00667
00668     if (h->h_real_ttl == 0) /* skip static records */
00669        continue;
00670
00671     dT = (long)(h->h_timeout - now);
00672     if (IN6_ARE_ADDR_EQUAL(&h->h_address[0], &in6addr_all_1))
00673          addr = "::";
00674     else addr = _inet6_ntoa (&h->h_address[0]);
00675
00676     SOCK_DEBUGF (("  %-40s %-40s %8s  ", h->h_name, addr,
00677                   dT < 0 ? "timedout" : hms_str(h->h_real_ttl)));
00678
00679     for (i = 0; h->h_aliases[i]; i++)
00680         SOCK_DEBUGF (("%s ", h->h_aliases[i]));
00681     if (i == 0)
00682          SOCK_DEBUGF (("<none>\n"));
00683     else SOCK_DEBUGF ((" \n"));
00684
00685     for (i = 1; i < h->h_num_addr; i++)
00686         SOCK_DEBUGF (("%62s %s\n", "", _inet6_ntoa(&h->h_address[i])));
00687
00688   }
00689 }
00690 #endif
00691
00692
00693 /*------------------------------------------------------------------*/
00694
00695 #ifdef TEST_PROG
00696
00697 #include "pcdbug.h"
00698 #include "sock_ini.h"
00699
00700 /*
00701  * Print list of hosts unsorted.
00702  */
00703 static void print_hosts (void)
00704 {
00705   const struct _hostent6 *h;
00706
00707   for (h = host0; h; h = h->h_next)
00708   {
00709     int i;
00710     printf ("%-40s -> %s; Aliases:", _inet6_ntoa(&h->h_address), h->h_name);
00711
00712     for (i = 0; h->h_aliases[i]; i++)
00713         printf (" %s,", h->h_aliases[i]);
00714     puts ("");
00715   }
00716   fflush (stdout);
00717 }
00718
00719 int main (void)
00720 {
00721   dbug_init();
00722   sock_init();
00723   print_hosts();
00724   return (0);
00725 }
00726 #endif /* TEST_PROG */
00727 #endif /* USE_BSD_API && USE_IPV6 */
00728 /* \endif */
00729
Generated on Wed Jan 25 15:42:34 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/GETNAME.C Source File

SRC/GETNAME.C

Go to the documentation of this file.
00001
00005 /*  BSD sockets functionality for Waterloo TCP/IP
00006  *
00007  *  Copyright (c) 1997-2002 Gisle Vanem <giva@bgnett.no>
00008  *
00009  *  Redistribution and use in source and binary forms, with or without
00010  *  modification, are permitted provided that the following conditions
00011  *  are met:
00012  *  1. Redistributions of source code must retain the above copyright
00013  *     notice, this list of conditions and the following disclaimer.
00014  *  2. Redistributions in binary form must reproduce the above copyright
00015  *     notice, this list of conditions and the following disclaimer in the
00016  *     documentation and/or other materials provided with the distribution.
00017  *  3. All advertising materials mentioning features or use of this software
00018  *     must display the following acknowledgement:
00019  *       This product includes software developed by Gisle Vanem
00020  *       Bergen, Norway.
00021  *
00022  *  THIS SOFTWARE IS PROVIDED BY ME (Gisle Vanem) AND CONTRIBUTORS ``AS IS''
00023  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00024  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00025  *  ARE DISCLAIMED.  IN NO EVENT SHALL I OR CONTRIBUTORS BE LIABLE FOR ANY
00026  *  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00027  *  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00028  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00029  *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00030  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00031  *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00032  *
00033  *  Version
00034  *
00035  *  0.5 : Dec 18, 1997 : G. Vanem - created
00036  *  0.6 : Aug 07, 2002 : G. Vanem - added AF_INET6 support
00037  */
00038
00039 #include "socket.h"
00040
00041 #if defined(USE_BSD_API)
00042
00043 int W32_CALL getsockname (int s, struct sockaddr *name, int *namelen)
00044 {
00045   Socket *socket = _socklist_find (s);
00046   int     sa_len;
00047
00048   SOCK_PROLOGUE (socket, "\ngetsockname:%d", s);
00049
00050   sa_len = (socket->so_family == AF_INET6) ? sizeof(struct sockaddr_in6) :
00051                                              sizeof(struct sockaddr_in);
00052
00053   if (!name || !namelen || (*namelen < sa_len))
00054   {
00055     SOCK_DEBUGF ((", EINVAL"));
00056     SOCK_ERRNO (EINVAL);
00057     if (namelen)
00058        *namelen = 0;
00059     return (-1);
00060   }
00061
00062   if (!socket->local_addr)
00063   {
00064     SOCK_DEBUGF ((", EINVAL"));
00065     SOCK_ERRNO (EINVAL);    /* according to HP/UX manpage */
00066     return (-1);
00067   }
00068
00069   VERIFY_RW (name, *namelen);
00070
00071   *namelen = sa_len;
00072   memcpy (name, socket->local_addr, sa_len);
00073
00074 #if defined(USE_IPV6)
00075   if (socket->so_family == AF_INET6)
00076   {
00077     const struct sockaddr_in6 *la = (const struct sockaddr_in6*)socket->local_addr;
00078
00079     SOCK_DEBUGF ((", %s (%d)", _inet6_ntoa(&la->sin6_addr), ntohs(la->sin6_port)));
00080     ARGSUSED (la);
00081   }
00082   else
00083 #endif
00084   {
00085     const struct sockaddr_in *la = socket->local_addr;
00086
00087     SOCK_DEBUGF ((", %s (%d)", inet_ntoa(la->sin_addr), ntohs(la->sin_port)));
00088     ARGSUSED (la);
00089   }
00090   return (0);
00091 }
00092
00093 int W32_CALL getpeername (int s, struct sockaddr *name, int *namelen)
00094 {
00095   Socket *socket = _socklist_find (s);
00096   int     sa_len;
00097
00098   SOCK_PROLOGUE (socket, "\ngetpeername:%d", s);
00099
00100   sa_len = (socket->so_family == AF_INET6) ? sizeof(struct sockaddr_in6) :
00101                                              sizeof(struct sockaddr_in);
00102
00103   if (!name || !namelen || (*namelen < sa_len))
00104   {
00105     SOCK_DEBUGF ((", EINVAL"));
00106     SOCK_ERRNO (EINVAL);
00107     if (namelen)
00108        *namelen = 0;
00109     return (-1);
00110   }
00111
00112   if (!(socket->so_state & SS_ISCONNECTED))
00113   {
00114     SOCK_DEBUGF ((", ENOTCONN"));
00115     SOCK_ERRNO (ENOTCONN);
00116     return (-1);
00117   }
00118   VERIFY_RW (name, *namelen);
00119
00120   *namelen = sa_len;
00121   memcpy (name, socket->remote_addr, *namelen);
00122
00123 #if defined(USE_IPV6)
00124   if (socket->so_family == AF_INET6)
00125   {
00126     const struct sockaddr_in6 *ra = (const struct sockaddr_in6*)socket->remote_addr;
00127     SOCK_DEBUGF ((", %s (%d)", _inet6_ntoa(&ra->sin6_addr), ntohs(ra->sin6_port)));
00128     ARGSUSED (ra);
00129   }
00130   else
00131 #endif
00132   {
00133     const struct sockaddr_in *ra = socket->remote_addr;
00134     SOCK_DEBUGF ((", %s (%d)", inet_ntoa(ra->sin_addr), ntohs(ra->sin_port)));
00135     ARGSUSED (ra);
00136   }
00137   return (0);
00138 }
00139 #endif
Generated on Wed Jan 25 15:42:34 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/GETNET.C Source File

SRC/GETNET.C

Go to the documentation of this file.
00001
00006 /*  Copyright (c) 1997-2002 Gisle Vanem <giva@bgnett.no>
00007  *
00008  *  Redistribution and use in source and binary forms, with or without
00009  *  modification, are permitted provided that the following conditions
00010  *  are met:
00011  *  1. Redistributions of source code must retain the above copyright
00012  *     notice, this list of conditions and the following disclaimer.
00013  *  2. Redistributions in binary form must reproduce the above copyright
00014  *     notice, this list of conditions and the following disclaimer in the
00015  *     documentation and/or other materials provided with the distribution.
00016  *  3. All advertising materials mentioning features or use of this software
00017  *     must display the following acknowledgement:
00018  *       This product includes software developed by Gisle Vanem
00019  *       Bergen, Norway.
00020  *
00021  *  THIS SOFTWARE IS PROVIDED BY ME (Gisle Vanem) AND CONTRIBUTORS ``AS IS''
00022  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00023  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00024  *  ARE DISCLAIMED.  IN NO EVENT SHALL I OR CONTRIBUTORS BE LIABLE FOR ANY
00025  *  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00026  *  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00027  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00028  *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00029  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00030  *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00031  *
00032  *
00033  *  18.aug 1996 - Created
00034  */
00035
00036 #include <stdio.h>
00037 #include <stdlib.h>
00038 #include <string.h>
00039 #include <arpa/inet.h>
00040
00041 #include "wattcp.h"
00042 #include "misc.h"
00043 #include "pcconfig.h"
00044 #include "language.h"
00045 #include "strings.h"
00046 #include "get_xby.h"
00047
00048 #if defined(USE_BSD_API)
00049
00050 static struct _netent *network0 = NULL;
00051 static char   *networkFname     = NULL;
00052 static FILE   *networkFile      = NULL;
00053 static BOOL    networkClose     = FALSE;
00054
00055 static __inline struct netent *fill_netent (const struct _netent *n)
00056 {
00057   static struct netent ret;
00058   static char   name [MAX_NAMELEN];
00059   static char  *aliases [MAX_NETENT_ALIASES+1];
00060
00061   memcpy (&aliases, n->n_aliases, sizeof(aliases));
00062   ret.n_name     = StrLcpy (name, n->n_name, sizeof(name));
00063   ret.n_aliases  = aliases;
00064   ret.n_net      = n->n_net;
00065   ret.n_addrtype = AF_INET;
00066   return (&ret);
00067 }
00068
00069 void ReadNetworksFile (const char *fname)
00070 {
00071   static BOOL been_here = FALSE;
00072
00073   if (!fname || !*fname)
00074      return;
00075
00076   if (been_here)  /* loading multiple network files */
00077   {
00078     free (networkFname);
00079     fclose (networkFile);
00080     networkFile = NULL;
00081   }
00082
00083   networkFname = strdup (fname);
00084   if (!networkFname)
00085      return;
00086
00087   setnetent (1);
00088   if (!networkFile)
00089      return;
00090
00091   been_here = TRUE;
00092
00093   while (1)
00094   {
00095     struct netent  *n = getnetent();
00096     struct _netent *n2;
00097     int    i;
00098
00099     if (!n)
00100        break;
00101
00102     n2 = (struct _netent*) calloc (sizeof(*n2), 1);
00103     if (!n2)
00104     {
00105       outs (networkFname);
00106       outsnl (_LANG(" too big!"));
00107       break;
00108     }
00109
00110     for (i = 0; n->n_aliases[i]; i++)
00111         n2->n_aliases[i] = strdup (n->n_aliases[i]);
00112     n2->n_net      = n->n_net;
00113     n2->n_addrtype = n->n_addrtype;
00114     n2->n_name     = strdup (n->n_name);
00115     if (!n2->n_name)
00116        break;
00117     n2->n_next = network0;
00118     network0   = n2;
00119   }
00120   rewind (networkFile);
00121   RUNDOWN_ADD (endnetent, 251);
00122
00123 #if 0  /* test */
00124   {
00125     struct _netent *n;
00126
00127     printf ("\n%s entries:\n", networkFname);
00128
00129     for (n = network0; n; n = n->n_next)
00130     {
00131       int i;
00132       printf ("net %-15.15s name %-10.10s  Aliases:",
00133               inet_ntoa(inet_makeaddr(n->n_net,0)), n->n_name);
00134       for (i = 0; n->n_aliases[i]; i++)
00135           printf (" %s,", n->n_aliases[i]);
00136       puts ("");
00137     }
00138     fflush (stdout);
00139   }
00140 #endif
00141 }
00142
00143 /*
00144  * Return name of networks file
00145  */
00146 const char *GetNetFile (void)
00147 {
00148   return (networkFname);
00149 }
00150
00151 /*
00152  * To prevent running out of file-handles, one should close the
00153  * 'networks' file before spawning a new shell.
00154  */
00155 void CloseNetworksFile (void)
00156 {
00157   fclose (networkFile);
00158   networkFile = NULL;
00159 }
00160
00161 void ReopenNetworksFile (void)
00162 {
00163   ReadNetworksFile (networkFname);
00164 }
00165
00166 /*
00167  * Return the next (non-commented) line from the network-file
00168  * Format is:
00169  *   name [=] net [alias..] {\n | # ..}
00170  *
00171  * e.g.
00172  *   loopback     127
00173  *   arpanet      10   arpa
00174  */
00175 struct netent * W32_CALL getnetent (void)
00176 {
00177   struct _netent n;
00178   char  *name, *net, *alias;
00179   char   buf [2*MAX_NAMELEN], *tok;
00180   int    i;
00181
00182   if (!netdb_init())
00183      return (NULL);
00184
00185   while (1)
00186   {
00187     if (!fgets(buf,sizeof(buf),networkFile))
00188        return (NULL);
00189
00190     tok = strltrim (buf);
00191     if (*tok == '#' || *tok == ';' || *tok == '\n')
00192        continue;
00193
00194     name = strtok (tok, " \t");
00195     net  = strtok (NULL, "= \t\n");
00196     if (name && net)
00197        break;
00198   }
00199
00200   if (networkClose)
00201      endnetent();
00202
00203   memset (&n, 0, sizeof(n));
00204   n.n_net  = inet_network (net);
00205   n.n_name = name;
00206   alias    = strtok (NULL, " \t\n");
00207
00208   for (i = 0; alias && i < MAX_NETENT_ALIASES; i++)
00209   {
00210     static char aliases [MAX_NETENT_ALIASES][MAX_NAMELEN];
00211
00212     if (*alias == '#' || *alias == ';')
00213        break;
00214
00215     n.n_aliases[i] = StrLcpy (aliases[i], alias, sizeof(aliases[i]));
00216     alias = strtok (NULL, " \t\n");
00217   }
00218   return fill_netent (&n);
00219 }
00220
00221 /*
00222  * Return a 'netent' structure for network 'name' or
00223  * NULL if not found.
00224  */
00225 struct netent * W32_CALL getnetbyname (const char *name)
00226 {
00227   const struct _netent *n;
00228
00229   if (!netdb_init() || !name)
00230      return (NULL);
00231
00232   for (n = network0; n; n = n->n_next)
00233   {
00234     int i;
00235
00236     if (n->n_name && !stricmp(n->n_name,name))
00237        return fill_netent (n);
00238
00239     for (i = 0; n->n_aliases[i]; i++)
00240         if (!stricmp(name,n->n_aliases[i]))
00241            return fill_netent (n);
00242   }
00243   return (NULL);
00244 }
00245
00246 /*
00247  * Return a 'netent' structure for network number 'net' or
00248  * NULL if not found.
00249  */
00250 struct netent * W32_CALL getnetbyaddr (long net, int type)
00251 {
00252   const struct _netent *n;
00253
00254   if (!netdb_init())
00255      return (NULL);
00256
00257   for (n = network0; n; n = n->n_next)
00258       if ((u_long)net == n->n_net && type == n->n_addrtype && n->n_name)
00259          return fill_netent (n);
00260   return (NULL);
00261 }
00262
00263 /*
00264  * Open the network file.
00265  */
00266 void W32_CALL setnetent (int stayopen)
00267 {
00268   networkClose = (stayopen == 0);
00269
00270   if (!netdb_init() || !networkFname)
00271      return;
00272
00273   if (!networkFile)
00274        networkFile = fopen (networkFname, "rt");
00275   else rewind (networkFile);
00276 }
00277
00278 /*
00279  * Close the network file and free associated memory
00280  */
00281 void W32_CALL endnetent (void)
00282 {
00283   struct _netent *n, *next;
00284
00285   if (_watt_fatal_error)
00286      return;
00287
00288   if (networkFname)
00289      free (networkFname);
00290   if (networkFile)
00291      fclose (networkFile);
00292   networkFname = NULL;
00293   networkFile  = NULL;
00294
00295   for (n = network0; n; n = next)
00296   {
00297     int i;
00298     for (i = 0; n->n_aliases[i]; i++)
00299         free (n->n_aliases[i]);
00300     next = n->n_next;
00301     free (n->n_name);
00302     free (n);
00303   }
00304   network0 = NULL;
00305   networkClose = TRUE;
00306 }
00307 #endif /* USE_BSD_API */
Generated on Wed Jan 25 15:42:34 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/GETOPT.C Source File

SRC/GETOPT.C

Go to the documentation of this file.
00001
00005 /* (emx+gcc) -- Copyright (c) 1990-1993 by Eberhard Mattes
00006  * Adapted for Waterloo TCP/IP by G. Vanem Nov-96
00007  */
00008
00009 #include <stdio.h>
00010 #include <stdlib.h>
00011 #include <string.h>
00012
00013 #if !defined(__DJGPP__)
00014 /*
00015  * Must compile this with MingW so a WATT-32.dll built with
00016  * MingW can be used with MSVC.
00017  */
00018 #include "wattcp.h"
00019 #include "language.h"
00020 #include "strings.h"
00021 #include "getopt.h"
00022
00023 char *optarg          = NULL;
00024 int   optopt          = 0;
00025 int   optind          = 0;        /* Default: first call */
00026 int   opterr          = 1;        /* Default: error messages enabled */
00027 char *optswchar       = "-/";     /* '-' or '/' starts options */
00028 enum _optmode optmode = GETOPT_UNIX;
00029
00030 static char *next_opt;        /* Next character in cluster of options */
00031 static char *empty = "";      /* Empty string */
00032
00033 static BOOL done;
00034 static char sw_char;
00035
00036 static char **options;        /* List of entries which are options */
00037 static char **non_options;    /* List of entries which are not options */
00038 static int    options_count;
00039 static int    non_options_count;
00040
00041 #define PUT(dst) do {                                    \
00042                    if (optmode == GETOPT_ANY)            \
00043                       dst[dst##_count++] = argv[optind]; \
00044                   } while (0)
00045
00046 #undef ERROR
00047
00048 #if defined(USE_DEBUG)
00049   #define ERROR(str,fmt,ch)  printf (str), printf (fmt, ch), puts ("")
00050 #else    /* avoid pulling in printf() */
00051   #define ERROR(str,fmt,ch)  outsnl (str)
00052 #endif
00053
00054
00055 int getopt (int argc, char *const *_argv, const char *opt_str)
00056 {
00057   char  c;
00058   char *q;
00059   int   i, j;
00060   char **argv = (char **) _argv;
00061
00062   if (optind == 0)
00063   {
00064     optind   = 1;
00065     done     = FALSE;
00066     next_opt = empty;
00067     if (optmode == GETOPT_ANY)
00068     {
00069       options     = (char**) malloc (argc * sizeof(char*));
00070       non_options = (char**) malloc (argc * sizeof(char*));
00071       if (!options || !non_options)
00072       {
00073         outsnl ("out of memory (getopt)");
00074         exit (255);
00075       }
00076       options_count     = 0;
00077       non_options_count = 0;
00078     }
00079   }
00080   if (done)
00081      return (EOF);
00082
00083 restart:
00084   optarg = NULL;
00085   if (*next_opt == 0)
00086   {
00087     if (optind >= argc)
00088     {
00089       if (optmode == GETOPT_ANY)
00090       {
00091         j = 1;
00092         for (i = 0; i < options_count; ++i)
00093             argv[j++] = options[i];
00094         for (i = 0; i < non_options_count; ++i)
00095             argv[j++] = non_options[i];
00096         optind = options_count+1;
00097         free (options);
00098         free (non_options);
00099       }
00100       done = TRUE;
00101       return (EOF);
00102     }
00103     else if (!strchr (optswchar, argv[optind][0]) || argv[optind][1] == 0)
00104     {
00105       if (optmode == GETOPT_UNIX)
00106       {
00107         done = TRUE;
00108         return (EOF);
00109       }
00110       PUT (non_options);
00111       optarg = argv[optind++];
00112       if (optmode == GETOPT_ANY)
00113          goto restart;
00114       /* optmode==GETOPT_KEEP */
00115       return (0);
00116     }
00117     else if (argv[optind][0] == argv[optind][1] && argv[optind][2] == 0)
00118     {
00119       if (optmode == GETOPT_ANY)
00120       {
00121         j = 1;
00122         for (i = 0; i < options_count; ++i)
00123             argv[j++] = options[i];
00124         argv[j++] = argv[optind];
00125         for (i = 0; i < non_options_count; ++i)
00126             argv[j++] = non_options[i];
00127         for (i = optind+1; i < argc; ++i)
00128             argv[j++] = argv[i];
00129         optind = options_count+2;
00130         free (options);
00131         free (non_options);
00132       }
00133       ++optind;
00134       done = TRUE;
00135       return (EOF);
00136     }
00137     else
00138     {
00139       PUT (options);
00140       sw_char  = argv[optind][0];
00141       next_opt = argv[optind]+1;
00142     }
00143   }
00144   c = *next_opt++;
00145   if (*next_opt == 0)  /* Move to next argument if end of argument reached */
00146      optind++;
00147   if (c == ':' || (q = strchr (opt_str, c)) == NULL)
00148   {
00149     if (opterr)
00150     {
00151       if (c < ' ' || c >= 127)
00152            ERROR ("Invalid option", "; character code=0x%.2x", c);
00153       else ERROR ("Invalid option", "/%c", c);
00154     }
00155     optopt = '?';
00156     return ('?');
00157   }
00158   if (q[1] == ':')
00159   {
00160     if (*next_opt != 0)         /* Argument given */
00161     {
00162       optarg = next_opt;
00163       next_opt = empty;
00164       ++optind;
00165     }
00166     else if (q[2] == ':')
00167       optarg = NULL;            /* Optional argument missing */
00168     else if (optind >= argc)
00169     {                           /* Required argument missing */
00170       if (opterr)
00171          ERROR ("No argument for option"," `/%c'", c);
00172       c = '?';
00173     }
00174     else
00175     {
00176       PUT (options);
00177       optarg = argv[optind++];
00178     }
00179   }
00180   optopt = c;
00181   return (c);
00182 }
00183 #endif  /* !__DJGPP__ && !__MINGW32__ */
00184
Generated on Wed Jan 25 15:42:34 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/GETOPT.H Source File

SRC/GETOPT.H

Go to the documentation of this file.
00001
00003 #ifndef _w32_GETOPT_H
00004 #define _w32_GETOPT_H
00005
00006 #if defined(__DJGPP__)
00007   #include <unistd.h>
00008
00009 #else
00010   #define optarg    NAMESPACE (optarg)
00011   #define optind    NAMESPACE (optind)
00012   #define opterr    NAMESPACE (opterr)
00013   #define optopt    NAMESPACE (optopt)
00014   #define optswchar NAMESPACE (optswchar)
00015   #define optmode   NAMESPACE (optmode)
00016   #define getopt    NAMESPACE (getopt)
00017
00018   W32_DATA char *optarg;     /* argument of current option                    */
00019   W32_DATA int   optind;     /* index of next argument; default=0: initialize */
00020   W32_DATA int   opterr;     /* 0=disable error messages; default=1: enable   */
00021   W32_DATA char *optswchar;  /* characters prefixing options; default="-"     */
00022
00023   W32_DATA enum _optmode {
00024            GETOPT_UNIX,      /* options at start of argument list (default)   */
00025            GETOPT_ANY,       /* move non-options to the end                   */
00026            GETOPT_KEEP,      /* return options in order                       */
00027          } optmode;
00028
00029   W32_FUNC int getopt (int argc, char *const *argv, const char *opt_str);
00030
00031 #endif
00032 #endif
Generated on Wed Jan 25 15:42:34 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/GETPROT.C Source File

SRC/GETPROT.C

Go to the documentation of this file.
00001
00006 /*  Copyright (c) 1997-2002 Gisle Vanem <giva@bgnett.no>
00007  *
00008  *  Redistribution and use in source and binary forms, with or without
00009  *  modification, are permitted provided that the following conditions
00010  *  are met:
00011  *  1. Redistributions of source code must retain the above copyright
00012  *     notice, this list of conditions and the following disclaimer.
00013  *  2. Redistributions in binary form must reproduce the above copyright
00014  *     notice, this list of conditions and the following disclaimer in the
00015  *     documentation and/or other materials provided with the distribution.
00016  *  3. All advertising materials mentioning features or use of this software
00017  *     must display the following acknowledgement:
00018  *       This product includes software developed by Gisle Vanem
00019  *       Bergen, Norway.
00020  *
00021  *  THIS SOFTWARE IS PROVIDED BY ME (Gisle Vanem) AND CONTRIBUTORS ``AS IS''
00022  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00023  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00024  *  ARE DISCLAIMED.  IN NO EVENT SHALL I OR CONTRIBUTORS BE LIABLE FOR ANY
00025  *  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00026  *  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00027  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00028  *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00029  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00030  *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00031  *
00032  *
00033  *  21.aug 1996 - Created
00034  */
00035
00036 #include <stdio.h>
00037 #include <stdlib.h>
00038 #include <string.h>
00039 #include <ctype.h>
00040
00041 #include "wattcp.h"
00042 #include "strings.h"
00043 #include "misc.h"
00044 #include "language.h"
00045 #include "pcconfig.h"
00046 #include "get_xby.h"
00047
00048 #if defined(USE_BSD_API)
00049
00050 static struct _protoent *proto0 = NULL;
00051 static char   *protoFname       = NULL;
00052 static FILE   *protoFile        = NULL;
00053 static BOOL    protoClose       = FALSE;
00054
00055 static __inline struct protoent *fill_protoent (const struct _protoent *p)
00056 {
00057   static struct protoent ret;
00058   static char   name [30];
00059   static char  *aliases [MAX_PROTO_ALIASES+1];
00060
00061   memcpy (&aliases, p->p_aliases, sizeof(aliases));
00062   ret.p_name    = StrLcpy (name, p->p_name, sizeof(name));
00063   ret.p_proto   = p->p_proto;
00064   ret.p_aliases = aliases;
00065   h_errno       = NETDB_SUCCESS;
00066   return (&ret);
00067 }
00068
00069 /*------------------------------------------------------------------*/
00070
00071 void ReadProtoFile (const char *fname)
00072 {
00073   static BOOL been_here = FALSE;
00074
00075   if (!fname || !*fname)
00076      return;
00077
00078   if (been_here)  /* loading multiple protocol files */
00079   {
00080     free (protoFname);
00081     fclose (protoFile);
00082     protoFile = NULL;
00083   }
00084
00085   protoFname = strdup (fname);
00086   if (!protoFname)
00087      return;
00088
00089   setprotoent (1);
00090   if (!protoFile)
00091      return;
00092
00093   been_here = TRUE;
00094
00095   while (1)
00096   {
00097     struct  protoent *p = getprotoent();
00098     struct _protoent *p2;
00099     int    i;
00100
00101     if (!p)
00102        break;
00103
00104     p2 = (struct _protoent*) calloc (sizeof(*p2), 1);
00105     if (!p2)
00106     {
00107       outs (protoFname);
00108       outsnl (_LANG(" too big!"));
00109       break;
00110     }
00111     for (i = 0; p->p_aliases[i]; i++)
00112         p2->p_aliases[i] = strdup (p->p_aliases[i]);
00113     p2->p_proto = p->p_proto;
00114     p2->p_name  = strdup (p->p_name);
00115
00116     if (!p2->p_name)
00117        break;
00118
00119     p2->p_next = proto0;
00120     proto0     = p2;
00121   }
00122   rewind (protoFile);
00123   RUNDOWN_ADD (endprotoent, 257);
00124
00125 #if 0  /* test */
00126   {
00127     const struct _protoent *p;
00128     int   i;
00129
00130     printf ("\n%s entries:\n", protoFname);
00131     for (p = proto0; p; p = p->p_next)
00132     {
00133       printf ("proto %3d  name %-10.10s  Aliases:", p->p_proto, p->p_name);
00134       for (i = 0; p->p_aliases[i]; i++)
00135           printf (" %s,", p->p_aliases[i]);
00136       puts ("");
00137     }
00138     fflush (stdout);
00139   }
00140 #endif
00141 }
00142
00143 /*------------------------------------------------------------------*/
00144
00145 const char *GetProtoFile (void)
00146 {
00147   return (protoFname);
00148 }
00149
00150 void CloseProtoFile (void)
00151 {
00152   fclose (protoFile);
00153   protoFile = NULL;
00154 }
00155
00156 void ReopenProtoFile (void)
00157 {
00158   ReadProtoFile (protoFname);
00159 }
00160
00161 /*------------------------------------------------------------------*/
00162
00163 struct protoent * W32_CALL getprotoent (void)
00164 {
00165   static struct _protoent p;
00166   char  *proto, *name;
00167
00168   if (!netdb_init() || !protoFile)
00169   {
00170     h_errno = NO_DATA;
00171     return (NULL);
00172   }
00173
00174   /*  Protocol  Name
00175    *  ----------------------------------------
00176    *  0         reserved
00177    *  1         icmp, internet control message
00178    *  2         igmp, internet group management
00179    *  3         ggp, # gateway-gateway protocol
00180    */
00181
00182   while (1)
00183   {
00184     char buf [2*MAX_NAMELEN], *tok;
00185
00186     if (!fgets(buf,sizeof(buf),protoFile))
00187     {
00188       h_errno = NO_DATA;
00189       return (NULL);
00190     }
00191
00192     tok = strltrim (buf);
00193     if (*tok == '#' || *tok == ';' || *tok == '\n')
00194        continue;
00195
00196     proto = strtok (tok, " \t");
00197     name  = strtok (NULL, " ,\t\n");
00198     if (proto && name)
00199        break;
00200   }
00201
00202   if (protoClose)
00203      endprotoent();
00204
00205   memset (&p, 0, sizeof(p));
00206   p.p_proto = atoi (proto);
00207   p.p_name  = name;
00208   return fill_protoent (&p);
00209 }
00210
00211 /*------------------------------------------------------------------*/
00212
00213 struct protoent * W32_CALL getprotobyname (const char *proto)
00214 {
00215   struct _protoent fixed;
00216   const struct _protoent *p;
00217   int   i;
00218
00219   memset (&fixed, 0, sizeof(fixed));
00220
00221   if (!netdb_init() || !proto)
00222   {
00223     h_errno = NO_DATA;
00224     return (NULL);
00225   }
00226
00227   /* No chances UDP/TCP protocols are renumbered
00228    */
00229   if (!stricmp(proto,"udp"))
00230   {
00231     fixed.p_name  = "udp";
00232     fixed.p_proto = UDP_PROTO;
00233     return fill_protoent (&fixed);
00234   }
00235
00236   if (!stricmp(proto,"tcp"))
00237   {
00238     fixed.p_name  = "tcp";
00239     fixed.p_proto = TCP_PROTO;
00240     return fill_protoent (&fixed);
00241   }
00242
00243   for (p = proto0; p; p = p->p_next)
00244   {
00245     if (p->p_name && !stricmp(p->p_name,proto))
00246        return fill_protoent (p);
00247
00248     /* aliases not supported (no need)
00249      */
00250     for (i = 0; p->p_aliases[i]; i++)
00251         if (!stricmp(proto,p->p_aliases[i]))
00252            return fill_protoent (p);
00253   }
00254   h_errno = NO_DATA;
00255   return (NULL);
00256 }
00257
00258 /*------------------------------------------------------------------*/
00259
00260 struct protoent * W32_CALL getprotobynumber (int proto)
00261 {
00262   const struct _protoent *p;
00263
00264   if (!netdb_init())
00265   {
00266     h_errno = NO_DATA;
00267     return (NULL);
00268   }
00269
00270   for (p = proto0; p; p = p->p_next)
00271       if (p->p_proto == proto)
00272          return fill_protoent (p);
00273   h_errno = NO_DATA;
00274   return (NULL);
00275 }
00276
00277 /*------------------------------------------------------------------*/
00278
00279 void W32_CALL setprotoent (int stayopen)
00280 {
00281   protoClose = (stayopen == 0);
00282
00283   if (!netdb_init() || !protoFname)
00284      return;
00285
00286   if (!protoFile)
00287        protoFile = fopen (protoFname, "rt");
00288   else rewind (protoFile);
00289 }
00290
00291 /*------------------------------------------------------------------*/
00292
00293 void W32_CALL endprotoent (void)
00294 {
00295   struct _protoent *p, *next;
00296
00297   if (_watt_fatal_error)
00298      return;
00299
00300   if (protoFname)
00301      free (protoFname);
00302   if (protoFile)
00303      fclose (protoFile);
00304   protoFname = NULL;
00305   protoFile  = NULL;
00306
00307   for (p = proto0; p; p = next)
00308   {
00309     int i;
00310     for (i = 0; p->p_aliases[i]; i++)
00311         free (p->p_aliases[i]);
00312     next = p->p_next;
00313     free (p->p_name);
00314     free (p);
00315   }
00316   proto0 = NULL;
00317   protoClose = TRUE;
00318 }
00319 #endif  /* USE_BSD_API */
Generated on Wed Jan 25 15:42:34 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/GETPUT.C Source File

SRC/GETPUT.C

Go to the documentation of this file.
00001
00006 /*  Copyright (c) 1997-2002 Gisle Vanem <giva@bgnett.no>
00007  *
00008  *  Redistribution and use in source and binary forms, with or without
00009  *  modification, are permitted provided that the following conditions
00010  *  are met:
00011  *  1. Redistributions of source code must retain the above copyright
00012  *     notice, this list of conditions and the following disclaimer.
00013  *  2. Redistributions in binary form must reproduce the above copyright
00014  *     notice, this list of conditions and the following disclaimer in the
00015  *     documentation and/or other materials provided with the distribution.
00016  *  3. All advertising materials mentioning features or use of this software
00017  *     must display the following acknowledgement:
00018  *       This product includes software developed by Gisle Vanem
00019  *       Bergen, Norway.
00020  *
00021  *  THIS SOFTWARE IS PROVIDED BY ME (Gisle Vanem) AND CONTRIBUTORS ``AS IS''
00022  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00023  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00024  *  ARE DISCLAIMED.  IN NO EVENT SHALL I OR CONTRIBUTORS BE LIABLE FOR ANY
00025  *  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00026  *  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00027  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00028  *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00029  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00030  *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00031  *
00032  */
00033
00034 #include "wattcp.h"
00035 #include "chksum.h"
00036 #include "misc.h"
00037
00038 /*
00039  * Functions for get/put short/long. Pointer is _NOT_ advanced.
00040  */
00041 #if !defined(USE_BIGENDIAN)
00042
00043 #define GETSHORT(s, cp) {            \
00044         BYTE *t_cp = (BYTE*)(cp);    \
00045         (s) = ((WORD)t_cp[0] << 8)   \
00046             | ((WORD)t_cp[1]);       \
00047       }
00048
00049 #define GETLONG(l, cp) {             \
00050         BYTE *t_cp = (BYTE*)(cp);    \
00051         (l) = ((DWORD)t_cp[0] << 24) \
00052             | ((DWORD)t_cp[1] << 16) \
00053             | ((DWORD)t_cp[2] << 8)  \
00054             | ((DWORD)t_cp[3]);      \
00055       }
00056
00057 #define PUTSHORT(s, cp) {            \
00058         WORD  t_s  = (WORD)(s);      \
00059         BYTE *t_cp = (BYTE*)(cp);    \
00060         *t_cp++ = (BYTE)(t_s >> 8);  \
00061         *t_cp   = (BYTE)t_s;         \
00062       }
00063
00064 #define PUTLONG(l, cp) {             \
00065         DWORD t_l  = (DWORD)(l);     \
00066         BYTE *t_cp = (BYTE*)(cp);    \
00067         *t_cp++ = (BYTE)(t_l >> 24); \
00068         *t_cp++ = (BYTE)(t_l >> 16); \
00069         *t_cp++ = (BYTE)(t_l >> 8);  \
00070         *t_cp   = (BYTE)t_l;         \
00071       }
00072
00073 WORD _getshort (const BYTE *x)   /* in <arpa/nameserv.h> */
00074 {
00075   WORD res;
00076   GETSHORT (res, x);
00077   return (res);
00078 }
00079
00080 DWORD _getlong (const BYTE *x)   /* in <arpa/nameserv.h> */
00081 {
00082   DWORD res;
00083   GETLONG (res, x);
00084   return (res);
00085 }
00086
00087 void __putshort (WORD var, BYTE *ptr)   /* in <resolv.h> */
00088 {
00089   PUTSHORT (var, ptr);
00090 }
00091
00092 void __putlong (DWORD var, BYTE *ptr)   /* in <resolv.h> */
00093 {
00094   PUTLONG (var, ptr);
00095 }
00096
00097 /*
00098  * If compiler/linker doesn't see our defines for htonl() etc.
00099  */
00100 #undef htonl
00101 #undef ntohl
00102 #undef htons
00103 #undef ntohs
00104
00105 DWORD W32_CALL htonl (DWORD val)
00106 {
00107   return intel (val);
00108 }
00109 DWORD W32_CALL ntohl (DWORD val)
00110 {
00111   return intel (val);
00112 }
00113 WORD W32_CALL htons (WORD val)
00114 {
00115   return intel16 (val);
00116 }
00117 WORD W32_CALL ntohs (WORD val)
00118 {
00119   return intel16 (val);
00120 }
00121 #endif  /* USE_BIGENDIAN */
Generated on Wed Jan 25 15:42:34 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/GETSERV.C Source File

SRC/GETSERV.C

Go to the documentation of this file.
00001
00006 /*  Copyright (c) 1997-2002 Gisle Vanem <giva@bgnett.no>
00007  *
00008  *  Redistribution and use in source and binary forms, with or without
00009  *  modification, are permitted provided that the following conditions
00010  *  are met:
00011  *  1. Redistributions of source code must retain the above copyright
00012  *     notice, this list of conditions and the following disclaimer.
00013  *  2. Redistributions in binary form must reproduce the above copyright
00014  *     notice, this list of conditions and the following disclaimer in the
00015  *     documentation and/or other materials provided with the distribution.
00016  *  3. All advertising materials mentioning features or use of this software
00017  *     must display the following acknowledgement:
00018  *       This product includes software developed by Gisle Vanem
00019  *       Bergen, Norway.
00020  *
00021  *  THIS SOFTWARE IS PROVIDED BY ME (Gisle Vanem) AND CONTRIBUTORS ``AS IS''
00022  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00023  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00024  *  ARE DISCLAIMED.  IN NO EVENT SHALL I OR CONTRIBUTORS BE LIABLE FOR ANY
00025  *  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00026  *  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00027  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00028  *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00029  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00030  *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00031  *
00032  *
00033  *  20.aug 1996 - Created
00034  */
00035
00036 #include <stdio.h>
00037 #include <stdlib.h>
00038 #include <string.h>
00039 #include <ctype.h>
00040
00041 #include "wattcp.h"
00042 #include "strings.h"
00043 #include "misc.h"
00044 #include "language.h"
00045 #include "netaddr.h"
00046 #include "pcconfig.h"
00047 #include "get_xby.h"
00048
00049 #if defined(USE_BSD_API)
00050
00051 #include <sys/socket.h>
00052 #include <netdb.h>
00053
00054 static struct _servent *serv0 = NULL;
00055 static char   *servFname      = NULL;
00056 static FILE   *servFile       = NULL;
00057 static BOOL    servClose      = FALSE;
00058
00059 /* For DOSX targets we use a small hash table to speed-up searches.
00060  */
00061 #if (DOSX)
00062   #define PORT_HASH_SIZE  256   /* must be 2^n */
00063   #define GET_HASH(p)     port_hash [(p) & (PORT_HASH_SIZE-1)]
00064   #define SET_HASH(se)    port_hash [se->s_port & (PORT_HASH_SIZE-1)] = se
00065   static struct _servent *port_hash [PORT_HASH_SIZE];
00066 #else
00067   #define GET_HASH(p)     serv0
00068   #define SET_HASH(p)     ((void)0)
00069 #endif
00070
00071 #define MAX_SERVLEN  20
00072 #define MAX_PROTLEN  20
00073
00074 static __inline struct servent *fill_servent (const struct _servent *s)
00075 {
00076   static struct servent ret;
00077   static char  name [MAX_SERVLEN];
00078   static char  prot [MAX_PROTLEN];
00079   static char *aliases [MAX_SERV_ALIASES+1];
00080
00081   memcpy (&aliases, s->s_aliases, sizeof(aliases));
00082   ret.s_name    = StrLcpy (name, s->s_name, sizeof(name));
00083   ret.s_proto   = StrLcpy (prot, s->s_proto, sizeof(prot));
00084   ret.s_aliases = aliases;
00085   ret.s_port    = s->s_port;
00086   h_errno       = NETDB_SUCCESS;
00087   return (&ret);
00088 }
00089
00090 /*
00091  * Read the \i services file and build linked-list.
00092  */
00093 void ReadServFile (const char *fname)
00094 {
00095   static BOOL been_here = FALSE;
00096
00097   if (!fname || !*fname)
00098      return;
00099
00100   if (been_here)  /* loading multiple services files */
00101   {
00102     free (servFname);
00103     fclose (servFile);
00104     servFile = NULL;
00105   }
00106   servFname = strdup (fname);
00107   if (!servFname)
00108      return;
00109
00110   setservent (1);
00111   if (!servFile)
00112      return;
00113
00114   been_here = TRUE;
00115
00116   while (1)
00117   {
00118     struct  servent *s = getservent();
00119     struct _servent *s2;
00120     int    i;
00121
00122     if (!s)
00123        break;
00124
00125     s2 = (struct _servent*) calloc (sizeof(*s2), 1);
00126     if (!s2)
00127     {
00128       outs (servFname);
00129       outsnl (_LANG(" too big!"));
00130       return;
00131     }
00132     for (i = 0; s->s_aliases[i]; i++)
00133         s2->s_aliases[i] = strdup (s->s_aliases[i]);
00134     s2->s_port  = s->s_port;
00135     s2->s_name  = strdup (s->s_name);
00136     s2->s_proto = strdup (s->s_proto);
00137
00138     if (!s2->s_name || !s2->s_proto)
00139        break;
00140
00141     s2->s_next = serv0;
00142     serv0      = s2;
00143     SET_HASH (s2);
00144   }
00145   rewind (servFile);
00146   RUNDOWN_ADD (endservent, 255);
00147 }
00148
00149 /*
00150  * Return name of \i /etc/services file.
00151  */
00152 const char *GetServFile (void)
00153 {
00154   return (servFname);
00155 }
00156
00157 /*
00158  * Close the \i /etc/services file.
00159  */
00160 void CloseServFile (void)
00161 {
00162   fclose (servFile);
00163   servFile = NULL;
00164 }
00165
00166 /*
00167  * Reopen the \i /etc/services file.
00168  */
00169 void ReopenServFile (void)
00170 {
00171   ReadServFile (servFname);
00172 }
00173
00174 /*------------------------------------------------------------------*/
00175
00176 struct servent * W32_CALL getservent (void)
00177 {
00178   static struct _servent s;
00179   char  *name, *proto, *alias;
00180   WORD   port;
00181   int    i;
00182
00183   if (!netdb_init() || !servFile)
00184   {
00185     h_errno = NO_DATA;
00186     return (NULL);
00187   }
00188
00189   while (1)
00190   {
00191     char buf[2*MAX_NAMELEN], *tok;
00192
00193     if (!fgets(buf,sizeof(buf),servFile))
00194     {
00195       h_errno = NO_DATA;
00196       return (NULL);
00197     }
00198
00199     tok = strltrim (buf);
00200     if (*tok == '#' || *tok == ';' || *tok == '\n')
00201        continue;
00202
00203     /*  # Service         port/prot       alias(es)
00204      *  #-------------------------------------------
00205      *    rtmp            1/ddp   <- we only support "udp"/"tcp"
00206      *    echo            7/tcp
00207      *    echo            7/udp
00208      *    discard         9/tcp           sink null
00209      *    discard         9/udp           sink null
00210      */
00211
00212     name = strtok (tok, " \t");
00213     tok  = strtok (NULL, "/ \t\n");
00214     if (!tok)
00215        continue;
00216     port  = intel16 (atoi(tok));
00217     proto = strtok (NULL, " \t\n");
00218     if (name && port && proto &&
00219         (!stricmp(proto,"udp") || !stricmp(proto,"tcp")))
00220        break;
00221   }
00222
00223   if (servClose)
00224      endservent();
00225
00226   memset (&s, 0, sizeof(s));
00227   s.s_name  = name;
00228   s.s_proto = proto;
00229   s.s_port  = port;
00230
00231   alias = strtok (NULL, " \t\n");
00232
00233   for (i = 0; alias && i < MAX_SERV_ALIASES; i++)
00234   {
00235     static char aliases [MAX_SERV_ALIASES][MAX_SERVLEN];
00236
00237     if (*alias == '#' || *alias == ';')
00238        break;
00239
00240     s.s_aliases[i] = StrLcpy (aliases[i], alias, sizeof(aliases[i]));
00241     alias = strtok (NULL, " \t\n");
00242   }
00243   return fill_servent (&s);
00244 }
00245
00246 /*------------------------------------------------------------------*/
00247
00248 struct servent * W32_CALL getservbyname (const char *serv, const char *proto)
00249 {
00250   const struct _servent *s;
00251   int   i;
00252
00253   if (!netdb_init() || !serv) /* proto == NULL is okay */
00254   {
00255     h_errno = NO_DATA;
00256     return (NULL);
00257   }
00258
00259   for (s = serv0; s; s = s->s_next)
00260   {
00261     BOOL chk_prot = FALSE;
00262
00263     if (s->s_name && !stricmp(s->s_name,serv))
00264        chk_prot = TRUE;
00265
00266     else for (i = 0; s->s_aliases[i]; i++)
00267              if (!stricmp(serv,s->s_aliases[i]))
00268              {
00269                chk_prot = TRUE;
00270                break;
00271              }
00272     if (chk_prot && (!proto || !stricmp(proto,s->s_proto)))
00273        return fill_servent (s);
00274   }
00275   h_errno = NO_DATA;
00276   return (NULL);
00277 }
00278
00279 /*------------------------------------------------------------------*/
00280
00281 struct servent * W32_CALL getservbyport (int port, const char *proto)
00282 {
00283   const struct _servent *s;
00284
00285   if (!netdb_init() || !proto)  /* proto == NULL is okay */
00286   {
00287     h_errno = NO_DATA;
00288     return (NULL);
00289   }
00290
00291   for (s = GET_HASH(port); s; s = s->s_next)
00292       if (s->s_port == port &&
00293           (!proto || !stricmp(s->s_proto,proto)))
00294          return fill_servent (s);
00295   h_errno = NO_DATA;
00296   return (NULL);
00297 }
00298
00299 /*------------------------------------------------------------------*/
00300
00301 void W32_CALL setservent (int stayopen)
00302 {
00303   servClose = (stayopen == 0);
00304   if (!netdb_init() || !servFname)
00305      return;
00306
00307   if (!servFile)
00308        servFile = fopen (servFname, "rt");
00309   else rewind (servFile);
00310 }
00311
00312 /*------------------------------------------------------------------*/
00313
00314 void W32_CALL endservent (void)
00315 {
00316   struct _servent *s, *next;
00317
00318   if (_watt_fatal_error)
00319      return;
00320
00321   if (servFname)
00322      free (servFname);
00323   if (servFile)
00324      fclose (servFile);
00325   servFname = NULL;
00326   servFile  = NULL;
00327
00328   for (s = serv0; s; s = next)
00329   {
00330     int i;
00331     for (i = 0; s->s_aliases[i]; i++)
00332         free (s->s_aliases[i]);
00333     next = s->s_next;
00334     free (s->s_name);
00335     free (s->s_proto);
00336     free (s);
00337   }
00338   serv0 = NULL;
00339   servClose = TRUE;
00340 }
00341 #endif /* USE_BSD_API */
00342
00343 #if defined(TEST_PROG)
00344
00345 #include "pcdbug.h"
00346 #include "sock_ini.h"
00347
00348 int main (void)
00349 {
00350   const struct _servent *s;
00351   int   i;
00352
00353   dbug_init();
00354   sock_init();
00355
00356   printf ("\n%s entries:\n", servFname);
00357
00358   for (s = serv0; s; s = s->s_next)
00359   {
00360     printf ("proto %-6.6s  port %4d  name %-10.10s  Aliases:",
00361             s->s_proto, intel16(s->s_port), s->s_name);
00362     for (i = 0; s->s_aliases[i]; i++)
00363          printf (" %s", s->s_aliases[i]);
00364     puts ("");
00365   }
00366   fflush (stdout);
00367   return (0);
00368 }
00369 #endif /* TEST_PROG */
00370
00371
Generated on Wed Jan 25 15:42:34 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/GETTOD.C Source File

SRC/GETTOD.C

Go to the documentation of this file.
00001
00007 /*  Copyright (c) 1997-2002 Gisle Vanem <giva@bgnett.no>
00008  *
00009  *  Redistribution and use in source and binary forms, with or without
00010  *  modification, are permitted provided that the following conditions
00011  *  are met:
00012  *  1. Redistributions of source code must retain the above copyright
00013  *     notice, this list of conditions and the following disclaimer.
00014  *  2. Redistributions in binary form must reproduce the above copyright
00015  *     notice, this list of conditions and the following disclaimer in the
00016  *     documentation and/or other materials provided with the distribution.
00017  *  3. All advertising materials mentioning features or use of this software
00018  *     must display the following acknowledgement:
00019  *       This product includes software developed by Gisle Vanem
00020  *       Bergen, Norway.
00021  *
00022  *  THIS SOFTWARE IS PROVIDED BY ME (Gisle Vanem) AND CONTRIBUTORS ``AS IS''
00023  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00024  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00025  *  ARE DISCLAIMED.  IN NO EVENT SHALL I OR CONTRIBUTORS BE LIABLE FOR ANY
00026  *  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00027  *  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00028  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00029  *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00030  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00031  *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00032  *
00033  *
00034  *  10.aug 1996 - Created
00035  *
00036  */
00037
00038 #include <stdio.h>
00039 #include <stdlib.h>
00040 #include <stddef.h>
00041 #include <time.h>
00042 #include <errno.h>
00043
00044 #include "wattcp.h"
00045 #include "misc.h"
00046 #include "timer.h"
00047 #include "x32vm.h"
00048 #include "cpumodel.h"
00049 #include "strings.h"
00050 #include "gettod.h"
00051
00052 #if defined(WIN32)
00053 #include <sys/timeb.h>
00054 #endif
00055
00056 /*
00057  * Timezone defines.
00058  */
00059 #if defined(__WATCOMC__)
00060   #define _timezone timezone
00061 #elif defined(__TURBOC__) && (__TURBOC__ <= 0x410)  /* TCC/BCC <= 3.1 */
00062   #define _timezone timezone
00063 #elif defined(__POCC__)
00064   #define _timezone 0
00065 #elif defined(_MSC_VER) && (_MSC_VER <= 600)
00066   #define _timezone timezone
00067 #endif
00068
00069 #if defined(__CCDL__)
00070 #define int386 _int386
00071 #endif
00072
00073 #ifndef __inline
00074 #define __inline
00075 #endif
00076
00077 static long utc_offset = 0;  /* UTC to local offset in seconds */
00078
00079 static void get_zone (struct timezone *tz, time_t now)
00080 {
00081   const struct tm *tm = localtime (&now);
00082
00083   if (tm && tz)
00084   {
00085 #ifdef __DJGPP__
00086     tz->tz_minuteswest = -tm->__tm_gmtoff / 60;
00087 #else
00088     tz->tz_minuteswest = -60 * (int)_timezone;
00089 #endif
00090     tz->tz_dsttime = tm->tm_isdst;
00091   }
00092 }
00093
00097 void set_utc_offset (void)
00098 {
00099   struct timezone tz = { 0, 0 };
00100
00101 #if !defined(__POCC__)
00102   tzset();
00103 #endif
00104   get_zone (&tz, time(NULL));
00105
00106 #ifdef TEST_PROG
00107   printf ("Minutes west %d, DST %d\n", tz.tz_minuteswest, tz.tz_dsttime);
00108 #endif
00109   utc_offset = 60 * tz.tz_minuteswest;
00110 }
00111
00112 #if defined(WIN32)
00113 /*
00114  * Stolen and modified from APR (Apache Portable Runtime):
00115  * Number of micro-seconds between the beginning of the Windows epoch
00116  * (Jan. 1, 1601) and the Unix epoch (Jan. 1, 1970).
00117  *
00118  * This assumes all Win32 compilers have 64-bit support.
00119  */
00120 #define DELTA_EPOCH_IN_USEC  U64_SUFFIX (11644473600000000)
00121
00122 static __inline uint64 FileTimeToUnixEpoch (const FILETIME *ft)
00123 {
00124   uint64 res = (uint64) ft->dwHighDateTime << 32;
00125
00126   res |= ft->dwLowDateTime;
00127   res /= 10;                   /* from 100 nano-sec periods to usec */
00128   res -= DELTA_EPOCH_IN_USEC;  /* from Win epoch to Unix epoch */
00129   return (res);
00130 }
00131
00132 int gettimeofday (struct timeval *tv, struct timezone *tz)
00133 {
00134   if (!tv && !tz)
00135   {
00136     SOCK_ERRNO (EINVAL);
00137     return (-1);
00138   }
00139
00140   if (tv)
00141   {
00142     FILETIME ft;
00143     uint64   tim;
00144
00145     GetSystemTimeAsFileTime (&ft);
00146     tim = FileTimeToUnixEpoch (&ft);
00147     tv->tv_sec  = (long) (tim / 1000000L);
00148     tv->tv_usec = (long) (tim % 1000000L);
00149   }
00150   if (tz)
00151      get_zone (tz, tv->tv_sec);
00152   return (0);
00153 }
00154
00155 #elif (DOSX == 0)
00156 int gettimeofday (struct timeval *tv, struct timezone *tz)
00157 {
00158   union  REGS reg;
00159   struct tm   tm;
00160
00161   if (!tv)
00162   {
00163     SOCK_ERRNO (EINVAL);
00164     return (-1);
00165   }
00166
00167   reg.h.ah = 0x2C;
00168   int86 (0x21, &reg, &reg);
00169
00170   tv->tv_usec = reg.h.dl * 10000UL;
00171   tm.tm_sec   = reg.h.dh;
00172   tm.tm_min   = reg.h.cl;
00173   tm.tm_hour  = reg.h.ch;
00174
00175   reg.h.ah = 0x2A;
00176   int86 (0x21, &reg, &reg);
00177
00178   tm.tm_mday  = reg.h.dl;
00179   tm.tm_mon   = reg.h.dh - 1;
00180   tm.tm_year  = (reg.x.cx & 0x7FF) - 1900;
00181   tm.tm_wday  = tm.tm_yday = 0;
00182   tm.tm_isdst = -1;
00183
00184   tv->tv_sec = mktime (&tm);
00185
00186   if (tz)
00187      get_zone (tz, tv->tv_sec);
00188   return (0);
00189 }
00190
00191 #elif (DOSX & (PHARLAP|X32VM))
00192 int gettimeofday (struct timeval *tv, struct timezone *tz)
00193 {
00194   SWI_REGS  reg;
00195   struct tm tm;
00196
00197   if (!tv)
00198   {
00199     SOCK_ERRNO (EINVAL);
00200     return (-1);
00201   }
00202
00203   reg.r_ax = 0x2C00;
00204   _dx_real_int (0x21, &reg);
00205
00206   tv->tv_usec = loBYTE (reg.r_dx) * 10000UL;
00207   tm.tm_sec   = hiBYTE (reg.r_dx);
00208   tm.tm_min   = loBYTE (reg.r_cx);
00209   tm.tm_hour  = hiBYTE (reg.r_cx);
00210
00211   reg.r_ax = 0x2A00;
00212   _dx_real_int (0x21, &reg);
00213
00214   tm.tm_mday  = loBYTE (reg.r_dx);
00215   tm.tm_mon   = hiBYTE (reg.r_dx) - 1;
00216   tm.tm_year  = (reg.r_cx & 0x7FF) - 1900;
00217   tm.tm_wday  = tm.tm_yday = 0;
00218   tm.tm_isdst = -1;
00219
00220   tv->tv_sec = mktime (&tm);
00221   if (tz)
00222      get_zone (tz, tv->tv_sec);
00223   return (0);
00224 }
00225
00226 #elif defined(WATCOM386) || defined(BORLAND386) || defined(__CCDL__)
00227 int gettimeofday (struct timeval *tv, struct timezone *tz)
00228 {
00229   union  REGS reg;
00230   struct tm   tm;
00231
00232   if (!tv)
00233   {
00234     SOCK_ERRNO (EINVAL);
00235     return (-1);
00236   }
00237
00238   reg.x.eax = 0x2C00;
00239   int386 (0x21, &reg, &reg);
00240
00241   tv->tv_usec = reg.h.dl * 10000UL;
00242   tm.tm_sec   = reg.h.dh;
00243   tm.tm_min   = reg.h.cl;
00244   tm.tm_hour  = reg.h.ch;
00245
00246   reg.x.eax = 0x2A00;
00247   int386 (0x21, &reg, &reg);
00248
00249   tm.tm_mday  = reg.h.dl;
00250   tm.tm_mon   = reg.h.dh - 1;
00251   tm.tm_year  = (reg.x.ecx & 0x7FF) - 1900;
00252   tm.tm_wday  = tm.tm_yday = 0;
00253   tm.tm_isdst = -1;
00254
00255   tv->tv_sec = mktime (&tm);
00256   if (tz)
00257      get_zone (tz, tv->tv_sec);
00258   return (0);
00259 }
00260 #endif   /* DOSX == 0 */
00261
00262
00263 #if defined(HAVE_UINT64) && !defined(WIN32)
00264 /*
00265  * Return hardware time-of-day in microseconds.
00266  * NOTE: hardware counter (lo) counts down from 65536 at a rate of
00267  *       1.19318 MHz (4.77/4).
00268  */
00269 static __inline uint64 microsec_clock (void)
00270 {
00271   DWORD  hi;
00272   long   lo;
00273   uint64 rc;
00274
00275   do
00276   {
00277     hi = PEEKL (0, BIOS_CLK);
00278     lo = clockbits();
00279   }
00280   while (hi != PEEKL(0, BIOS_CLK));   /* tick count changed, try again */
00281   lo = 0 - lo;
00282   rc = ((uint64)hi << 16) + lo;
00283   return (rc * U64_SUFFIX(4000000) / U64_SUFFIX(4770000));
00284 }
00285
00286 #if (DOSX)
00287 /*
00288  * Return CPU time-stamp counter in microseconds since epoch
00289  * (1 Jan 1970 UTC) or from '*base'.
00290  */
00291 static uint64 tsc_microsec (const uint64 *base)
00292 {
00293   static uint64 time_ofs = U64_SUFFIX(-1);
00294   static time_t start    = 0;
00295   uint64 rc, now;
00296
00297   if (clocks_per_usec == 0)
00298      return (0);
00299
00300   if (time_ofs == U64_SUFFIX(-1))
00301   {
00302     start = time (NULL);
00303     while (time(NULL) == start)
00304           ENABLE();
00305     time_ofs = get_rdtsc();
00306   }
00307   if (base)
00308        now = *base;
00309   else now = get_rdtsc();
00310   rc  = (now - time_ofs) / clocks_per_usec;
00311   rc += U64_SUFFIX(1000000) * (start+1);
00312   return (rc);
00313 }
00314
00315 static void adjust_cpu_clock (const struct timeval *tv)
00316 {
00317   static DWORD last = 0;
00318   DWORD  tick = PEEKL (0, BIOS_CLK);
00319
00320   if (((tick % 5) == 0) && last != tick) /* 260msec passed */
00321   {
00322     static double sample[4];
00323     static int    idx = 0;
00324
00325     if (idx < DIM(sample))
00326     {
00327       struct timeval tv0;
00328
00329       gettimeofday (&tv0, NULL);
00330       sample[idx++] = timeval_diff (&tv0, tv);
00331     }
00332     else
00333     {
00334       double diff = 0.0;
00335       int    i, corr;
00336
00337       for (i = 0; i < DIM(sample); i++)
00338           diff += sample[i];
00339       idx  = 0;
00340       diff = diff / DIM(sample);
00341       corr = abs ((int)last-(int)tick) / 8;
00342       corr = diff < 0.0 ? -corr : +corr;
00343       clocks_per_usec += corr;
00344
00345 #ifdef TEST_PROG
00346       printf ("diff %.6f, corr %d\n", diff/1E6, corr);
00347 #endif
00348     }
00349     last = tick;
00350   }
00351 }
00352
00353 /*
00354  * Return a 'timeval' from a CPU timestamp.
00355  */
00356 BOOL get_tv_from_tsc (const struct ulong_long *tsc, struct timeval *tv)
00357 {
00358   uint64 usecs;
00359
00360   if (!tsc || !tv || !has_rdtsc)
00361      return (FALSE);
00362
00363   usecs = tsc_microsec ((const uint64*)tsc);
00364   if (!usecs)
00365      return (FALSE);
00366
00367   tv->tv_usec = (long) (usecs % U64_SUFFIX(1000000));
00368   tv->tv_sec  = (time_t) ((usecs - tv->tv_usec) / U64_SUFFIX(1000000));
00369   return (TRUE);
00370 }
00371 #endif /* DOSX */
00372 #endif /* HAVE_UINT64 && !WIN32 */
00373
00374
00375 /*
00376  * A high-resolution [1us] version of gettimeofday() needed in
00377  * select_s() etc. Should return 'tv_sec' in UTC.
00378  */
00379 int gettimeofday2 (struct timeval *tv, struct timezone *tz)
00380 {
00381   init_misc();
00382
00383   if (user_tick_active)
00384   {
00385     tv->tv_usec = (long) (1000UL * (user_tick_msec % 1000UL));
00386     tv->tv_sec  = (DWORD) user_tick_base + (user_tick_msec / 1000UL);
00387
00388     if (tz)
00389        get_zone (tz, tv->tv_sec);
00390     return (0);
00391   }
00392
00393 #if defined(HAVE_UINT64) && !defined(WIN32)
00394 #if (DOSX)
00395   if (has_rdtsc && use_rdtsc)
00396   {
00397     uint64 usecs = tsc_microsec (NULL);
00398
00399     if (!usecs)
00400        return (-1);
00401
00402     tv->tv_usec = (long) (usecs % U64_SUFFIX(1000000));
00403     tv->tv_sec  = (time_t) ((usecs - tv->tv_usec) / U64_SUFFIX(1000000));
00404     if (tz)
00405        get_zone (tz, tv->tv_sec);
00406     adjust_cpu_clock (tv);
00407     return (0);
00408   }
00409 #endif
00410
00411   if (has_8254)
00412   {
00413     static time_t secs = 0;           /* seconds since midnight */
00414     static uint64 last = 0;
00415     uint64 usecs = microsec_clock();  /* usec day-clock */
00416
00417     if (secs == 0 || usecs < last)    /* not init or wrapped */
00418     {
00419       secs = time (NULL);
00420       secs -= (secs % (24*3600));
00421     }
00422     last = usecs;
00423     tv->tv_usec = (long) (usecs % U64_SUFFIX(1000000));
00424     tv->tv_sec  = (time_t) ((usecs - tv->tv_usec) / U64_SUFFIX(1000000) + (uint64)secs);
00425     tv->tv_sec += utc_offset;
00426
00427     if (tz)
00428        get_zone (tz, tv->tv_sec);
00429     return (0);
00430   }
00431 #endif  /* HAVE_UINT64 && !WIN32 */
00432
00433   return gettimeofday (tv, tz);
00434 }
00435
00436
00437 #if defined(TEST_PROG)   /* for djgpp/Watcom/HighC */
00438
00439 #include "printk.h"
00440 #include "getopt.h"
00441
00442 static __inline BOOL dayrollover (void)
00443 {
00444   return PEEKB (0, 0x470);
00445 }
00446
00447 #if !defined(__DJGPP__) && 0
00448 static void usleep (DWORD usec)
00449 {
00450   struct timeval now, start, expiry;
00451
00452   gettimeofday2 (&start, NULL);
00453   expiry.tv_sec  = start.tv_sec  + (usec / 1000000UL);
00454   expiry.tv_usec = start.tv_usec + (usec % 1000000UL);
00455   while (expiry.tv_usec >= 1000000UL)
00456   {
00457     expiry.tv_usec -= 1000000UL;
00458     expiry.tv_sec++;
00459   }
00460   while (1)
00461   {
00462     gettimeofday2 (&now, NULL);
00463     if (now.tv_sec > expiry.tv_sec ||
00464         (now.tv_sec == expiry.tv_sec && now.tv_usec > expiry.tv_usec))
00465        break;
00466   }
00467 }
00468 #endif
00469
00470 int main (int argc, char **argv)
00471 {
00472   DWORD loops   = 0;
00473   BOOL  do_cmp  = FALSE;
00474   BOOL  use_isr = FALSE;
00475   int   ch;
00476
00477   putenv ("USE_RDTSC=0");
00478
00479   init_misc();
00480
00481   while ((ch = getopt(argc, argv, "?chir")) != EOF)
00482         switch (ch)
00483         {
00484           case 'c':
00485                do_cmp = TRUE;
00486                break;
00487           case 'h':
00488                hires_timer (0);
00489                break;
00490           case 'i':
00491                init_timer_isr();
00492                use_isr = TRUE;
00493                break;
00494           case 'r':
00495                if (use_isr)
00496                {
00497                  puts ("Cannot use both `-i' and `-r'");
00498                  return (-1);
00499                }
00500                putenv ("USE_RDTSC=1");
00501                break;
00502           case '?':
00503           default:
00504                printf ("Usage: %s [-chir]\n"
00505                        "  -c compare gettimeofday2() and gettimeofday()\n"
00506                        "  -h don't use hi-res 8254 PIT\n"
00507                        "  -i use timer ISR\n"
00508                        "  -r use RDTSC for gettimeofday2()\n",
00509                        argv[0]);
00510                return (0);
00511         }
00512
00513   if (do_cmp)
00514        puts ("gettimeofday2(),   gettimeofday(),    tv2-tv        ctime     rollover");
00515   else puts ("gettimeofday2(),   sleep,    (ctime)");
00516
00517   puts ("------------------------------------------------------------------------");
00518
00519   while (!kbhit())
00520   {
00521     struct timeval tv, tv2;
00522     struct timeval last;
00523     double delta;
00524
00525     gettimeofday (&tv, NULL);
00526     gettimeofday2 (&tv2, NULL);
00527
00528     if (loops > 0)
00529          delta = timeval_diff (&tv2, &last);
00530     else delta = 0.0;
00531     last.tv_sec  = tv2.tv_sec;
00532     last.tv_usec = tv2.tv_usec;
00533
00534     if (do_cmp)
00535     {
00536       printf ("%10ld.%06lu, %10ld.%06lu, %12.6f",
00537               (long)tv2.tv_sec, tv2.tv_usec, (long)tv.tv_sec, tv.tv_usec,
00538               timeval_diff(&tv2,&tv)/1E6);
00539     }
00540     else
00541       printf ("%10ld.%06lu, %.6f", (long)tv2.tv_sec, tv2.tv_usec, delta/1E6);
00542
00543     printf (", %.8s, %d\n",
00544             ctime(&tv2.tv_sec)+11, dayrollover());
00545
00546 #ifdef __DJGPP__   /* don't use delay(). It doesn't work under Win2K/XP */
00547     usleep (1000000);
00548 #else
00549     sleep (1);
00550 #endif
00551     loops++;
00552   }
00553   return (0);
00554 }
00555 #endif  /* TEST_PROG */
00556
Generated on Wed Jan 25 15:42:35 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/GETTOD.H Source File

SRC/GETTOD.H

Go to the documentation of this file.
00001
00003 #ifndef _w32_GETTIMEOFDAY_H
00004 #define _w32_GETTIMEOFDAY_H
00005
00006 #include <sys/wtime.h>
00007
00008 #if (DOSX) && defined(HAVE_UINT64)
00009 extern BOOL get_tv_from_tsc (const struct ulong_long *tsc,
00010                              struct timeval *tv);
00011 #endif
00012
00013 extern void set_utc_offset (void);
00014 extern int  gettimeofday2 (struct timeval *tv, struct timezone *tz);
00015
00016 #endif
Generated on Wed Jan 25 15:42:35 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/HIGHC.C Source File

SRC/HIGHC.C

Go to the documentation of this file.
00001
00036 #include <stdio.h>
00037 #include <stdlib.h>
00038 #include <string.h>
00039 #include <ctype.h>
00040 #include <io.h>
00041
00042 #include "wattcp.h"
00043 #include "strings.h"
00044 #include "pcconfig.h"
00045
00046 #if defined(__HIGHC__) && (DOSX & PHARLAP)
00047
00048 /*
00049  * HighC's putenv() doesn't modify the inherited environment.
00050  * We must do it ourself.
00051  */
00052 static char *SetupEnvironment (void)
00053 {
00054   char  *copy;
00055   char  *start;
00056   char **env  = _environ; /* list of env.var + putenv() vars */
00057   UINT   size = 0;
00058
00059   if (!env || !*env)
00060      return (NULL);
00061
00062   while (env && *env)  /* find how many bytes we need to malloc */
00063        size += strlen (*env++) + 1;
00064
00065   size++;
00066   copy = malloc (size);
00067   if (!copy)
00068      return (NULL);
00069
00070   start = copy;
00071   env   = _environ;
00072   while (env && *env)  /* make a new continuous environment block */
00073   {
00074     int len = strlen (*env) + 1;
00075
00076     memcpy (copy, *env++, len);
00077     copy += len;
00078   }
00079   *copy = '\0';        /* final termination */
00080   return (start);
00081 }
00082
00083 static int Execute (const char *path, const char *args, char **env)
00084 {
00085   union  REGS reg;
00086   EXEC_BLK    blk;
00087   char        buf[256];
00088   int         len;
00089   ULONG       minPages, maxPages;
00090   UCHAR      *our_env = (UCHAR*) SetupEnvironment();
00091
00092   *env = our_env;
00093   len  = strlen (args);
00094   if (len > sizeof(buf)-2)
00095      return (0);
00096
00097   _dx_cmem_usage (0, FALSE, &minPages, &maxPages);
00098
00099   strcpy (buf+1, args);
00100   buf [0]   = len++;
00101   buf [len] = '\r';
00102
00103   /* if `our_env' is NULL we'll inherit the environment without any
00104    * variables added by `putenv()'
00105    */
00106   blk.ex_eoff = our_env;        /* pass new environment */
00107   blk.ex_eseg = SS_DATA;
00108   blk.ex_coff = (UCHAR*) buf;   /* command line address */
00109   blk.ex_cseg = SS_DATA;
00110   reg.x.ax    = 0x4B00;
00111   reg.x.bx    = (UINT) &blk;
00112   reg.x.dx    = (UINT) path;
00113   fflush (stdout);              /* flush buffers now */
00114   fflush (stderr);
00115
00116   intdos (&reg, &reg);
00117   if (reg.x.cflag & 1)          /* carry set, return -1 */
00118      return (-1);
00119
00120   reg.x.ax = 0x4D00;
00121   intdos (&reg, &reg);
00122   return (reg.h.al);            /* return child exit code */
00123 }
00124
00125 /*
00126  * This replaces system() in hc386.lib
00127  * Note: this is aliased in <tcp.h>
00128  */
00129 int _mw_watt_system (const char *cmd)
00130 {
00131   char  buf[150];
00132   char *env_copy, *env = getenv ("COMSPEC");
00133   int   rc;
00134
00135   if (!env || access(env,0))
00136   {
00137     (*_printf) ("Bad COMSPEC variable\n");
00138     return (0);
00139   }
00140
00141   if (cmd && *cmd)
00142        _bprintf (buf, sizeof(buf), " /c %s", cmd);
00143   else _bprintf (buf, sizeof(buf), "%s", cmd);
00144
00145   rc = Execute (env, buf, &env_copy);
00146
00147   if (env_copy)
00148      free (env_copy);
00149   return (rc);
00150 }
00151
00152 /*
00153  * The following functions are called when Call_trace, Prolog_trace
00154  * and Epilog_trace pragmas are in effect.
00155  * Library must be compiled with:  -Hon=Call_trace
00156  *                                 -Hon=Prolog_trace
00157  *                             and -Hon=Epilog_trace
00158  */
00159
00160 #pragma Off(Call_trace)      /* no trace of trace itself */
00161 #pragma Off(Prolog_trace)
00162 #pragma Off(Epilog_trace)
00163 #pragma Global_aliasing_convention("%r")
00164
00165 #if defined(USE_DEBUG)
00166
00167 #define MAX_LEVEL 1000
00168
00169
00170 static int   level = 0;
00171 static const char *caller [MAX_LEVEL];
00172
00173 static BOOL is_watt32_func (const char *func) /* incomplete */
00174 {
00175   if (!strcmp(func,"watt_sock_init"))
00176      return (TRUE);
00177   if (!strcmp(func,"sock_init"))
00178      return (TRUE);
00179   if (!strcmp(func,"_w32_init_misc"))
00180      return (TRUE);
00181   if (!strcmp(func,"setup_dos_xfer_buf"))
00182      return (TRUE);
00183   if (!strcmp(func,"RDTSC_enabled"))
00184      return (TRUE);
00185   if (!strcmp(func,"_w32_init_timers"))
00186      return (TRUE);
00187   if (!strcmp(func,"set_utc_offset"))
00188      return (TRUE);
00189   if (!strcmp(func,"get_zone"))
00190      return (TRUE);
00191   if (!strcmp(func,"tcp_init"))
00192      return (TRUE);
00193   if (!strcmp(func,"_eth_init"))
00194      return (TRUE);
00195   return (FALSE);
00196 }
00197
00198 void _call_trace (const char *from, const char *module, unsigned line,
00199                   const char *to)
00200 {
00201   static const char *last_module = NULL;
00202   char   where[30];
00203
00204   if (!ctrace_on || level >= DIM(caller)-1)
00205      return;
00206
00207   _bprintf (where, sizeof(where), "%s(%u)", module, line);
00208
00209   (*_printf) ("%-16s:%*s %s() -> %s()\n", where, level, "", from, to);
00210
00211   if (caller[level] == NULL ||
00212       (strcmp(from,caller[level])) && is_watt32_func(to))
00213      caller[level++] = from;
00214
00215   else if (last_module && !strcmp(module,last_module) && level > 0)
00216      level--;
00217
00218   last_module = module;
00219 }
00220
00221 void _prolog_trace (const char *func)
00222 {
00223 #if 0
00224   if (ctrace_on)
00225     (*_printf) ("%s()\n", func);
00226 #endif
00227   ARGSUSED (func);
00228 }
00229
00230 void _epilog_trace (const char *func)
00231 {
00232   if (level > 0 && ctrace_on)
00233     --level;
00234 }
00235 #else     /* !USE_DEBUG */
00236
00237 void _call_trace (const char *from, const char *module, unsigned line, const char *to)
00238 {
00239   ARGSUSED (from);
00240   ARGSUSED (module);
00241   ARGSUSED (line);
00242   ARGSUSED (to);
00243 }
00244
00245 void _prolog_trace (const char *func)
00246 {
00247   ARGSUSED (func);
00248 }
00249
00250 void _epilog_trace (const char *func)
00251 {
00252   ARGSUSED (func);
00253 }
00254 #endif   /* USE_DEBUG */
00255 #endif   /* __HIGHC__ && (DOSX & PHARLAP) */
Generated on Wed Jan 25 15:42:35 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/IDNA.C Source File

SRC/IDNA.C

00001 /*
00002  * Code for enabling lookup of names with non-ASCII letters via
00003  * ACE and IDNA (Internationalizing Domain Names in Applications)
00004  * Ref. RFC-3490.
00005  *
00006  */
00007
00008 /*  \version 0.1: Mar 19, 2004 :
00009  *    G. Vanem - Created.
00010  *
00011  */
00012
00013 #include <stdio.h>
00014 #include <stdlib.h>
00015 #include <limits.h>
00016 #include <string.h>
00017 #include <ctype.h>
00018
00019 #include "wattcp.h"
00020 #include "misc.h"
00021 #include "strings.h"
00022 #include "pcconfig.h"
00023 #include "punycode.h"
00024 #include "idna.h"
00025
00026 #if defined(USE_IDNA)
00027
00028 #define _FLUSHWC_H  /* normal_flushwc() not needed */
00029
00030 #ifdef _MSC_VER
00031 #pragma warning (disable:4244)
00032 #endif
00033
00034 #include "iconv/ascii.h"
00035 #include "iconv/jisx0201.h"
00036 #include "iconv/jisx0208.h"
00037 #include "iconv/cp437.h"
00038 #include "iconv/cp737.h"
00039 #include "iconv/cp775.h"
00040 #include "iconv/cp850.h"
00041 #include "iconv/cp852.h"
00042 #include "iconv/cp853.h"
00043 #include "iconv/cp855.h"
00044 #include "iconv/cp856.h"
00045 #include "iconv/cp857.h"
00046 #include "iconv/cp858.h"
00047 #include "iconv/cp860.h"
00048 #include "iconv/cp861.h"
00049 #include "iconv/cp862.h"
00050 #include "iconv/cp863.h"
00051 #include "iconv/cp864.h"
00052 #include "iconv/cp865.h"
00053 #include "iconv/cp866.h"
00054 #include "iconv/cp869.h"
00055 #include "iconv/cp874.h"
00056 #include "iconv/cp922.h"
00057 #include "iconv/cp932.h"
00058 #include "iconv/cp943.h"
00059 #include "iconv/ksc5601.h"
00060 #include "iconv/cp949.h"
00061 #include "iconv/big5.h"
00062 #include "iconv/cp950.h"
00063 #include "iconv/cp1046.h"
00064 #include "iconv/cp1124.h"
00065 #include "iconv/cp1125.h"
00066 #include "iconv/cp1129.h"
00067 #include "iconv/cp1133.h"
00068 #include "iconv/cp1161.h"
00069 #include "iconv/cp1162.h"
00070 #include "iconv/cp1163.h"
00071 #include "iconv/cp1250.h"
00072 #include "iconv/cp1251.h"
00073 #include "iconv/cp1252.h"
00074 #include "iconv/cp1253.h"
00075 #include "iconv/cp1254.h"
00076 #include "iconv/cp1255.h"
00077 #include "iconv/cp1256.h"
00078 #include "iconv/cp1257.h"
00079 #include "iconv/vietcomb.h"
00080 #include "iconv/cp1258.h"
00081
00082 typedef int (*toUnicode) (conv_t, ucs4_t *, const unsigned char *, int);
00083 typedef int (*toAscii)   (conv_t, unsigned char *, ucs4_t, int);
00084
00085 struct iconv_table {
00086        const char *name;
00087        WORD        codepage;
00088        toUnicode   mbtowc;
00089        toAscii     wctomb;
00090      };
00091
00092 static const struct iconv_table mappings[] = {
00093        { "CP437",  437,  cp437_mbtowc,  cp437_wctomb  },
00094        { "CP737",  737,  cp737_mbtowc,  cp737_wctomb  },
00095        { "CP775",  775,  cp775_mbtowc,  cp775_wctomb  },
00096        { "CP850",  850,  cp850_mbtowc,  cp850_wctomb  },
00097        { "CP852",  852,  cp852_mbtowc,  cp852_wctomb  },
00098        { "CP853",  853,  cp853_mbtowc,  cp853_wctomb  },
00099        { "CP855",  855,  cp855_mbtowc,  cp855_wctomb  },
00100        { "CP856",  856,  cp856_mbtowc,  cp856_wctomb  },
00101        { "CP857",  857,  cp857_mbtowc,  cp857_wctomb  },
00102        { "CP858",  858,  cp858_mbtowc,  cp858_wctomb  },
00103        { "CP860",  860,  cp860_mbtowc,  cp860_wctomb  },
00104        { "CP861",  861,  cp861_mbtowc,  cp861_wctomb  },
00105        { "CP862",  862,  cp862_mbtowc,  cp862_wctomb  },
00106        { "CP863",  863,  cp863_mbtowc,  cp863_wctomb  },
00107        { "CP864",  864,  cp864_mbtowc,  cp864_wctomb  },
00108        { "CP865",  865,  cp865_mbtowc,  cp865_wctomb  },
00109        { "CP866",  866,  cp866_mbtowc,  cp866_wctomb  },
00110        { "CP869",  869,  cp869_mbtowc,  cp869_wctomb  },
00111        { "CP874",  874,  cp874_mbtowc,  cp874_wctomb  },
00112        { "CP922",  922,  cp922_mbtowc,  cp922_wctomb  },
00113        { "CP932",  932,  cp932_mbtowc,  cp932_wctomb  },
00114        { "CP943",  943,  cp943_mbtowc,  cp943_wctomb  },
00115        { "CP949",  949,  cp949_mbtowc,  cp949_wctomb  },
00116        { "CP950",  950,  cp950_mbtowc,  cp950_wctomb  },
00117        { "CP1046", 1046, cp1046_mbtowc, cp1046_wctomb },
00118        { "CP1124", 1124, cp1124_mbtowc, cp1124_wctomb },
00119        { "CP1125", 1125, cp1125_mbtowc, cp1125_wctomb },
00120        { "CP1129", 1129, cp1129_mbtowc, cp1129_wctomb },
00121        { "CP1133", 1133, cp1133_mbtowc, cp1133_wctomb },
00122        { "CP1161", 1161, cp1161_mbtowc, cp1161_wctomb },
00123        { "CP1162", 1162, cp1162_mbtowc, cp1162_wctomb },
00124        { "CP1163", 1163, cp1163_mbtowc, cp1163_wctomb },
00125        { "CP1250", 1250, cp1250_mbtowc, cp1250_wctomb },
00126        { "CP1251", 1251, cp1251_mbtowc, cp1251_wctomb },
00127        { "CP1252", 1252, cp1252_mbtowc, cp1252_wctomb },
00128        { "CP1253", 1253, cp1253_mbtowc, cp1253_wctomb },
00129        { "CP1254", 1254, cp1254_mbtowc, cp1254_wctomb },
00130        { "CP1255", 1255, cp1255_mbtowc, cp1255_wctomb },
00131        { "CP1256", 1256, cp1256_mbtowc, cp1256_wctomb },
00132        { "CP1257", 1257, cp1257_mbtowc, cp1257_wctomb },
00133        { "CP1258", 1258, cp1258_mbtowc, cp1258_wctomb },
00134        { NULL,     0,    NULL,          NULL }
00135      };
00136
00137 static const struct iconv_table *curr_mapping = NULL;
00138 static conv_t iconv;
00139
00140 /* The following string is used to convert printable
00141  * characters between ASCII and the native charset:
00142  */
00143 static const char print_ascii[] = "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
00144                                   "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
00145                                   " !\"#$%&'()*+,-./" "0123456789:;<=>?"
00146                                   "@ABCDEFGHIJKLMNO"
00147                                   "PQRSTUVWXYZ[\\]^_"
00148                                   "`abcdefghijklmno"
00149                                   "pqrstuvwxyz{|}~\n";
00150 #if defined(WIN32)
00151   #define GET_CODEPAGE()  GetACP()
00152 #else
00153   #define GET_CODEPAGE()  GetCodePage()
00154 #endif
00155
00159 BOOL iconv_init (WORD cp)
00160 {
00161   int i;
00162
00163   if (cp == 0)
00164      cp = GET_CODEPAGE();
00165
00166   IDNA_DEBUG (2, ("iconv_init: codepage %u\n", cp));
00167   if (!cp)
00168      return (FALSE);
00169
00170   for (i = 0; i < DIM(mappings); i++)
00171       if (cp == mappings[i].codepage)
00172          break;
00173   if (i == DIM(mappings))
00174      return (FALSE);
00175   curr_mapping = mappings + i;
00176   return (TRUE);
00177 }
00178
00182 const char *iconv_strerror (int rc)
00183 {
00184   switch (rc)
00185   {
00186     case RET_ILUNI:
00187          return ("Illegal Unicode");
00188     case RET_ILSEQ:
00189          return ("Illegal sequence");
00190     case RET_TOOSMALL:
00191          return ("Output buffer too small");
00192     case RET_TOOFEW(0):
00193          return ("Input sequence too short");
00194     case RET_TOOFEW(1):
00195          return ("Input sequence 1 byte too short");
00196     case RET_TOOFEW(2):
00197          return ("Input sequence 2 bytes too short");
00198     case RET_TOOFEW(3):
00199          return ("Input sequence 3 bytes too short");
00200     default:
00201          return ("Unknown");
00202   }
00203 }
00204
00208 static int iconv_to_unicode (char ch, ucs4_t *uc)
00209 {
00210   ucs4_t res = 0;
00211   int    rc;
00212
00213   if (!curr_mapping)
00214      return (0);
00215   rc = (*curr_mapping->mbtowc) (iconv, &res, (unsigned char*)&ch, 1);
00216   if (rc < 1)
00217   {
00218     IDNA_DEBUG (1, ("iconv_to_unicode failed; %d, %s\n",
00219                 rc, iconv_strerror(rc)));
00220     return (0);
00221   }
00222   *uc = res;
00223   return (rc);
00224 }
00225
00229 static int iconv_to_ascii (ucs4_t uc, char *ch)
00230 {
00231   int rc = 0;
00232
00233   if (curr_mapping)
00234   {
00235     unsigned char res[4] = { 0,0,0,0 };
00236
00237     rc = (*curr_mapping->wctomb) (iconv, res, uc, sizeof(res));
00238     if (rc == 1)
00239        *ch = (char) res[0];
00240     else if (rc == 2)
00241        *(WORD*)ch = *(WORD*)&res;
00242     else if (rc > 2)
00243        memcpy (ch, res, rc);
00244     else
00245        IDNA_DEBUG (1, ("iconv_to_ascii failed; %d, %s\n",
00246                    rc, iconv_strerror(rc)));
00247   }
00248   return (rc);
00249 }
00250
00254 static char **split_labels (const char *name)
00255 {
00256   static char  buf [MAX_LABELS][MAX_HOSTLEN];
00257   static char *res [MAX_LABELS+1];
00258   const  char *p = name;
00259   int    i;
00260
00261   for (i = 0; i < MAX_LABELS && *p; i++)
00262   {
00263     const char *dot = strchr (p, '.');
00264
00265     if (!dot)
00266     {
00267       res[i] = StrLcpy (buf[i], p, sizeof(buf[i]));
00268       i++;
00269       break;
00270     }
00271     res[i] = StrLcpy (buf[i], p, dot-p+1);
00272     p = ++dot;
00273   }
00274   res[i] = NULL;
00275   IDNA_DEBUG (3, ("split_labels: `%s', %d labels\n", name, i));
00276   return (res);
00277 }
00278
00282 static char *convert_to_ACE (const char *name)
00283 {
00284   DWORD  utf_input[MAX_HOSTLEN];
00285   BYTE   utf_case [MAX_HOSTLEN];
00286   const  char *p;
00287   size_t in_len, out_len;
00288   static char out_buf [2*MAX_HOSTLEN];
00289   enum punycode_status status;
00290   int  i, c;
00291
00292   for (i = 0, p = name; *p; i++)
00293   {
00294     ucs4_t utf = 0;
00295
00296     c = *p++;
00297     iconv_to_unicode (c, &utf);
00298     utf_input[i] = utf;
00299     utf_case[i]  = isupper (c);
00300     if (utf > 0xFFFF)
00301          IDNA_DEBUG (3, ("%c -> u+%08lX\n", c, utf));
00302     else IDNA_DEBUG (3, ("%c -> u+%04lX\n", c, utf));
00303   }
00304   in_len  = i;
00305   out_len = sizeof(out_buf);
00306   status  = punycode_encode (in_len, utf_input, utf_case, &out_len, out_buf);
00307
00308   if (status != punycode_success)
00309      out_len = 0;
00310
00311   for (i = 0; i < (int)out_len; i++)
00312   {
00313     int c = out_buf[i];
00314
00315     if (c < 0 || c > 127)
00316     {
00317       IDNA_DEBUG (1, ("illegal Punycode result: %c (%d)\n", c, c));
00318       return (NULL);
00319     }
00320     if (!print_ascii[c])
00321     {
00322       IDNA_DEBUG (1, ("Punycode not ASCII: %c (%d)\n", c, c));
00323       return (NULL);
00324     }
00325     out_buf[i] = print_ascii[c];
00326   }
00327   out_buf[i] = '\0';
00328   IDNA_DEBUG (2, ("punycode_encode: status %d, out_len %lu, out_buf `%s'\n",
00329               status, (DWORD)out_len, out_buf));
00330   return (status == punycode_success ? out_buf : NULL);
00331 }
00332
00336 static char *convert_from_ACE (const char *name)
00337 {
00338   DWORD  utf_output[MAX_HOSTLEN];
00339   BYTE   utf_case  [MAX_HOSTLEN];
00340   static char out_buf [MAX_HOSTLEN];
00341   size_t utf_len, i, j;
00342   enum punycode_status status;
00343
00344   utf_len = sizeof(utf_output);
00345   status = punycode_decode (strlen(name), name, &utf_len, utf_output, utf_case);
00346
00347   if (status != punycode_success)
00348      utf_len = 0;
00349
00350   for (i = j = 0; i < utf_len && j < sizeof(out_buf); i++)
00351   {
00352     ucs4_t utf = utf_output[i];
00353     int    len = iconv_to_ascii (utf, out_buf+j);
00354
00355     if (len <= 0)
00356        break;
00357     IDNA_DEBUG (3, ("%c+%04lX -> %*.s\n",
00358                 utf_case[i] ? 'U' : 'u', utf, len, out_buf+j));
00359     j += len;
00360   }
00361   out_buf[j] = '\0';
00362   IDNA_DEBUG (2, ("punycode_decode: status %d, out_len %lu, out_buf `%s'\n",
00363               status, (DWORD)utf_len, out_buf));
00364   return (status == punycode_success ? out_buf : NULL);
00365 }
00366
00367
00385 BOOL IDNA_convert_to_ACE (
00386           char   *name,   /* IN/OUT: native ASCII/ACE name */
00387           size_t *size)   /* IN:     length of name buf, */
00388 {                         /* OUT:    ACE encoded length */
00389   const  char *ace;
00390   char  *in_name = name;
00391   char **labels = split_labels (name);
00392   int    i;
00393   size_t len = 0;
00394
00395   for (i = 0; labels[i]; i++)
00396   {
00397     const BYTE *p;
00398     const char *label = labels[i];
00399
00400     ace = NULL;
00401     if (strnicmp(label,"xn--",4))  /* if not already encoded */
00402     {
00403       for (p = (const BYTE*)label; *p; p++)
00404           if (*p >= 0x80)
00405           {
00406             ace = convert_to_ACE (label);
00407             if (!ace)
00408                return (FALSE);
00409             break;
00410           }
00411     }
00412
00413     if (ace)
00414     {
00415       if (len + 5 + strlen(ace) > *size)
00416       {
00417         IDNA_DEBUG (1, ("input length exceeded\n"));
00418         return (FALSE);
00419       }
00420       name += sprintf (name, "xn--%s.", ace);
00421     }
00422     else  /* pass through unchanged */
00423     {
00424       if (len + 1 + strlen(label) > *size)
00425       {
00426         IDNA_DEBUG (1, ("input length exceeded\n"));
00427         return (FALSE);
00428       }
00429       name += sprintf (name, "%s.", label);
00430     }
00431   }
00432   if (name > in_name)   /* drop trailing '.' */
00433      name--;
00434   len = name - in_name;
00435   *name = '\0';
00436   *size = len;
00437   IDNA_DEBUG (2, ("IDNA_convert_to_ACE: `%s', %lu bytes\n",
00438               in_name, (DWORD)len));
00439   return (TRUE);
00440 }
00441
00452 BOOL IDNA_convert_from_ACE (
00453           char   *name,   /* IN/OUT: ACE/native ASCII name */
00454           size_t *size)   /* IN:     ACE raw string length, */
00455 {                         /* OUT:    ASCII deccoded length */
00456   char  *in_name = name;
00457   char **labels  = split_labels (name);
00458   int    i;
00459
00460   for (i = 0; labels[i]; i++)
00461   {
00462     const char *ascii = NULL;
00463     const char *label = labels[i];
00464
00465     if (!strncmp(label,"xn--",4) && label[4])
00466     {
00467       ascii = convert_from_ACE (label+4);
00468       if (!ascii)
00469          return (FALSE);
00470     }
00471     name += sprintf (name, "%s.", ascii ? ascii : label);
00472   }
00473   if (name > in_name)   /* drop trailing '.' */
00474      name--;
00475   *name = '\0';
00476   *size = name - in_name;
00477   IDNA_DEBUG (2, ("IDNA_convert_from_ACE: `%s', %lu bytes\n",
00478               in_name, (DWORD)*size));
00479   return (TRUE);
00480 }
00481
00482 #if defined(TEST_PROG)
00483
00484 #include <netdb.h>
00485 #include <arpa/inet.h>
00486
00487 #include "sock_ini.h"
00488 #include "udp_dom.h"
00489 #include "pcdbug.h"
00490 #include "getopt.h"
00491
00492 void usage (void)
00493 {
00494   printf ("IDNA [-d] [-c <codepage] hostname | ip-address\n"
00495           "   -d debug level, \"-dd\" for more details\n"
00496           "   -c select codepage (active is CP%d)\n", GET_CODEPAGE());
00497   exit (0);
00498 }
00499
00500 int main (int argc, char **argv)
00501 {
00502   struct hostent *he;
00503   struct in_addr addr;
00504   char   host [100];
00505   WORD   cp = 0;
00506   int    debug = 0;
00507   int    ch;
00508
00509   while ((ch = getopt(argc, argv, "c:dh?")) != EOF)
00510      switch (ch)
00511      {
00512        case 'c':
00513             cp = atoi (optarg);
00514             break;
00515        case 'd':
00516             debug++;
00517             break;
00518        case '?':
00519        case 'h':
00520        default:
00521             usage();
00522             break;
00523   }
00524
00525   argc -= optind;
00526   argv += optind;
00527   if (!*argv)
00528      usage();
00529
00530   if (debug)
00531      dbug_init();
00532   sock_init();
00533
00534   if (!iconv_init(cp))
00535   {
00536     printf ("iconv_init() failed for CP %d\n", cp);
00537     return (1);
00538   }
00539
00540   debug_on = debug;
00541   dns_do_idna = TRUE;
00542
00543   StrLcpy (host, argv[0], sizeof(host));
00544   printf ("Resolving `%s'...", host);
00545   fflush (stdout);
00546
00547   if (inet_aton(host,&addr))
00548   {
00549     he = gethostbyaddr ((char*)&addr, sizeof(addr), AF_INET);
00550     if (he)
00551          printf ("%s\n", he->h_name);
00552     else printf ("failed; %s)\n", hstrerror(h_errno));
00553   }
00554   else
00555   {
00556     he = gethostbyname (host);
00557     if (he)
00558          printf ("%s\n", inet_ntoa(*(struct in_addr*)he->h_addr));
00559     else printf ("failed; %s\n", hstrerror(h_errno));
00560   }
00561
00562   debug_on = 0;
00563   return (0);
00564 }
00565 #endif  /* TEST_PROG */
00566 #endif  /* USE_IDNA */
00567
Generated on Wed Jan 25 15:42:35 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/IDNA.H Source File

SRC/IDNA.H

Go to the documentation of this file.
00001
00003 #ifndef _w32_IDNA_H
00004 #define _w32_IDNA_H
00005
00006 typedef long  ucs4_t;
00007
00008 typedef struct {
00009         int istate;
00010       } *conv_t;
00011
00012 typedef struct {
00013         WORD  indx;  /* index into big table */
00014         WORD  used;  /* bitmask of used entries */
00015       } Summary16;
00016
00017 #define iconv_init            NAMESPACE (iconv_init)
00018 #define iconv_strerror        NAMESPACE (iconv_strerror)
00019 #define IDNA_convert_to_ACE   NAMESPACE (IDNA_convert_to_ACE)
00020 #define IDNA_convert_from_ACE NAMESPACE (IDNA_convert_from_ACE)
00021
00022 extern const char *iconv_strerror (int rc);
00023 extern BOOL        iconv_init (WORD code_page);
00024
00025 extern BOOL IDNA_convert_to_ACE   (char *name, size_t *size);
00026 extern BOOL IDNA_convert_from_ACE (char *name, size_t *size);
00027
00028 #ifndef MAX_LABELS
00029 #define MAX_LABELS 8
00030 #endif
00031
00032 #if defined(USE_DEBUG) || defined(TEST_PROG)
00033   #define IDNA_DEBUG(lvl, args) \
00034           do { \
00035             if (debug_on >= lvl) { \
00036               (*_printf) ("%s(%u): ", __FILE__, __LINE__); \
00037               (*_printf) args; \
00038               fflush (stdout); \
00039             } \
00040           } while (0)
00041 #else
00042   #define IDNA_DEBUG(lvl, args)  ((void)0)
00043 #endif
00044
00045 #define RET_ILUNI      -1
00046 #define RET_ILSEQ      -2
00047 #define RET_TOOSMALL   -3
00048 #define RET_TOOFEW(n) (-4-(n))
00049
00050 #endif  /* _w32_IDNA_H */
00051
Generated on Wed Jan 25 15:42:35 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/IOCTL.C Source File

SRC/IOCTL.C

Go to the documentation of this file.
00001
00005 /*  BSD sockets functionality for Waterloo TCP/IP
00006  *
00007  *  Copyright (c) 1997-2002 Gisle Vanem <giva@bgnett.no>
00008  *
00009  *  Redistribution and use in source and binary forms, with or without
00010  *  modification, are permitted provided that the following conditions
00011  *  are met:
00012  *  1. Redistributions of source code must retain the above copyright
00013  *     notice, this list of conditions and the following disclaimer.
00014  *  2. Redistributions in binary form must reproduce the above copyright
00015  *     notice, this list of conditions and the following disclaimer in the
00016  *     documentation and/or other materials provided with the distribution.
00017  *  3. All advertising materials mentioning features or use of this software
00018  *     must display the following acknowledgement:
00019  *       This product includes software developed by Gisle Vanem
00020  *       Bergen, Norway.
00021  *
00022  *  THIS SOFTWARE IS PROVIDED BY ME (Gisle Vanem) AND CONTRIBUTORS ``AS IS''
00023  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00024  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00025  *  ARE DISCLAIMED.  IN NO EVENT SHALL I OR CONTRIBUTORS BE LIABLE FOR ANY
00026  *  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00027  *  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00028  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00029  *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00030  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00031  *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00032  *
00033  *  Version
00034  *
00035  *  0.5 : Dec 18, 1997 : G. Vanem - created
00036  */
00037
00038 #define BSD    /* in order to include SIOxx macros in <sys/ioctl.h> */
00039
00040 #include "socket.h"
00041
00042 #if defined(USE_BSD_API)
00043
00044 static int file_ioctrl  (Socket *socket, long cmd, char *argp);
00045 static int iface_ioctrl (Socket *socket, long cmd, char *argp);
00046 static int arp_ioctrl   (Socket *socket, long cmd, char *argp);
00047 static int waterm_ioctrl(Socket *socket, long cmd, char *argp);
00048
00049 #define NO_CMD(cmd) SOCK_DEBUGF ((", unsupported cmd %d, group %c", \
00050                                   (int)((cmd) & IOCPARM_MASK),      \
00051                                   (char)IOCGROUP(cmd)))
00052 #ifdef USE_DEBUG
00053 static const char *get_ioctl_cmd (long cmd);
00054 #endif
00055
00056 #ifndef NUM_IFACES
00057 #define NUM_IFACES 1
00058 #endif
00059
00060 #ifndef ARPHRD_FDDI
00061 #define ARPHRD_FDDI 10
00062 #endif
00063
00064 int W32_CALL ioctlsocket (int s, long cmd, char *argp)
00065 {
00066   Socket *socket = _socklist_find (s);
00067
00068   SOCK_PROLOGUE (socket, "\nioctlsocket:%d", s);
00069
00070   SOCK_DEBUGF ((", %s", get_ioctl_cmd(cmd)));
00071
00072   switch (IOCGROUP(cmd))
00073   {
00074     case 'f':
00075          return file_ioctrl (socket, cmd, argp);
00076
00077     case 'I':
00078          return iface_ioctrl (socket, cmd, argp);
00079
00080     case 's':
00081          return waterm_ioctrl (socket, cmd, argp);
00082
00083     default:
00084          NO_CMD (cmd);
00085          SOCK_ERRNO (ESOCKTNOSUPPORT);
00086   }
00087   return (-1);
00088 }
00089
00090 /*
00091  * IO-control for "file" handles (i.e. stream/datagram sockets)
00092  */
00093 static int file_ioctrl (Socket *socket, long cmd, char *argp)
00094 {
00095   int len;
00096
00097   VERIFY_RW (argp, sizeof(*argp));
00098
00099   switch ((DWORD)cmd)
00100   {
00101     case FIONREAD:
00102          if (socket->so_type != SOCK_DGRAM &&
00103              socket->so_type != SOCK_STREAM)
00104          {
00105            SOCK_ERRNO (EBADF);
00106            return (-1);
00107          }
00108          if (socket->so_type == SOCK_DGRAM)
00109          {
00110            if (socket->so_state & SS_PRIV)
00111                 len = sock_recv_used ((sock_type*)socket->udp_sock);
00112            else len = sock_rbused ((sock_type*)socket->udp_sock);
00113          }
00114          else
00115            len = sock_rbused ((sock_type*)socket->tcp_sock);
00116
00117          if (len < 0)
00118          {
00119            SOCK_ERRNO (EBADF);
00120            return (-1);
00121          }
00122
00123          SOCK_DEBUGF ((" %d", len));
00124          if (len >= 0)
00125             *(u_long*)argp = len;
00126          break;
00127
00128     case FIONBIO:                 /* set nonblocking I/O on/off */
00129          if (*argp)
00130          {
00131            socket->so_state |= SS_NBIO;
00132            socket->timeout = 0;
00133            if (socket->tcp_sock)
00134               socket->tcp_sock->timeout = 0;
00135          }
00136          else
00137          {
00138            socket->so_state &= ~SS_NBIO;
00139            socket->timeout = sock_delay;
00140          }
00141          SOCK_DEBUGF ((" %d", (socket->so_state & SS_NBIO) ? 1 : 0));
00142          break;
00143
00144 #if 0
00145     case FIOASYNC:
00146     case FIOCLEX:
00147     case FIONCLEX:
00148     case FIONREAD:
00149     case FIOSETOWN:
00150     case FIOGETOWN:
00151 #endif
00152
00153     default:
00154          NO_CMD (cmd);
00155          SOCK_ERRNO (ESOCKTNOSUPPORT);
00156          return (-1);
00157   }
00158   return (0);
00159 }
00160
00161 /*
00162  * Return name of this interface.
00163  * We only support a single interface at a time.
00164  */
00165 static char eth_ifname [IFNAMSIZ] = "eth0";
00166 static char arc_ifname [IFNAMSIZ] = "arch0";
00167 static char tok_ifname [IFNAMSIZ] = "tr0";
00168 static char fddi_ifname[IFNAMSIZ] = "fddi0";
00169 static char ppp_ifname [IFNAMSIZ] = "ppp0";
00170 static char slp_ifname [IFNAMSIZ] = "slp0";
00171
00172 void __get_ifname (char *if_name)
00173 {
00174   switch (_pktdevclass)
00175   {
00176     case PDCLASS_ETHER:
00177          strcpy (if_name, eth_ifname);
00178          break;
00179     case PDCLASS_TOKEN:
00180          strcpy (if_name, tok_ifname);
00181          break;
00182     case PDCLASS_FDDI:
00183          strcpy (if_name, fddi_ifname);
00184          break;
00185     case PDCLASS_ARCNET:
00186          strcpy (if_name, arc_ifname);
00187          break;
00188     case PDCLASS_SLIP:
00189          strcpy (if_name, slp_ifname);
00190          break;
00191     case PDCLASS_PPP:
00192          strcpy (if_name, ppp_ifname);
00193          break;
00194     default:
00195          strcpy (if_name, "??");
00196          break;
00197   }
00198 }
00199
00200 #ifdef NOT_USED_YET
00201 /*
00202  * Set a new name for this interface.
00203  */
00204 void __set_ifname (const char *if_name)
00205 {
00206   switch (_pktdevclass)
00207   {
00208     case PDCLASS_ETHER:
00209          strcpy (eth_ifname, if_name);
00210          break;
00211     case PDCLASS_TOKEN:
00212          strcpy (tok_ifname, if_name);
00213          break;
00214     case PDCLASS_FDDI:
00215          strcpy (fddi_name, if_ifname);
00216          break;
00217     case PDCLASS_ARCNET:
00218          strcpy (arc_name, if_ifname);
00219          break;
00220     case PDCLASS_SLIP:
00221          strcpy (slp_ifname, if_name);
00222          break;
00223     case PDCLASS_PPP:
00224          strcpy (ppp_ifname, if_name);
00225          break;
00226     default:
00227          break;
00228   }
00229 }
00230
00231 static struct ifnet *eth_ifnet (void)
00232 {
00233   static struct ifnet net;
00234
00236   return (&net);
00237 }
00238
00239 static struct ifnet *tok_ifnet (void)
00240 {
00241   static struct ifnet net;
00242
00244   return (&net);
00245 }
00246 #endif
00247
00248 /*
00249  * Handler for interface request get/set commands
00250  */
00251 static int iface_ioctrl (Socket *socket, long cmd, char *argp)
00252 {
00253   struct ifreq       *ifr = (struct ifreq *) argp;
00254   struct ifconf      *ifc = (struct ifconf*) argp;
00255   struct sockaddr_in *sin;
00256   const eth_address  *eth;
00257   int   len;
00258
00259   VERIFY_RW (argp, sizeof(*ifr));
00260
00261   switch ((DWORD)cmd)
00262   {
00263     case SIOCSARP:
00264     case SIOCGARP:
00265     case SIOCDARP:
00266          return arp_ioctrl (socket, cmd, argp);
00267
00268     case SIOCGIFADDR:                /* get interface address */
00269     case OSIOCGIFADDR:
00270          __get_ifname (ifr->ifr_name);
00271
00272          if (ifr->ifr_addr.sa_family == AF_INET)
00273          {
00274            struct sockaddr_in *sin = (struct sockaddr_in*) &ifr->ifr_addr;
00275            sin->sin_addr.s_addr = htonl (my_ip_addr);
00276            break;
00277          }
00278 #if defined(USE_IPV6)
00279          if (ifr->ifr_addr.sa_family == AF_INET6)
00280          {
00281            struct sockaddr_in6 *sin = (struct sockaddr_in6*) &ifr->ifr_addr;
00282            memcpy (&sin->sin6_addr, &in6addr_my_ip, sizeof(sin->sin6_addr));
00283            break;
00284          }
00285 #endif
00286          if (_pktdevclass == PDCLASS_TOKEN  || /* otherwise return MAC addr? */
00287              _pktdevclass == PDCLASS_ETHER  ||
00288              _pktdevclass == PDCLASS_ARCNET ||
00289              _pktdevclass == PDCLASS_FDDI)
00290               memcpy (ifr->ifr_addr.sa_data, _eth_addr, sizeof(_eth_addr));
00291          else memset (ifr->ifr_addr.sa_data, 0, sizeof(ifr->ifr_addr.sa_data));
00292          break;
00293
00294     case SIOCGIFMTU:                 /* get interface MTU */
00295          ifr->ifr_mtu = _mtu;
00296          break;
00297
00298 #if 0
00299     case SIOCGIFNAME:                /* get interface name */
00300          break;
00301 #endif
00302
00303     case SIOCSIFADDR:                /* set interface address */
00304          if (ifr->ifr_addr.sa_family == AF_INET)
00305          {
00306            sin = (struct sockaddr_in*) &ifr->ifr_addr;
00307            my_ip_addr = ntohl (sin->sin_addr.s_addr);
00308            break;
00309          }
00310 #if defined(USE_IPV6)
00311          if (ifr->ifr_addr.sa_family == AF_INET6)
00312          {
00313            struct sockaddr_in6 *sin = (struct sockaddr_in6*) &ifr->ifr_addr;
00314            memcpy ((void*)&in6addr_my_ip, &sin->sin6_addr, sizeof(in6addr_my_ip));
00315            break;
00316          }
00317 #endif
00318          eth = (const eth_address*) ifr->ifr_addr.sa_data;  /* ?? */
00319          if (!_eth_set_addr(eth))
00320          {
00321            SOCK_ERRNO (EINVAL);
00322            return (-1);
00323          }
00324          break;
00325
00326     case OSIOCGIFDSTADDR:
00327     case SIOCGIFDSTADDR:
00329          break;
00330
00331     case SIOCSIFDSTADDR:
00333          break;
00334
00335     case SIOCSIFFLAGS:   /* set iface flags */
00336          /* Allow other socket types to do this?
00337           */
00338          if (socket->so_type == SOCK_PACKET)
00339          {
00340            BOOL rc;
00341
00342            if (ifr->ifr_flags & IFF_PROMISC)
00343                 rc = _sock_set_promisc_rx_mode();
00344            else if (ifr->ifr_flags & IFF_ALLMULTI)
00345                 rc = _sock_set_mcast_rx_mode();
00346            else rc = _sock_set_normal_rx_mode (socket);
00347            if (!rc)
00348            {
00349              SOCK_ERRNO (ENETDOWN);
00350              return (-1);
00351            }
00352          }
00353          break;
00354
00355     case SIOCGIFFLAGS:               /* get iface flags */
00356          ifr->ifr_flags = 0;
00357          if (_eth_is_init)
00358          {
00359            ifr->ifr_flags |= (IFF_UP | IFF_RUNNING);
00360
00361            if (_pkt_rxmode == RXMODE_PROMISCOUS)
00362               ifr->ifr_flags |= IFF_PROMISC;
00363
00364            if (_pkt_rxmode >= RXMODE_MULTICAST2)
00365               ifr->ifr_flags |= IFF_ALLMULTI;
00366
00367            if (_pktdevclass == PDCLASS_PPP  ||
00368                _pktdevclass == PDCLASS_SLIP ||
00369                _pktdevclass == PDCLASS_AX25)
00370                 ifr->ifr_flags |= IFF_POINTOPOINT;
00371            else ifr->ifr_flags |= IFF_BROADCAST;  /* ARCNET broadcast? */
00372
00373 #if defined(USE_MULTICAST)
00374            if (_multicast_on)
00375               ifr->ifr_flags |= IFF_MULTICAST;
00376 #endif
00377          }
00378          break;
00379
00380     case SIOCGIFBRDADDR:             /* get IP broadcast address */
00381     case OSIOCGIFBRDADDR:
00382          sin = (struct sockaddr_in*) &ifr->ifr_broadaddr;
00383          sin->sin_addr.s_addr = htonl (my_ip_addr | ~sin_mask);
00384          sin->sin_family      = AF_INET;
00385          __get_ifname (ifr->ifr_name);
00386          break;
00387
00388     case SIOCSIFBRDADDR:             /* set IP broadcast address */
00389          break;
00390
00391     case SIOCGIFMETRIC:              /* get interface metric */
00392          ifr->ifr_metric = 1;
00393          __get_ifname (ifr->ifr_name);
00394          break;
00395
00396     case SIOCSIFMETRIC:
00398          break;
00399
00400     case SIOCDIFADDR:                /* delete interface addr */
00401 #if defined(USE_IPV6)
00402          if (ifr->ifr_addr.sa_family == AF_INET6)
00403          {
00404            memset ((void*)&in6addr_my_ip, 0, sizeof(in6addr_my_ip));
00405            break;
00406          }
00407 #endif
00408          if (ifr->ifr_addr.sa_family == AF_INET)
00409          {
00410            my_ip_addr = 0;
00411            break;
00412          }
00413
00415          break;
00416
00417     case SIOCAIFADDR:
00419          break;
00420
00421     case SIOCGIFNETMASK:             /* get interface net-mask */
00422     case OSIOCGIFNETMASK:
00423          sin = (struct sockaddr_in*) &ifr->ifr_addr;
00424          sin->sin_addr.s_addr = htonl (sin_mask);
00425          sin->sin_family      = AF_INET;
00426          __get_ifname (ifr->ifr_name);
00427          break;
00428
00429     case SIOCSIFNETMASK:             /* set interface net-mask */
00430          sin = (struct sockaddr_in*) &ifr->ifr_addr;
00431          sin_mask = ntohl (sin->sin_addr.s_addr);
00432          break;
00433
00434     case SIOCGIFCONF:                /* get interfaces config */
00435     case OSIOCGIFCONF:
00436          len = ifc->ifc_len = min (ifc->ifc_len, NUM_IFACES*SIZEOF(*ifr));
00437          ifc = (struct ifconf*) ifc->ifc_buf; /* user's buffer */
00438          VERIFY_RW (ifc, len);
00439
00440          ifr = (struct ifreq*) ifc;
00441          __get_ifname (ifr->ifr_name);
00442          sin = (struct sockaddr_in*) &ifr->ifr_addr;
00443          sin->sin_addr.s_addr = htonl (my_ip_addr);
00444          sin->sin_family      = AF_INET;
00445          break;
00446
00447     case SIOCGIFHWADDR:
00448          switch (_pktdevclass)
00449          {
00450            case PDCLASS_ETHER:
00451                 ifr->ifr_hwaddr.sa_family = ARPHRD_ETHER;
00452                 memcpy (ifr->ifr_hwaddr.sa_data, _eth_addr,
00453                         sizeof(ifr->ifr_hwaddr.sa_data));
00454                 break;
00455            case PDCLASS_TOKEN:
00456                 ifr->ifr_hwaddr.sa_family = ARPHRD_TOKEN;
00457                 memcpy (ifr->ifr_hwaddr.sa_data, _eth_addr,
00458                         sizeof(ifr->ifr_hwaddr.sa_data));
00459                 break;
00460            case PDCLASS_FDDI:
00461                 ifr->ifr_hwaddr.sa_family = ARPHRD_FDDI;
00462                 memcpy (ifr->ifr_hwaddr.sa_data, _eth_addr,
00463                         sizeof(ifr->ifr_hwaddr.sa_data));
00464                 break;
00465            case PDCLASS_ARCNET:
00466                 ifr->ifr_hwaddr.sa_family  = ARPHRD_ARCNET;
00467                 ifr->ifr_hwaddr.sa_data[0] = _eth_addr[0];
00468                 break;
00469            case PDCLASS_SLIP:
00470            case PDCLASS_PPP:
00471                 ifr->ifr_hwaddr.sa_family = 0;
00472                 memset (ifr->ifr_hwaddr.sa_data, 0,
00473                         sizeof(ifr->ifr_hwaddr.sa_data));
00474                 break;
00475            default:
00476                 return (-1);
00477          }
00478          break;
00479
00480     default:
00481          NO_CMD (cmd);
00482          SOCK_ERRNO (ESOCKTNOSUPPORT);
00483          return (-1);
00484   }
00485   ARGSUSED (len);
00486   return (0);
00487 }
00488
00489
00490 /*
00491  * Handler for buffer hi/lo watermark and urgent data (OOB)
00492  */
00493 static int waterm_ioctrl (Socket *socket, long cmd, char *argp)
00494 {
00495   VERIFY_RW (argp, sizeof(*argp));
00496
00497   switch ((DWORD)cmd)
00498   {
00499     case SIOCSHIWAT:
00501          break;
00502
00503     case SIOCGHIWAT:
00505          break;
00506
00507     case SIOCSLOWAT:
00509          break;
00510
00511     case SIOCGLOWAT:
00513          break;
00514
00515     case SIOCATMARK:
00517          break;
00518
00519     default:
00520          NO_CMD (cmd);
00521          SOCK_ERRNO (ESOCKTNOSUPPORT);
00522          return (-1);
00523   }
00524   ARGSUSED (socket);
00525   ARGSUSED (argp);
00526   return (0);
00527 }
00528
00529
00530 /*
00531  * Handler for ARP-cache interface commands
00532  */
00533 static int arp_ioctrl (Socket *socket, long cmd, char *argp)
00534 {
00535   struct arpreq *arp = (struct arpreq*) argp;
00536   eth_address   *eth;
00537   DWORD  ip;
00538
00539   switch ((DWORD)cmd)
00540   {
00541     case SIOCSARP:      /* add given IP/MAC-addr pair to ARP cache */
00542          ip  = intel (*(DWORD*)arp->arp_pa.sa_data);
00543          eth = (eth_address*) arp->arp_ha.sa_data;
00544          if (!_arp_add_cache (ip, (const eth_address*)eth, FALSE))
00545          {
00546            SOCK_ERRNO (EINVAL);
00547            return (-1);
00548          }
00549          break;
00550
00551     case SIOCGARP:      /* return ARP entry for given ip */
00552     case OSIOCGARP:
00553          ip  = intel (*(DWORD*)arp->arp_pa.sa_data);
00554          eth = (eth_address*) arp->arp_ha.sa_data;
00555          if (arp_lookup_fixed (ip, eth))
00556          {
00557            arp->arp_flags |= (ATF_INUSE | ATF_COM | ATF_PERM);  /* fixed addr */
00558          }
00559          else if (arp_lookup (ip, eth))
00560          {
00561            arp->arp_flags |= (ATF_INUSE | ATF_COM);   /* dynamic addr */
00562          }
00563          else
00564          {
00565            arp->arp_flags = 0;
00566            SOCK_ERRNO (ENOENT);
00567            return (-1);
00568          }
00569          break;
00570
00571     case SIOCDARP:      /* delete ARP-entry for given ip */
00572          ip = intel (*(DWORD*)arp->arp_pa.sa_data);
00573          if (!_arp_delete_cache (ip))
00574          {
00575            SOCK_ERRNO (ENOENT);
00576            return (-1);
00577          }
00578          break;
00579
00580     default:
00581          NO_CMD (cmd);
00582          SOCK_ERRNO (ESOCKTNOSUPPORT);
00583          return (-1);
00584   }
00585   ARGSUSED (socket);
00586   return (0);
00587 }
00588
00589 /*
00590  * Return string for ioctlsocket() command
00591  */
00592 #if defined (USE_DEBUG)
00593 static const struct search_list commands[] = {
00594                   { FIOCLEX,         "FIOCLEX"         },
00595                   { FIONCLEX,        "FIONCLEX"        },
00596                   { FIONREAD,        "FIONREAD"        },
00597                   { FIONBIO,         "FIONBIO"         },
00598                   { FIOASYNC,        "FIOASYNC"        },
00599                   { FIOSETOWN,       "FIOSETOWN"       },
00600                   { FIOGETOWN,       "FIOGETOWN"       },
00601                   { SIOCSPGRP,       "SIOCSPGRP"       },
00602                   { SIOCGPGRP,       "SIOCGPGRP"       },
00603                   { SIOCADDRT,       "SIOCADDRT"       },
00604                   { SIOCDELRT,       "SIOCDELRT"       },
00605                   { SIOCSIFADDR,     "SIOCSIFADDR"     },
00606                   { OSIOCGIFADDR,    "OSIOCGIFADDR"    },
00607                   { SIOCGIFADDR,     "SIOCGIFADDR"     },
00608                   { SIOCSIFDSTADDR,  "SIOCSIFDSTADDR"  },
00609                   { OSIOCGIFDSTADDR, "OSIOCGIFDSTADDR" },
00610                   { SIOCGIFDSTADDR,  "SIOCGIFDSTADDR"  },
00611                   { SIOCSIFFLAGS,    "SIOCSIFFLAGS"    },
00612                   { SIOCGIFFLAGS,    "SIOCGIFFLAGS"    },
00613                   { OSIOCGIFBRDADDR, "OSIOCGIFBRDADDR" },
00614                   { SIOCGIFBRDADDR,  "SIOCGIFBRDADDR"  },
00615                   { SIOCSIFBRDADDR,  "SIOCSIFBRDADDR"  },
00616                   { OSIOCGIFCONF,    "OSIOCGIFCONF"    },
00617                   { SIOCGIFCONF,     "SIOCGIFCONF"     },
00618                   { OSIOCGIFNETMASK, "OSIOCGIFNETMASK" },
00619                   { SIOCGIFNETMASK,  "SIOCGIFNETMASK"  },
00620                   { SIOCSIFNETMASK,  "SIOCSIFNETMASK"  },
00621                   { SIOCGIFMETRIC,   "SIOCGIFMETRIC"   },
00622                   { SIOCSIFMETRIC,   "SIOCSIFMETRIC"   },
00623                   { SIOCDIFADDR,     "SIOCDIFADDR"     },
00624                   { SIOCAIFADDR,     "SIOCAIFADDR"     },
00625                   { SIOCGIFMTU,      "SIOCGIFMTU"      },
00626                   { SIOCSARP,        "SIOCSARP"        },
00627                   { OSIOCGARP,       "OSIOCGARP"       },
00628                   { SIOCGARP,        "SIOCGARP"        },
00629                   { SIOCDARP,        "SIOCDARP"        },
00630                   { SIOCSHIWAT,      "SIOCSHIWAT"      },
00631                   { SIOCGHIWAT,      "SIOCGHIWAT"      },
00632                   { SIOCSLOWAT,      "SIOCSLOWAT"      },
00633                   { SIOCGLOWAT,      "SIOCGLOWAT"      },
00634                   { SIOCATMARK,      "SIOCATMARK"      },
00635                   { SIOCGIFHWADDR,   "SIOCGIFHWADDR"   }
00636                 };
00637
00638 static const char *get_ioctl_cmd (long cmd)
00639 {
00640   static char buf[50];
00641
00642   switch (IOCGROUP(cmd))
00643   {
00644     case 'f':
00645          strcpy (buf, "file cmd: ");
00646          break;
00647
00648     case 'I':
00649          strcpy (buf, "iface cmd: ");
00650          break;
00651
00652     case 's':
00653          strcpy (buf, "waterm cmd: ");
00654          break;
00655
00656     default:
00657          return ("??unknown");
00658   }
00659   strcat (buf, list_lookup(cmd, commands, DIM(commands)));
00660   return (buf);
00661 }
00662 #endif
00663
00664
00665 /*
00666  * A small test program for above functions.
00667  */
00668 #if defined(TEST_PROG)
00669
00670 #undef  assert
00671 #define assert(x) ((x) ? (void)0 : AssertFail(__LINE__))
00672
00673 void AssertFail (unsigned line)
00674 {
00675   fprintf (stderr, "\nAssert failed at line %d, errno = %d (%s)\n",
00676            line, errno, strerror (errno));
00677   exit (-1);
00678 }
00679
00680 char *eth_addr_string (struct ether_addr *eth)
00681 {
00682   static char buf[20];
00683
00684   sprintf (buf, "%02X:%02X:%02X:%02X:%02X:%02X",
00685            eth->ether_addr_octet[0],
00686            eth->ether_addr_octet[1],
00687            eth->ether_addr_octet[2],
00688            eth->ether_addr_octet[3],
00689            eth->ether_addr_octet[4],
00690            eth->ether_addr_octet[5]);
00691   return (buf);
00692 }
00693
00694 int main (void)
00695 {
00696   struct ifreq ifr;
00697   struct sockaddr_in *sin;
00698   int    sock, on = 1;
00699
00700   dbug_init();
00701
00702   sock = socket (AF_INET, SOCK_DGRAM, 0);
00703   assert (sock > 0);
00704   assert (setsockopt(sock, SOL_SOCKET, SO_DEBUG, &on,sizeof(on)) == 0);
00705
00706   ifr.ifr_addr.sa_family = AF_UNSPEC;  /* get MAC-address */
00707
00708   assert (ioctlsocket (sock, SIOCGIFADDR, (char*)&ifr) == 0);
00709   printf ("Interface `%s':\n\t ether-addr: %s\n",
00710           ifr.ifr_name,
00711           eth_addr_string ((struct ether_addr*)&ifr.ifr_addr.sa_data));
00712
00713   assert (ioctlsocket (sock, SIOCGIFBRDADDR, (char*)&ifr) == 0);
00714   sin = (struct sockaddr_in*) &ifr.ifr_broadaddr;
00715   printf ("\t bcast-addr: %s\n", inet_ntoa (sin->sin_addr));
00716
00717   ifr.ifr_addr.sa_family = AF_INET;
00718
00719   assert (ioctlsocket (sock, SIOCGIFADDR, (char*)&ifr) == 0);
00720   sin = (struct sockaddr_in*) &ifr.ifr_addr;
00721   printf ("\t inet-addr:  %s\n", inet_ntoa (sin->sin_addr));
00722
00723   assert (ioctlsocket (sock, SIOCGIFNETMASK, (char*)&ifr) == 0);
00724   printf ("\t net-mask :  %s\n", inet_ntoa (*(struct in_addr*)&ifr.ifr_addr.sa_data));
00725
00726   assert (close_s(sock) >= 0);
00727   return (0);
00728 }
00729
00730 #endif  /* TEST_PROG */
00731 #endif  /* USE_BSD_API */
Generated on Wed Jan 25 15:42:35 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/IOPORT.H Source File

SRC/IOPORT.H

Go to the documentation of this file.
00001
00003 #ifndef _w32_IOPORT_H
00004 #define _w32_IOPORT_H
00005
00006 /*
00007  * Make sure <conio.h> (or <pc.h> for djgpp) gets included
00008  */
00009 #if !defined(_w32_TARGET_H)
00010 #error You must include IOPORT.H after TARGET.H
00011 #endif
00012
00013 /*
00014  * Macros necessary to bypass the limitation of Borland's BCC32 not
00015  * to allow inline port functions. Assignements should be volatile,
00016  * check the .asm output.
00017  * NB! macro-args must be TASM/MASM compatible
00018  */
00019
00020 #if defined(__BORLANDC__) && defined(__FLAT__)
00021   #define VOLATILE        volatile
00022   #define __in(p,t,z)     ( _DX = (unsigned short)(p),__emit__(0xEC+z),(unsigned t)_AX )
00023   #define __out(p,x,z)    { _AX = (unsigned short)(x); _DX = (unsigned short)(p);__emit__(0xEE+z); }
00024   #define _inportb(p)     __in(p,char,0)
00025   #define _inportw(p)     __in(p,short,1)
00026   #define _outportb(p,x)  __out(p,x,0)
00027   #define _outportw(p,x)  __out(p,x,1)
00028
00029 #elif defined (__HIGHC__)
00030   #define _inportb(p)     _inb(p)
00031   #define _inportw(p)     _inw(p)
00032   #define _outportb(p,x)  _outb(p,x)
00033   #define _outportw(p,x)  _outpw(p,x)
00034   #define VOLATILE
00035
00036 #elif defined (__DJGPP__) || defined (__EMX__)
00037   #define _inportb(p)     inportb(p)
00038   #define _inport(p)      inportw(p)
00039   #define _outportb(p,x)  outportb(p,x)
00040   #define _outportw(p,x)  outportw(p,x)
00041   #define VOLATILE
00042
00043 #elif defined(_MSC_VER) && (_MSC_VER >= 800)
00044   #include <conio.h>
00045   #pragma intrinsic (_inp, _inpw, _outp, _outpw)
00046   #define _inportb(p)     _inp(p)
00047   #define _inportw(p)     _inpw(p)
00048   #define _outportb(p,x)  _outp(p,x)
00049   #define _outportw(p,x)  _outpw(p,x)
00050   #define VOLATILE
00051
00052 #else
00053   #define _inportb(p)     inp(p)
00054   #define _inportw(p)     inpw(p)
00055   #define _outportb(p,x)  outp(p,x)
00056   #define _outportw(p,x)  outpw(p,x)
00057   #define VOLATILE
00058 #endif
00059
00060 #if defined (__EMX__)
00061
00062 /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
00063
00064 extern __inline__ unsigned char inportb (unsigned short port)
00065 {
00066   unsigned char rc;
00067   __asm__ __volatile__ (
00068             "inb %1, %0"
00069           : "=a" (rc)
00070           : "dN" (port));
00071   return (rc);
00072 }
00073
00074 extern __inline__ unsigned short inportw (unsigned short port)
00075 {
00076   unsigned short rc;
00077   __asm__ __volatile__ (
00078             "inw %1, %0"
00079           : "=a" (rc)
00080           : "dN" (port));
00081   return (rc);
00082 }
00083
00084 extern __inline__ void outportb (unsigned short port, unsigned char data)
00085 {
00086   __asm__ __volatile__ (
00087              "outb %1, %0"
00088           :: "dN" (port),
00089              "a" (data));
00090 }
00091
00092 extern __inline__ void outportw (unsigned short port, unsigned short data)
00093 {
00094   __asm__ __volatile__ (
00095              "outw %1, %0"
00096           :: "dN" (port),
00097              "a" (data));
00098 }
00099 #endif  /* __EMX__ */
00100 #endif  /* _w32_IOPORT_H */
00101
Generated on Wed Jan 25 15:42:35 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/IP4_FRAG.C Source File

SRC/IP4_FRAG.C

Go to the documentation of this file.
00001
00005 /*
00006  *  Packet de-fragmentation code for WATTCP
00007  *  Written by and COPYRIGHT (c)1993 to Quentin Smart
00008  *                               smart@actrix.gen.nz
00009  *  all rights reserved.
00010  *
00011  *    This software is distributed in the hope that it will be useful,
00012  *    but without any warranty; without even the implied warranty of
00013  *    merchantability or fitness for a particular purpose.
00014  *
00015  *    You may freely distribute this source code, but if distributed for
00016  *    financial gain then only executables derived from the source may be
00017  *    sold.
00018  *
00019  *  Murf = Murf@perftech.com
00020  *  other fragfix = mdurkin@tsoft.net
00021  *
00022  *  Based on RFC815
00023  *
00024  *  Code used to use pktbuf[] as reassembly buffer. It now allocates
00025  *  a "bucket" dynamically. There are MAX_IP_FRAGS buckets to handle
00026  *  at the same time.
00027  *
00028  *  G.Vanem 1998 <giva@bgnett.no>
00029  */
00030
00031 #include <stdio.h>
00032 #include <stdlib.h>
00033 #include <limits.h>
00034 #include <arpa/inet.h>
00035
00036 #include "wattcp.h"
00037 #include "strings.h"
00038 #include "language.h"
00039 #include "misc.h"
00040 #include "timer.h"
00041 #include "chksum.h"
00042 #include "pcconfig.h"
00043 #include "pcqueue.h"
00044 #include "pcstat.h"
00045 #include "pcpkt.h"
00046 #include "pcicmp.h"
00047 #include "pctcp.h"
00048 #include "pcdbug.h"
00049 #include "netaddr.h"
00050 #include "ip4_in.h"
00051 #include "ip4_out.h"
00052 #include "ip4_frag.h"
00053
00054 #define MAX_IP_FRAGS     2   /* max # of fragmented IP-packets */
00055 #define MAX_IP_HOLDTIME  15  /* time (in sec) to hold before discarding */
00056
00057 int _ip4_frag_reasm = MAX_IP_HOLDTIME;
00058
00059 #if defined(USE_FRAGMENTS)
00060
00061 /*@-nullderef@*/
00062
00063 #if 0
00064 #undef  MAX_FRAGMENTS
00065 #define MAX_FRAGMENTS   20U   /* !! test */
00066 #define MAX_FRAG_SIZE   (MAX_FRAGMENTS * MAX_IP4_DATA) // 29600
00067 #endif
00068
00069 #define BUCKET_SIZE     (sizeof(HugeIP))  /* ~= 64k bytes */
00070 #define BUCKET_MARKER   0xDEAFABBA
00071
00072 typedef struct huge_ip {
00073         in_Header hdr;
00074         BYTE      data [MAX_FRAG_SIZE];   /* 66600 for DOSX */
00075         DWORD     marker;
00076       } HugeIP;
00077
00078 typedef struct {
00079         DWORD  source;
00080         DWORD  destin;
00081         WORD   ident;
00082         BYTE   proto;
00083       } frag_key;
00084
00085 typedef struct {
00086         BOOL        used;     /* this bucket is taken */
00087         BOOL        got_ofs0; /* we've received ofs-0 fragment */
00088         int         active;   /* # of active fragments */
00089         frag_key    key;      /* key for matching new fragments */
00090         mac_address mac_src;  /* remember for icmp_send_timexceed() */
00091         HugeIP     *ip;       /* malloced, size = (BUCKET_SIZE) */
00092       } frag_bucket;
00093
00094 typedef struct hd {
00095         struct hd *next;
00096         long       start;
00097         long       end;
00098       } hole_descr;
00099
00100 typedef struct {
00101         BOOL        used;     /* this position in table in use */
00102         DWORD       timer;
00103         hole_descr *hole_first;
00104         in_Header  *ip;
00105         BYTE       *data_offset;
00106       } frag_hdr;
00107
00108
00109 static frag_hdr    frag_list   [MAX_IP_FRAGS][MAX_FRAGMENTS];
00110 static frag_bucket frag_buckets[MAX_IP_FRAGS];
00111
00112 static long        data_start;  /* NB! global data; not reentrant */
00113 static long        data_end;
00114 static long        data_length;
00115 static BOOL        more_frags;
00116
00117 static BOOL       setup_first_frag  (const in_Header *ip, int idx);
00118 static in_Header *alloc_frag_buffer (const in_Header *ip, int idx);
00119
00120 #if defined(__DJGPP__) && 0
00121   #define FIND_FRAG_BUG
00122 #endif
00123
00124 #if defined(TEST_PROG) || defined(FIND_FRAG_BUG)
00125   #define MSG(x)  printf x
00126 #else
00127   #define MSG(x)  ((void)0)
00128 #endif
00129
00130
00131 /*
00132  * Check if this packet is part of a fragment-chain. It might be
00133  * a last fragment (MF=0) with ofs 0. This would be normal for
00134  * fragments sent from Linux. Look in 'frag_buckets' for a match.
00135  *
00136  * If not found, return FALSE and set '*free' to free bucket.
00137  * If found, return TRUE and set '*slot' to free slot in frag-chain.
00138  */
00139 static BOOL match_frag (const in_Header *ip, int *slot, int *bucket, int *free)
00140 {
00141   frag_key key;
00142   int      i, j;
00143
00144   *bucket = -1;
00145   *slot   = -1;
00146   *free   = -1;
00147
00148   key.source = ip->source;
00149   key.destin = ip->destination;
00150   key.ident  = ip->identification;
00151   key.proto  = ip->proto;
00152
00153   for (j = 0; j < MAX_IP_FRAGS; j++)
00154   {
00155     const frag_bucket *frag = &frag_buckets[j];
00156
00157     if (!frag->used)
00158     {
00159       if (*free == -1)   /* get 1st vacant bucket */
00160          *free = j;
00161       continue;
00162     }
00163
00164     if (memcmp(&key,&frag->key,sizeof(key)))
00165        continue;
00166
00167     for (i = 0; i < (int)MAX_FRAGMENTS; i++)
00168     {
00169       if (!frag_list[j][i].used)
00170       {
00171         *bucket = j;
00172         return (TRUE);
00173       }
00174       *slot = i;
00175     }
00176   }
00177   return (FALSE);
00178 }
00179
00180 /*
00181  * Check and report if fragment data-offset is okay
00182  */
00183 static __inline int check_data_start (const in_Header *ip, DWORD ofs)
00184 {
00185   if (ofs <= MAX_FRAG_SIZE && /* fragment offset okay, < 65528 */
00186       ofs <= USHRT_MAX-8)
00187      return (1);
00188
00189   TCP_CONSOLE_MSG (2, (_LANG("Bad frag-ofs: %lu, ip-prot %u (%s -> %s)\n"),
00190                    ofs, ip->proto,
00191                    _inet_ntoa(NULL,intel(ip->source)),
00192                    _inet_ntoa(NULL,intel(ip->destination))));
00193   ARGSUSED (ip);
00194   return (0);
00195 }
00196
00197 /*
00198  * ip4_defragment() is called if '*ip_ptr' is part of a new or excisting
00199  * fragment chain.
00200  *
00201  * IP header already checked in _ip4_handler().
00202  * Return the reassembled segment (ICMP, UDP or TCP) in '*ip_ptr'.
00203  * We assume MAC-header is the same on all fragments.
00204  * We return a packet with the MAC-header of the first
00205  * fragment received.
00206  */
00207 int ip4_defragment (const in_Header **ip_ptr, DWORD offset, WORD flags)
00208 {
00209   frag_hdr   *frag      = NULL;
00210   hole_descr *hole      = NULL;
00211   hole_descr *prev_hole = NULL;
00212   const in_Header  *ip  = *ip_ptr;
00213
00214   BOOL  found    = FALSE;
00215   BOOL  got_hole = FALSE;
00216   int   i, j, j_free;
00217
00218   /* Check if part of an existing frag-chain or a new fragment
00219    */
00220   if (!match_frag(ip,&i,&j,&j_free))
00221   {
00222     if (i == MAX_FRAGMENTS-1)   /* found but no slots free */
00223     {
00224       STAT (ip4stats.ips_fragments++);
00225       STAT (ip4stats.ips_fragdropped++);
00226       return (0);
00227     }
00228
00229     if (offset == 0)
00230        return (1);
00231
00232     /* Not in frag-list, but ofs > 0. Must be a part of a new
00233      * fragment chain.
00234      */
00235   }
00236
00237   STAT (ip4stats.ips_fragments++);
00238
00239   MSG (("\nip4_defrag: src %s, dst %s, id %04X, ofs %lu, flag %04X\n",
00240         _inet_ntoa(NULL,intel(ip->source)),
00241         _inet_ntoa(NULL,intel(ip->destination)),
00242         intel16(ip->identification), offset, flags));
00243
00244   /* Calculate where data should go
00245    */
00246   data_start  = (long) offset;
00247   data_length = (long) intel16 (ip->length) - in_GetHdrLen (ip);
00248   data_end    = data_start + data_length;
00249   more_frags  = FALSE;  // !!! (flags & IP_MF);
00250
00251   if (!check_data_start(ip,data_start))
00252   {
00253     STAT (ip4stats.ips_fragdropped++);
00254     DEBUG_RX (NULL, ip);
00255     return (0);
00256   }
00257
00258   found = (j > -1);
00259
00260   if (!found)
00261   {
00262     MSG (("bucket=%d, i=%d, key not found\n", j_free, i));
00263     j = j_free;
00264
00265     /* Can't handle any new frags, biff packet
00266      */
00267     if (j == -1 || frag_buckets[j].active == MAX_FRAGMENTS)
00268     {
00269       STAT (ip4stats.ips_fragdropped++);
00270       MSG (("all buckets full\n"));
00271     }
00272     else
00273     {
00274       setup_first_frag (ip, j); /* Setup first fragment received */
00275       if (offset == 0)
00276          frag_buckets[j].got_ofs0 = TRUE;
00277     }
00278     DEBUG_RX (NULL, ip);
00279     return (0);
00280   }
00281
00282   frag = &frag_list[j][i];
00283
00284   MSG (("bucket=%d, slot=%d key found, more_frags=%d, active=%d\n",
00285         j, i, more_frags ? 1 : 0, frag_buckets[j].active));
00286
00287 #if 0
00288   if (!more_frags)           /* Adjust length  */
00289      frag->ip->length = intel16 ((WORD)(data_end + in_GetHdrLen(ip)));
00290 #endif
00291
00292   if (offset == 0)
00293      frag_buckets[j].got_ofs0 = TRUE;
00294
00295   hole = frag->hole_first;   /* Hole handling */
00296
00297   do
00298   {
00299     if (hole && (data_start <= hole->end) &&   /* We've found the spot */
00300         (data_end >= hole->start))
00301     {
00302       long temp = hole->end;    /* Pick up old hole end for later */
00303
00304       got_hole = 1;
00305
00306       more_frags = (intel16(frag->ip->frag_ofs) & IP_MF);  // !!
00307
00308       /* Find where to insert fragment.
00309        * Check if there's a hole before the new frag
00310        */
00311       if (data_start > hole->start)
00312       {
00313         hole->end = data_start - 1;
00314         prev_hole = hole;  /* We have a new prev */
00315       }
00316       else
00317       {
00318         /* No, delete current hole
00319          */
00320         if (!prev_hole)
00321              frag->hole_first = hole->next;
00322         else prev_hole->next  = hole->next;
00323       }
00324
00325       /* Is there a hole after the current fragment?
00326        * Only if we're not last and more to come
00327        */
00328       if (data_end < hole->end /* !! && more_frags */)
00329       {
00330         hole = (hole_descr*) (data_end + 1 + frag->data_offset);
00331         hole->start = data_end + 1;
00332         hole->end   = temp;
00333
00334         /* prev_hole = NULL if first
00335          */
00336         if (!prev_hole)
00337         {
00338           hole->next = frag->hole_first;
00339           frag->hole_first = hole;
00340         }
00341         else
00342         {
00343           hole->next = prev_hole->next;
00344           prev_hole->next = hole;
00345         }
00346       }
00347     }
00348     prev_hole = hole;
00349     hole = hole->next;
00350   }
00351   while (hole);          /* Until we got to the end or found */
00352
00353
00354   /* Thats all setup so copy in the data
00355    */
00356   if (got_hole)
00357      memcpy (frag->data_offset + data_start,
00358              (BYTE*)ip + in_GetHdrLen(ip), (size_t)data_length);
00359
00360   MSG (("got_hole %d, frag->hole_first %lX\n",
00361         got_hole, (DWORD)frag->hole_first));
00362
00363   if (!frag->hole_first /* !! && !more_frags */)  /* Now we have all the parts */
00364   {
00365     if (frag_buckets[j].active >= 1)
00366         frag_buckets[j].active--;
00367
00368     /* Redo checksum as we've changed the length in the header
00369      */
00370     frag->ip->frag_ofs = 0;    /* no MF or frag-ofs */
00371     frag->ip->checksum = 0;
00372     frag->ip->checksum = ~CHECKSUM (frag->ip, sizeof(in_Header));
00373
00374     STAT (ip4stats.ips_reassembled++);
00375     *ip_ptr = frag->ip;      /* MAC-header is in front of IP */
00376     return (1);
00377   }
00378   DEBUG_RX (NULL, ip);
00379   ARGSUSED (flags);
00380   return (0);
00381 }
00382
00383 /*
00384  * Prepare and setup for reassembly
00385  */
00386 static BOOL setup_first_frag (const in_Header *ip, int idx)
00387 {
00388   frag_hdr   *frag;
00389   in_Header  *bucket;
00390   hole_descr *hole;
00391   unsigned    i;
00392
00393   /* Allocate a fragment bucket. MAC-header is in front of bucket.
00394    */
00395   bucket = alloc_frag_buffer (ip, idx);
00396   if (!bucket)
00397   {
00398     STAT (ip4stats.ips_fragdropped++);
00399     MSG (("alloc bucket failed\n"));
00400     return (FALSE);
00401   }
00402
00403   /* Find first empty slot
00404    */
00405   frag = &frag_list[idx][0];
00406   for (i = 0; i < MAX_FRAGMENTS; i++, frag++)
00407       if (!frag->used)
00408          break;
00409
00410   if (i == MAX_FRAGMENTS)
00411   {
00412     STAT (ip4stats.ips_fragdropped++);
00413     MSG (("frag_list[%d] full\n", idx));
00414     return (FALSE);
00415   }
00416
00417   frag->used = TRUE;            /* mark as used */
00418   frag_buckets[idx].active++;   /* inc active frags counter */
00419
00420   MSG (("bucket=%d, active=%u, i=%u\n", idx, frag_buckets[idx].active, i));
00421
00422   /* Remember MAC source address
00423    */
00424   if (_pktserial)
00425        memset (&frag_buckets[idx].mac_src, 0, sizeof(mac_address));
00426   else memcpy (&frag_buckets[idx].mac_src, MAC_SRC(ip), sizeof(mac_address));
00427
00428   /* Setup frag header data, first packet
00429    */
00430   frag_buckets[idx].key.proto  = ip->proto;
00431   frag_buckets[idx].key.source = ip->source;
00432   frag_buckets[idx].key.destin = ip->destination;
00433   frag_buckets[idx].key.ident  = ip->identification;
00434
00435   frag->ip    = bucket;
00436   frag->timer = set_timeout (1000 * min(_ip4_frag_reasm, ip->ttl));
00437
00438   /* Set pointers to beginning of IP packet data
00439    */
00440   frag->data_offset = (BYTE*)bucket + in_GetHdrLen(ip);
00441
00442   /* Setup initial hole table
00443    */
00444   if (data_start == 0)  /* 1st fragment sent is 1st fragment received */
00445   {
00446     WORD  ip_len = intel16 (ip->length);
00447     BYTE *dst    = (BYTE*)bucket;
00448
00449     memcpy (dst, ip, min(ip_len,_mtu));
00450     hole = (hole_descr*) (dst + ip_len + 1);
00451     frag->hole_first = hole;
00452   }
00453   else
00454   {
00455     /* !!fix-me: assumes header length of this fragment is same as
00456      *           in reassembled IP packet (may have IP-options)
00457      */
00458     BYTE *dst = frag->data_offset + data_start;
00459     BYTE *src = (BYTE*)ip + in_GetHdrLen(ip);
00460
00461     memcpy (dst, src, (size_t)data_length);
00462
00463     /* Bracket beginning of data
00464      */
00465     hole        = frag->hole_first = (hole_descr*)frag->data_offset;
00466     hole->start = 0;
00467     hole->end   = data_start - 1;
00468   //if (more_frags)
00469     {
00470       hole->next = (hole_descr*) (frag->data_offset + data_length + 1);
00471       hole = hole->next;
00472     }
00473 #if 0
00474     else
00475     {
00476       hole = frag->hole_first->next = NULL;
00477       /* Adjust length */
00478       frag->ip->length = intel16 ((WORD)(data_end + in_GetHdrLen(ip)));
00479     }
00480 #endif
00481   }
00482
00483   if (hole)
00484   {
00485     hole->start = data_length;
00486     hole->end   = MAX_FRAG_SIZE;
00487     hole->next  = NULL;
00488
00489     MSG (("hole %lX, start %lu, end %lu\n",
00490           (DWORD)hole, hole->start, hole->end));
00491   }
00492   return (TRUE);
00493 }
00494
00495
00496 /*
00497  * Allocate a bucket for doing fragment reassembly
00498  */
00499 static in_Header *alloc_frag_buffer (const in_Header *ip, int j)
00500 {
00501   BYTE *p;
00502
00503   if (!frag_buckets[j].ip)
00504   {
00505     p = (BYTE*) calloc (BUCKET_SIZE + _pkt_ip_ofs, 1);
00506     if (!p)
00507        return (NULL);
00508
00509     frag_buckets[j].ip = (HugeIP*) (p + _pkt_ip_ofs);
00510     ((HugeIP*)p)->marker = BUCKET_MARKER;
00511   }
00512   else
00513   {
00514     p = (BYTE*)frag_buckets[j].ip - _pkt_ip_ofs;
00515     if (((HugeIP*)p)->marker != BUCKET_MARKER)
00516     {
00517       TCP_CONSOLE_MSG (0, ("frag_buckets[%d] destroyed\n!", j));
00518       free (p);
00519       frag_buckets[j].ip   = NULL;
00520       frag_buckets[j].used = FALSE;
00521       return (NULL);
00522     }
00523   }
00524   MSG (("alloc_frag() = %lX\n", (DWORD)frag_buckets[j].ip));
00525
00526   frag_buckets[j].used     = TRUE;
00527   frag_buckets[j].got_ofs0 = FALSE;
00528
00529   if (!_pktserial)
00530      memcpy (p, MAC_HDR(ip), _pkt_ip_ofs);  /* remember MAC-head */
00531   return (&frag_buckets[j].ip->hdr);
00532 }
00533
00534 /*
00535  * Free/release the reassembled IP-packet.
00536  * Note: we don't free it to the heap.
00537  */
00538 int ip4_free_fragment (const in_Header *ip)
00539 {
00540   unsigned i, j;
00541
00542   for (j = 0; j < MAX_IP_FRAGS; j++)
00543       if (ip == &frag_buckets[j].ip->hdr && frag_buckets[j].used)
00544       {
00545         MSG (("ip4_free_fragment(%lX), bucket=%d, active=%d\n",
00546               (DWORD)ip, j, frag_buckets[j].active));
00547
00548         frag_buckets[j].used   = FALSE;
00549         frag_buckets[j].active = 0;
00550         for (i = 0; i < MAX_FRAGMENTS; i++)
00551             frag_list[j][i].used = FALSE;
00552         return (1);
00553       }
00554   return (0);
00555 }
00556
00557 /*
00558  * Check if any fragment chains has timed-out
00559  */
00560 void chk_timeout_frags (void)
00561 {
00562   unsigned i, j;
00563
00564   for (j = 0; j < MAX_IP_FRAGS; j++)
00565   {
00566     for (i = 0; i < MAX_FRAGMENTS; i++)
00567     {
00568       in_Header ip;
00569
00570       if (!frag_buckets[j].active ||
00571           !frag_list[j][i].used   ||
00572           !chk_timeout(frag_list[j][i].timer))
00573          continue;
00574
00575       memset (&ip, 0, sizeof(ip));
00576       ip.identification = frag_buckets[j].key.ident;
00577       ip.proto          = frag_buckets[j].key.proto;
00578       ip.source         = frag_buckets[j].key.source;
00579       ip.destination    = frag_buckets[j].key.destin;
00580
00581       if (frag_buckets[j].got_ofs0)
00582       {
00583         if (_pktserial)    /* send an ICMP_TIMXCEED (code 1) */
00584              icmp_send_timexceed (&ip, NULL);
00585         else icmp_send_timexceed (&ip, (const void*)&frag_buckets[j].mac_src);
00586       }
00587
00588       STAT (ip4stats.ips_fragtimeout++);
00589
00590       MSG (("chk_timeout_frags(), bucket %u, slot %d, id %04X\n",
00591             j, i, intel16(ip.identification)));
00592
00593       if (ip4_free_fragment(&frag_buckets[j].ip->hdr))
00594          return;
00595     }
00596   }
00597 }
00598
00599 /*----------------------------------------------------------------------*/
00600
00601 #if defined(TEST_PROG)  /* a small test program (djgpp/Watcom/HighC) */
00602 #undef FP_OFF
00603 #undef enable
00604 #undef disable
00605
00606 #include <unistd.h>
00607
00608 #include "sock_ini.h"
00609 #include "loopback.h"
00610 #include "pcarp.h"
00611 #include "getopt.h"
00612
00613 static DWORD to_host   = 0;
00614 static WORD  frag_ofs  = 0;
00615 static int   max_frags = 5;
00616 static int   frag_size = 1000;
00617 static int   rand_frag = 0;
00618 static int   rev_order = 0;
00619 static int   time_frag = 0;
00620
00621 void usage (char *argv0)
00622 {
00623   printf ("%s [-n num] [-s size] [-h ip] [-r] [-R] [-t]\n"
00624           "Send fragmented ICMP Echo Request (ping)\n\n"
00625           "options:\n"
00626           "  -n  number of fragments to send     (default %d)\n"
00627           "  -s  size of each fragment           (default %d)\n"
00628           "  -h  specify destination IP          (default 127.0.0.1)\n"
00629           "  -r  send fragments in random order  (default %s)\n"
00630           "  -R  send fragments in reverse order (default %s)\n"
00631           "  -t  simulate fragment timeout       (default %s)\n",
00632           argv0, max_frags, frag_size,
00633           rand_frag ? "yes" : "no",
00634           rev_order ? "yes" : "no",
00635           time_frag ? "yes" : "no");
00636   exit (0);
00637 }
00638
00639 BYTE *init_frag (int argc, char **argv)
00640 {
00641   int   i, ch;
00642   BYTE *data;
00643
00644   while ((ch = getopt(argc, argv, "h:n:s:rRt?")) != EOF)
00645      switch (ch)
00646      {
00647        case 'h': to_host = inet_addr (optarg);
00648                  if (to_host == INADDR_NONE)
00649                  {
00650                    printf ("Illegal IP-address\n");
00651                    exit (-1);
00652                  }
00653                  break;
00654        case 'n': max_frags = atoi (optarg);
00655                  break;
00656        case 's': frag_size = atoi (optarg) / 8;  /* multiples of 8 */
00657                  frag_size <<= 3;
00658                  break;
00659        case 'r': rand_frag = 1;
00660                  break;
00661        case 'R': rev_order = 1;
00662                  break;
00663        case 't': time_frag = 1;
00664                  break;
00665        case '?':
00666        default : usage (argv[0]);
00667      }
00668
00669   if (max_frags < 1 || max_frags > FD_SETSIZE)
00670   {
00671     printf ("# of fragments is 1 - %d\n", FD_SETSIZE);
00672     exit (-1);
00673   }
00674
00675   if (frag_size < 8 || frag_size > MAX_IP4_DATA)
00676   {
00677     printf ("Fragsize range is 8 - %ld\n", MAX_IP4_DATA);
00678     exit (-1);
00679   }
00680
00681   if (frag_size * max_frags > USHRT_MAX)
00682   {
00683     printf ("Total fragsize > 64kB!\n");
00684     exit (-1);
00685   }
00686
00687   data = calloc (frag_size * max_frags, 1);
00688   if (!data)
00689   {
00690     printf ("no memory\n");
00691     exit (-1);
00692   }
00693
00694   for (i = 0; i < max_frags; i++)
00695      memset (data + i*frag_size, 'a'+i, frag_size);
00696
00697   loopback_mode |= LBACK_MODE_ENABLE;
00698   dbug_init();
00699   sock_init();
00700
00701   if (!to_host)
00702      to_host = htonl (INADDR_LOOPBACK);
00703   return (data);
00704 }
00705
00706 /*----------------------------------------------------------------------*/
00707
00708 int rand_packet (fd_set *fd, int max)
00709 {
00710   int count = 0;
00711
00712   while (1)
00713   {
00714     int i = Random (0, max);
00715     if (i < max && !FD_ISSET(i,fd))
00716     {
00717       FD_SET (i, fd);
00718       return (i);
00719     }
00720     if (++count == 10*max)
00721        return (-1);
00722   }
00723 }
00724
00725 /*----------------------------------------------------------------------*/
00726
00727 int main (int argc, char **argv)
00728 {
00729   fd_set      is_sent;
00730   int         i;
00731   eth_address eth;
00732   in_Header  *ip;
00733   ICMP_PKT   *icmp;
00734   WORD        frag_flag;
00735   BYTE       *data = init_frag (argc, argv);
00736
00737   if (!_arp_resolve (ntohl(to_host), &eth))
00738   {
00739     printf ("ARP failed\n");
00740     return (-1);
00741   }
00742
00743   ip   = (in_Header*) _eth_formatpacket (&eth, IP4_TYPE);
00744   icmp = (ICMP_PKT*) data;
00745
00746   ip->hdrlen         = sizeof(*ip)/4;
00747   ip->ver            = 4;
00748   ip->tos            = _default_tos;
00749   ip->identification = _get_ip4_id();
00750   ip->ttl            = 15;           /* max 15sec reassembly time */
00751   ip->proto          = ICMP_PROTO;
00752
00753   icmp->echo.type       = ICMP_ECHO;
00754   icmp->echo.code       = 0;
00755   icmp->echo.identifier = 0;
00756   icmp->echo.index      = 1;
00757   icmp->echo.sequence   = set_timeout (1);  /* "random" id */
00758   icmp->echo.checksum   = 0;
00759   icmp->echo.checksum   = ~CHECKSUM (icmp, max_frags*frag_size);
00760
00761   FD_ZERO (&is_sent);
00762
00763 #if 0  /* test random generation */
00764   if (rand_frag)
00765      for (i = 0; i < max_frags; i++)
00766      {
00767        int j = rand_packet (&is_sent, max_frags);
00768        printf ("index %d\n", j);
00769      }
00770   exit (0);
00771 #endif
00772
00773   for (i = 0; i < max_frags; i++)
00774   {
00775     int j;
00776
00777     if (rand_frag)
00778     {
00779       j = rand_packet (&is_sent, max_frags);
00780       if (j < 0)
00781          break;
00782     }
00783     if (rev_order)
00784     {
00785       j = max_frags - i - 1;
00786       frag_flag = (j > 0) ? IP_MF : 0;
00787     }
00788     else
00789     {
00790       j = i;
00791       frag_flag = (j < max_frags) ? IP_MF : 0;
00792     }
00793
00794     frag_ofs = (j * frag_size);
00795     memcpy ((BYTE*)(ip+1), data+frag_ofs, frag_size);
00796
00797     /* The loopback device swaps src/dest IP; hence we must set them
00798      * on each iteration of the loop
00799      */
00800     ip->source      = intel (my_ip_addr);
00801     ip->destination = to_host;
00802     ip->frag_ofs    = intel16 (frag_ofs/8 | frag_flag);
00803     ip->length      = intel16 (frag_size + sizeof(*ip));
00804     ip->checksum    = 0;
00805     ip->checksum    = ~CHECKSUM (ip, sizeof(*ip));
00806
00807     _eth_send (frag_size+sizeof(*ip), NULL, __FILE__, __LINE__);
00808
00809     STAT (ip4stats.ips_ofragments++);
00810     tcp_tick (NULL);
00811   }
00812
00813   puts ("tcp_tick()");
00814
00815   /* poll the IP-queue, reassemble fragments and
00816    * dump reassembled IP/ICMP packet to debugger (look in wattcp.dbg)
00817    */
00818   if (to_host != htonl (INADDR_LOOPBACK))
00819   {
00820 #if defined(__HIGHC__) || defined(__WATCOMC__)
00821     sleep (1);
00822 #else
00823     usleep (1000000 + 100*max_frags*frag_size); /* wait for reply */
00824 #endif
00825   }
00826
00827   tcp_tick (NULL);
00828   return (0);
00829 }
00830 #endif  /* TEST_PROG */
00831 #endif  /* USE_FRAGMENTS */
00832
Generated on Wed Jan 25 15:42:35 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/IP4_FRAG.H Source File

SRC/IP4_FRAG.H

Go to the documentation of this file.
00001
00003 #ifndef _w32_IP4_FRAG_H
00004 #define _w32_IP4_FRAG_H
00005
00006 extern int _ip4_frag_reasm;
00007
00008 extern int  ip4_defragment    (const in_Header **ip, DWORD ofs, WORD flags);
00009 extern int  ip4_free_fragment (const in_Header *ip);
00010 extern void chk_timeout_frags (void);
00011
00012 #endif
00013
Generated on Wed Jan 25 15:42:35 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/IP4_IN.C Source File

SRC/IP4_IN.C

Go to the documentation of this file.
00001
00011 #include <stdio.h>
00012 #include <stdlib.h>
00013
00014 #include "wattcp.h"
00015 #include "misc.h"
00016 #include "chksum.h"
00017 #include "rs232.h"
00018 #include "pcconfig.h"
00019 #include "pcmulti.h"
00020 #include "pcdbug.h"
00021 #include "pcsed.h"
00022 #include "pctcp.h"
00023 #include "pcstat.h"
00024 #include "pcicmp.h"
00025 #include "ip4_frag.h"
00026 #include "ip4_in.h"
00027
00028 /*
00029  * _ip4_handler - do a simple check on IPv4 header.
00030  *              - check the fragment chain queue for a match.
00031  *              - Demultiplex packet to correct protocol handler.
00032  */
00033 int _ip4_handler (const in_Header *ip, BOOL broadcast)
00034 {
00035 #if defined(USE_FRAGMENTS)
00036   const in_Header *in_ip = ip;
00037 #endif
00038   sock_type *s = NULL;
00039   DWORD  frag_ofs;
00040   WORD   frag_flg;
00041   BOOL   delivered = TRUE;   /* assume yes */
00042
00043   SIO_TRACE (("_ip4_handler"));
00044
00045   if (block_ip || !_chk_ip4_header(ip))
00046      return (0);
00047
00048   frag_ofs = intel16 (ip->frag_ofs);
00049   frag_flg = (WORD) (frag_ofs & ~IP_OFFMASK);
00050   frag_ofs = (frag_ofs & IP_OFFMASK) << 3;    /* 0 <= frag_ofs <= 65536-8 */
00051
00052 #if defined(USE_FRAGMENTS)
00053   if (!ip4_defragment(&ip,frag_ofs,frag_flg)) /* not defragged yet */
00054      return (0);
00055 #else
00056   ARGSUSED (frag_flg);
00057   if (frag_ofs)
00058      return (0);
00059 #endif
00060
00066 #if defined(USE_BSD_API)
00067   /*
00068    * Match 'ip' against all SOCK_RAW sockets before doing normal
00069    * protocol multiplexing below.
00070    *
00071    * Note: _bsd_socket_hook does nothing unless we have allocated at least
00072    *       one SOCK_RAW socket.
00073    *
00074    * Should we return if the hook consumed packet (return non-NULL) ?
00075    */
00076   if (_bsd_socket_hook)
00077     (*_bsd_socket_hook) (BSO_IP4_RAW, ip);
00078 #endif
00079
00080
00081   switch (ip->proto)
00082   {
00083     case TCP_PROTO:
00084 #if !defined(USE_UDP_ONLY)
00085          s = (sock_type*) _tcp_handler (ip, broadcast);
00086 #endif
00087          break;
00088
00089     case UDP_PROTO:
00090          s = (sock_type*) _udp_handler (ip, broadcast);
00091          break;
00092
00093     case ICMP_PROTO:
00094          icmp_handler (ip, broadcast);
00095          break;
00096
00097     case IGMP_PROTO:
00098 #if defined(USE_MULTICAST)
00099          igmp_handler (ip, broadcast);
00100 #endif
00101          break;
00102
00103     case IPCOMP_PROTO:
00106     default:
00107          DEBUG_RX (NULL, ip);
00108          if (!broadcast)
00109          {
00110            if (_ip4_is_local_addr(intel(ip->destination)))
00111               icmp_send_unreach (ip, ICMP_UNREACH_PROTOCOL);
00112            STAT (ip4stats.ips_noproto++);
00113          }
00114          delivered = FALSE;
00115          break;
00116   }
00117
00118 #ifdef NOT_USED
00119   if (s)         /* Check if peer allows IP-fragments */
00120   {
00121     if (intel16(ip->frag_ofs) & IP_DF)
00122          s->tcp.locflags |=  LF_NO_IPFRAGS;
00123     else s->tcp.locflags &= ~LF_NO_IPFRAGMS;
00124   }
00125 #endif
00126
00127 #if defined(USE_FRAGMENTS)
00128   if (ip != in_ip)
00129      ip4_free_fragment (ip);  /* free this fragment chain */
00130 #endif
00131
00132   if (delivered)
00133      STAT (ip4stats.ips_delivered++);
00134   ARGSUSED (s);
00135   return (1);
00136 }
00137
00138 /*
00139  * Check for correct IP-version, header length and header checksum.
00140  * If failed, discard the packet. ref. RFC1122: section 3.1.2.2
00141  */
00142 int _chk_ip4_header (const in_Header *ip)
00143 {
00144   unsigned hlen = in_GetHdrLen (ip);
00145
00146   if (ip->ver != 4)    /* We only speak IPv4 */
00147   {
00148     DEBUG_RX (NULL, ip);
00149     STAT (ip4stats.ips_badvers++);
00150     return (0);
00151   }
00152   if (hlen < sizeof(*ip))
00153   {
00154     DEBUG_RX (NULL, ip);
00155     STAT (ip4stats.ips_tooshort++);
00156     return (0);
00157   }
00158   if (CHECKSUM(ip,hlen) != 0xFFFF)
00159   {
00160     DEBUG_RX (NULL, ip);
00161     STAT (ip4stats.ips_badsum++);
00162     return (0);
00163   }
00164   return (1);
00165 }
00166
00167 /*
00168  * Return TRUE if ip address is a local address or on the
00169  * loopback network (127.x.x.x). `ip' is on host order.
00170  * If netmask is 255.255.255.255, 'ip' *could* be remote.
00171  */
00172 int _ip4_is_local_addr (DWORD ip)
00173 {
00174   if (sin_mask == 0xFFFFFFFFUL)
00175      return (0);
00176   return _ip4_is_loopback_addr(ip) || _ip4_is_multihome_addr(ip);
00177 }
00178
00179 int _ip4_is_loopback_addr (DWORD ip)
00180 {
00181   return ((ip >> 24) == 127);
00182 }
00183
00184 /*
00185  * Return TRUE if ip address is a legal address for
00186  * a unique host. `ip' is on host order.
00187  */
00188 int _ip4_is_unique_addr (DWORD ip)
00189 {
00190   return (ip && (ip & ~sin_mask) == 0);
00191 }
00192
00193 /*
00194  * Return TRUE if ip address is among our interface addresses
00195  * [my_ip_addr.. (my_ip_addr+multihomes)], `ip' is on host order.
00196  */
00197 int _ip4_is_multihome_addr (DWORD ip)
00198 {
00199   if (!my_ip_addr || ip < my_ip_addr)
00200      return (0);
00201   if (ip - my_ip_addr <= multihomes)
00202      return (1);
00203   return (0);
00204 }
00205
00206 /*
00207  * return TRUE if ip packet is a (directed) broadcast packet.
00208  */
00209 int _ip4_is_ip_brdcast (const in_Header *ip)
00210 {
00211   DWORD dst = intel (ip->destination);
00212   return ((~dst & ~sin_mask) == 0); /* (directed) ip-broadcast */
00213 }
00214
00215 /*
00216  * determines if the given IP addr is Class D (Multicast)
00217  *
00218  * int _ip4_is_multicast (DWORD ip)
00219  * Where:
00220  *    `ip' is on host order.
00221  * Returns:
00222  *    1   if ip is Class D
00223  *    0   if ip is not Class D
00224  *
00225  * Note: class-D is 224.0.0.0 - 239.255.255.255, but
00226  *       range      224.0.0.0 - 224.0.0.255 is reserved for mcast
00227  *                  routing information.
00228  */
00229 int _ip4_is_multicast (DWORD ip)
00230 {
00231   return IN_MULTICAST(ip);
00232 }
00233
Generated on Wed Jan 25 15:42:35 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/IP4_IN.H Source File

SRC/IP4_IN.H

Go to the documentation of this file.
00001
00003 #ifndef _w32_IP4_IN_H
00004 #define _w32_IP4_IN_H
00005
00009 #define IPOPT_EOL       0
00010 #define IPOPT_NOP       1
00011 #define IPOPT_RR        7
00012 #define IPOPT_TS        68
00013 #define IPOPT_SECURITY  130
00014 #define IPOPT_LSRR      131
00015 #define IPOPT_SATID     136
00016 #define IPOPT_SSRR      137
00017 #define IPOPT_RA        148
00022 #ifndef IN_MULTICAST
00023 #define IN_MULTICAST(ip)    ((ip & 0xF0000000UL) == 0xE0000000UL)
00024 #endif
00025
00026 #ifndef IN_EXPERIMENTAL
00027 #define IN_EXPERIMENTAL(ip) ((ip & 0xF0000000UL) == 0xF0000000UL)
00028 #endif
00029
00030 extern int _ip4_handler (const in_Header *ip, BOOL broadcast);
00031 extern int _chk_ip4_header (const in_Header *ip);
00032
00033 extern int _ip4_is_local_addr (DWORD ip);
00034 extern int _ip4_is_unique_addr (DWORD ip);
00035 extern int _ip4_is_multihome_addr (DWORD ip);
00036 extern int _ip4_is_ip_brdcast (const in_Header *ip);
00037 extern int _ip4_is_multicast (DWORD ip);
00038 extern int _ip4_is_loopback_addr (DWORD ip);
00039
00040 #endif
Generated on Wed Jan 25 15:42:35 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/IP4_OUT.C Source File

SRC/IP4_OUT.C

Go to the documentation of this file.
00001
00005 /*  Copyright (c) 1997-2002 Gisle Vanem <giva@bgnett.no>
00006  *
00007  *  Redistribution and use in source and binary forms, with or without
00008  *  modification, are permitted provided that the following conditions
00009  *  are met:
00010  *  1. Redistributions of source code must retain the above copyright
00011  *     notice, this list of conditions and the following disclaimer.
00012  *  2. Redistributions in binary form must reproduce the above copyright
00013  *     notice, this list of conditions and the following disclaimer in the
00014  *     documentation and/or other materials provided with the distribution.
00015  *  3. All advertising materials mentioning features or use of this software
00016  *     must display the following acknowledgement:
00017  *       This product includes software developed by Gisle Vanem
00018  *       Bergen, Norway.
00019  *
00020  *  THIS SOFTWARE IS PROVIDED BY ME (Gisle Vanem) AND CONTRIBUTORS ``AS IS''
00021  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00022  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00023  *  ARE DISCLAIMED.  IN NO EVENT SHALL I OR CONTRIBUTORS BE LIABLE FOR ANY
00024  *  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00025  *  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00026  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00027  *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00028  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00029  *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00030  *
00031  *  Version
00032  *
00033  *  1.0 : Apr 18, 1999 : G. Vanem - created
00034  *  1.1 : Jan 29, 2000 : G. Vanem - added functions for
00035  *                       handling list of IP-fragments.
00036  */
00037
00038 #include <stdio.h>
00039 #include <stdlib.h>
00040 #include <sys/socket.h>
00041
00042 #include "wattcp.h"
00043 #include "misc.h"
00044 #include "chksum.h"
00045 #include "pcdbug.h"
00046 #include "pcsed.h"
00047 #include "pctcp.h"
00048 #include "pcstat.h"
00049 #include "pcicmp.h"
00050 #include "socket.h"
00051
00052 BYTE _default_tos      = 0;      /* Type-Of-Service */
00053 int  _default_ttl      = 254;    /* TTL on outgoing packets */
00054 int  _ip4_id_increment = 1;      /* Some stacks uses 5 */
00055 BOOL _ip4_dont_frag    = FALSE;  /* Don't set DF bit on every packet */
00056
00057 static WORD ip4_id = 0;
00058
00064 WORD _get_ip4_id (void)
00065 {
00066   ip4_id += _ip4_id_increment;
00067   return intel16 (ip4_id);
00068 }
00069
00073 WORD _get_this_ip4_id (void)
00074 {
00075   return intel16 (ip4_id);
00076 }
00077
00085 int _ip4_output (in_Header  *ip,        /* ip-structure to fill in */
00086                  DWORD       src_ip,    /* from address (network order!) */
00087                  DWORD       dst_ip,    /* dest address (network order!) */
00088                  BYTE        protocol,  /* IP-protocol number */
00089                  BYTE        ttl,       /* Time To Live */
00090                  BYTE        tos,       /* Type Of Service, 0 unspecified */
00091                  WORD        ip_id,     /* IP identification, normally 0 */
00092                  int         data_len,  /* length of data after ip header */
00093                  const void *sock,      /* which socket is this */
00094                  const char *file,      /* Debug: from what file */
00095                  unsigned    line)      /*  and line was _ip4_output called */
00096 {
00097   int len = sizeof(*ip) + data_len;
00098
00099  /*
00100   * Note: the 'ip->frag_ofs' field isn't normally set here (it's
00101   *       cleared in eth_formatpacket() causing IP_DF bit to off).
00102   *       If sending fragments it's set in _ip4_send_fragments() below.
00103   */
00104
00105   if (src_ip == 0)
00106       src_ip = intel (my_ip_addr);
00107
00108   if (_ip4_dont_frag)
00109      ip->frag_ofs |= intel16 (IP_DF);
00110
00111   ip->ver            = 4;
00112   ip->hdrlen         = sizeof(*ip) / 4;
00113   ip->length         = intel16 (len);
00114   ip->tos            = tos & IP_TOSMASK;
00115   ip->ttl            = ttl   ? ttl   : _default_ttl;
00116   ip->identification = ip_id ? ip_id : _get_ip4_id();
00117   ip->proto          = protocol;
00118   ip->source         = src_ip;
00119   ip->destination    = dst_ip;
00120   ip->checksum       = 0;
00121   ip->checksum       = ~CHECKSUM (ip, sizeof(*ip));
00122
00123   return _eth_send (len, sock, file, line);
00124 }
00125
00126 #if defined(USE_FRAGMENTS)
00127 /*
00128  * Note: host is on network order.
00129  * No IP options supported here.
00130  */
00131 static __inline in_Header *make_ip_pkt (DWORD host, BOOL first, char **data)
00132 {
00133   static eth_address dest;
00134   in_Header *ip;
00135
00136   if (first && !_arp_resolve(intel(host),&dest))
00137   {
00138     if (debug_on)
00139        outsnl (_LANG("make_ip_pkt(): ARP failed"));
00140     SOCK_DEBUGF ((", EHOSTUNREACH"));
00141     SOCK_ERRNO (EHOSTUNREACH);
00142     return (NULL);
00143   }
00144
00145   ip = (in_Header*) _eth_formatpacket (&dest, IP4_TYPE);
00146   *data = (char*) (ip+1);
00147   return (ip);
00148 }
00149
00150 /*
00151  * \todo Handle IP/TCP options.
00152  */
00153 static in_Header *make_tcp_pkt (const _tcp_Socket *s,
00154                                 BOOL first, char **data)
00155 {
00156   in_Header *ip = (in_Header*) _eth_formatpacket (&s->his_ethaddr, IP4_TYPE);
00157
00158   if (first)
00159   {
00160     tcp_Header      *tcp = (tcp_Header*) (ip+1);
00161     tcp_PseudoHeader ph;
00162     WORD tcp_len = sizeof(*tcp);
00163
00164     tcp->srcPort  = intel16 (s->myport);
00165     tcp->dstPort  = intel16 (s->hisport);
00166     tcp->seqnum   = intel (s->send_next + s->send_una);
00167     tcp->acknum   = intel (s->recv_next);
00168     tcp->window   = intel16 (s->max_rx_data - s->rx_datalen);
00169     tcp->flags    = (BYTE) s->flags;
00170     tcp->unused   = 0;
00171     tcp->checksum = 0;
00172     tcp->urgent   = 0;
00173     tcp->offset   = tcp_len / 4;
00174
00175     memset (&ph, 0, sizeof(ph));
00176     ph.src      = intel (s->myaddr);
00177     ph.dst      = intel (s->hisaddr);
00178     ph.protocol = TCP_PROTO;
00179     ph.length   = intel16 (tcp_len);
00180     ph.checksum = CHECKSUM (tcp, tcp_len);
00181     tcp->checksum = ~CHECKSUM (&ph, sizeof(ph));
00182     *data = (char*)tcp + sizeof(*tcp);
00183   }
00184   else
00185     *data = (char*)(ip+1);
00186
00187   return (ip);
00188 }
00189
00190 /*
00191  * Note: We assume 's->his_ethaddr' is filled by udp_open() or udp_demux().
00192  *       I.e. socket is active and not a broadcast socket.
00193  */
00194 static __inline in_Header *make_udp_pkt (const _udp_Socket *s, BOOL first,
00195                                          unsigned len, char **data)
00196 {
00197   in_Header *ip = (in_Header*) _eth_formatpacket (&s->his_ethaddr, IP4_TYPE);
00198
00199   if (first)
00200   {
00201     udp_Header      *udp = (udp_Header*) (ip+1);
00202     tcp_PseudoHeader ph;
00203
00204     udp->srcPort  = intel16 (s->myport);
00205     udp->dstPort  = intel16 (s->hisport);
00206     udp->checksum = 0;
00207     udp->length   = intel16 (sizeof(*udp) + len);
00208     memset (&ph, 0, sizeof(ph));
00209     ph.src = intel (s->myaddr);
00210     ph.dst = intel (s->hisaddr);
00211
00212     if (s->sockmode & SOCK_MODE_UDPCHK)
00213     {
00214       ph.protocol = UDP_PROTO;
00215       ph.length   = udp->length;
00216       ph.checksum = CHECKSUM (udp, sizeof(*udp)) + CHECKSUM (*data, len);
00217       udp->checksum = ~CHECKSUM (&ph, sizeof(ph));
00218     }
00219     *data = (char*)udp + sizeof(*udp);
00220   }
00221   else
00222     *data = (char*)(ip+1);
00223
00224   return (ip);
00225 }
00226
00227
00228 /*
00229  * Sends a chain of IPv4 fragments for proto. `buf' is higher-level
00230  * protocol (ICMP/UDP/TCP).
00231  * Note: `dest' is on network order. This function is only called
00232  *       when we're sure fragment are needed; num_frags >= 1.
00233  */
00234 int _ip4_send_fragments (sock_type *s, BYTE proto, DWORD dest,
00235                          const void *buf, unsigned len,
00236                          const char *file, unsigned line)
00237 {
00238   int  i, num_frags, rc = 0;
00239   int  frag_size, frag_ofs;
00240   WORD ip_id;
00241   WORD ip_max = _mtu - sizeof(in_Header);
00242
00243   num_frags = len / ip_max;
00244
00245   WATT_ASSERT (num_frags >= 1);
00246
00247   if (len % ip_max)
00248      num_frags++;
00249
00250   /* Increment IP-identifier. Use same value for all fragments
00251    */
00252   ip_id = _get_ip4_id();
00253
00256   for (frag_ofs = i = 0; i < num_frags; i++)
00257   {
00258     in_Header *ip   = NULL;
00259     char      *data = (char*) buf;
00260
00261     switch (proto)
00262     {
00263 #if 0
00264       case IP4_TYPE:       /* raw IP type (from ip4_transmit) */
00265            proto = ((in_Header*)buf)->proto;
00266            /* fall through */
00267 #endif
00268       case ICMP_PROTO:
00269            ip = make_ip_pkt (dest, frag_ofs == 0, &data);
00270            if (!ip)
00271               return (-1);
00272            break;
00273
00274       case UDP_PROTO:
00275            ip = make_udp_pkt (&s->udp, frag_ofs == 0, len, &data);
00276            break;
00277
00278       case TCP_PROTO:
00279            if (s->tcp.state != tcp_StateESTAB)
00280               return (0);
00281            ip = make_tcp_pkt (&s->tcp, frag_ofs == 0, &data);
00282            break;
00283
00284       default:
00285            TCP_CONSOLE_MSG (0, ("%s (%d): Illegal protocol %04X\n",
00286                             __FILE__, __LINE__, proto));
00287            return (0);
00288     }
00289
00290     if (i == num_frags-1)    /* last fragment */
00291     {
00292       frag_size    = len;
00293       ip->frag_ofs = intel16 (frag_ofs/8);
00294    /* memset (data+frag_size-8, 0, len); */  /* padding */
00295     }
00296     else
00297     {
00298       frag_size    = ip_max;
00299       ip->frag_ofs = intel16 (frag_ofs/8 | IP_MF);
00300     }
00301
00302     memcpy (data, (const char*)buf + frag_ofs, frag_size);
00303
00304     if (_ip4_output (ip, 0, dest, proto, 0, 0, ip_id, frag_size,
00305                      s, file, line) <= 0)
00306     {
00307       SOCK_DEBUGF ((", ENETDOWN"));
00308       SOCK_ERRNO (ENETDOWN);
00309       rc = -1;
00310       break;
00311     }
00312     STAT (ip4stats.ips_ofragments++);
00313
00314     frag_ofs += frag_size;
00315     len      -= frag_size;
00316     rc       += frag_size;
00317   }
00318
00319   tcp_tick (NULL);  /* !! for viewing loopback trace */
00320   return (rc);
00321 }
00322 #endif /* USE_FRAGMENTS */
00323
Generated on Wed Jan 25 15:42:35 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/IP4_OUT.H Source File

SRC/IP4_OUT.H

Go to the documentation of this file.
00001
00003 #ifndef _w32_IP_OUT_H
00004 #define _w32_IP_OUT_H
00005
00006 extern BOOL _ip4_dont_frag;
00007 extern int  _ip4_id_increment;
00008 extern int  _default_ttl;
00009 extern BYTE _default_tos;
00011 extern WORD _get_ip4_id (void);
00012 extern WORD _get_this_ip4_id (void);
00013
00014 extern int _ip4_output (in_Header *ip, DWORD src_ip, DWORD dst_ip,
00015                         BYTE protocol, BYTE ttl, BYTE tos, WORD ip_id,
00016                         int data_len, const void *sock,
00017                         const char *file, unsigned line);
00018
00019 #define IP4_OUTPUT(ip, src, dst, proto, ttl, tos, ip_id, data_len, sock) \
00020        _ip4_output(ip, src, dst, proto, ttl, tos, ip_id, data_len, sock, \
00021                    __FILE__, __LINE__)
00022
00023
00024 #if defined(USE_FRAGMENTS)
00025   int _ip4_send_fragments (sock_type *sk, BYTE proto, DWORD dest,
00026                            const void *buf, unsigned len, const char *file,
00027                            unsigned line);
00028
00029   #define _IP4_SEND_FRAGMENTS(sk, proto, dest, buf, len) \
00030           _ip4_send_fragments(sk, proto, dest, buf, len, __FILE__, __LINE__)
00031 #endif
00032
00033 #endif
Generated on Wed Jan 25 15:42:35 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/IP6_IN.C Source File

SRC/IP6_IN.C

Go to the documentation of this file.
00001
00005 /*
00006  *  Copyright (c) 1997-2002 Gisle Vanem <giva@bgnett.no>
00007  *
00008  *  Redistribution and use in source and binary forms, with or without
00009  *  modification, are permitted provided that the following conditions
00010  *  are met:
00011  *  1. Redistributions of source code must retain the above copyright
00012  *     notice, this list of conditions and the following disclaimer.
00013  *  2. Redistributions in binary form must reproduce the above copyright
00014  *     notice, this list of conditions and the following disclaimer in the
00015  *     documentation and/or other materials provided with the distribution.
00016  *  3. All advertising materials mentioning features or use of this software
00017  *     must display the following acknowledgement:
00018  *       This product includes software developed by Gisle Vanem
00019  *       Bergen, Norway.
00020  *
00021  *  THIS SOFTWARE IS PROVIDED BY ME (Gisle Vanem) AND CONTRIBUTORS ``AS IS''
00022  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00023  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00024  *  ARE DISCLAIMED.  IN NO EVENT SHALL I OR CONTRIBUTORS BE LIABLE FOR ANY
00025  *  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00026  *  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00027  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00028  *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00029  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00030  *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00031  *
00032  *  Version
00033  *
00034  *  0.5 : Jul 29, 2002 : G. Vanem - created
00035  *
00036  */
00037
00038 #include <stdio.h>
00039 #include <stdlib.h>
00040 #include <arpa/inet.h>
00041
00042 #include "wattcp.h"
00043 #include "misc.h"
00044 #include "chksum.h"
00045 #include "rs232.h"
00046 #include "strings.h"
00047 #include "language.h"
00048 #include "sock_ini.h"
00049 #include "split.h"
00050 #include "pctcp.h"
00051 #include "pcsed.h"
00052 #include "pcstat.h"
00053 #include "pcdbug.h"
00054 #include "pcpkt.h"
00055 #include "pcconfig.h"
00056 #include "pcicmp6.h"
00057 #include "bsddbug.h"
00058 #include "netaddr.h"
00059 #include "get_xby.h"
00060 #include "ip6_out.h"
00061 #include "ip6_in.h"
00062
00063 /* \if USE_IPV6 */
00064 #if defined(USE_IPV6)
00065
00066 /*
00067  * _ip6_handler - do a simple check on IPv6 header
00068  *              - Demultiplex packet to correct protocol handler
00069  */
00070 int _ip6_handler (const in6_Header *ip, BOOL broadcast)
00071 {
00072   const struct pkt_split *ps;
00073
00074   SIO_TRACE (("_ip6_handler"));
00075
00076   if (block_ip)
00077      return (0);
00078
00079   if (ip->ver != 6)
00080   {
00081     DEBUG_RX (NULL, ip);
00082     STAT (ip6stats.ip6s_badvers++);
00083     return (0);
00084   }
00085
00086   /* Match 'ip' against all SOCK_RAW sockets before doing normal
00087    * protocol multiplexing below.
00088    */
00089   if (_bsd_socket_hook)
00090     (*_bsd_socket_hook) (BSO_IP6_RAW, ip);
00091
00092   for (ps = pkt_get_split_in(); ps->data; ps++)
00093       switch (ps->type)
00094       {
00095         case TYPE_TOKEN_HEAD:
00096         case TYPE_FDDI_HEAD:
00097         case TYPE_ETHER_HEAD:
00098         case TYPE_IP6:
00099              break;
00100
00101         case TYPE_TCP_HEAD:
00102              _tcp_handler ((const in_Header*)ip, broadcast);
00103              break;
00104
00105         case TYPE_UDP_HEAD:
00106              _udp_handler ((const in_Header*)ip, broadcast);
00107              break;
00108
00109         case TYPE_IP6_ICMP:
00110              icmp6_handler (ip);
00111              break;
00112
00113         case TYPE_IP6_NONE:
00114              break;
00115
00116         case TYPE_IP6_UNSUPP:
00117 #if defined(USE_DEBUG)
00118              dbug_printf ("Received unsupported IPv6 message, next-hdr %d,"
00119                           " broadcast %d\n", ip->next_hdr, broadcast);
00120 #endif
00121              break;
00122
00123         default:
00124              DEBUG_RX (NULL, ip);
00125              if ((ps->type >= TYPE_IP6_HOP && ps->type <= TYPE_IP6_DEST) &&
00126                  !broadcast)
00127              {
00128                if (IN6_IS_ADDR_LINKLOCAL(ip->destination))
00129                   icmp6_unreach (ip, 2);  /* protocol unreachable */
00130                STAT (ip6stats.ip6s_cantforward++);
00131              }
00132              break;
00133       }
00134
00135 #if 0
00136   if (ip->next_hdr != IP6_NEXT_ICMP)  /* !! bug hunt */
00137      dbug_printf ("IP6 packet, next-hdr %d, brdcast %d\n",
00138                   ip->next_hdr, broadcast);
00139 #endif
00140
00141   STAT (ip6stats.ip6s_delivered++);
00142   return (1);
00143 }
00144
00145 /*
00146  * Return TRUE if IPv6 address is a local address or on the
00147  * loopback network (::1).
00148  */
00149 int _ip6_is_local_addr (const void *ip)
00150 {
00151   if (!memcmp(&in6addr_my_ip,ip,sizeof(in6addr_my_ip)) ||
00152       !memcmp(&in6addr_loopback,ip,sizeof(in6addr_loopback)))
00153     return (1);
00154   return (0);
00155 }
00156
00157 #ifdef NOT_USED  /* use IN6_xx macros in <netinet/in.h> instead */
00158 /*
00159  * Return true if address has a IPv4 prefix (0:0:0:0:0:FFFF)
00160  */
00161 static WORD v4_prefix[6] = { 0,0,0,0,0,0xFFFF };
00162
00163 int _ip6_is_addr_v4mapped (const void *ip)
00164 {
00165   if (!memcmp(ip,&v4_prefix,sizeof(v4_prefix)))
00166      return (1);
00167   return (0);
00168 }
00169
00170 int _ip6_is_addr_loopback (const void *ip)
00171 {
00172   if (!memcmp(ip,&in6addr_loopback,sizeof(in6addr_loopback)))
00173      return (1);
00174   return (0);
00175 }
00176 #endif  /* NOT_USED */
00177
00178
00179 static void (*prev_hook) (const char*, const char*) = NULL;
00180
00181 static void set_my_ip6 (const char *value)
00182 {
00183   if (!stricmp(value,"dhcp") || !stricmp(value,"dhcp6"))
00184      _dhcp6_on = 1;
00185   else if (!inet_pton(AF_INET6, value, (void*)&in6addr_my_ip))
00186      printf (_LANG("\"IP6.MY_IP\": Invalid IPv6 address \"%s\"\n"), value);
00187 }
00188
00189 static void ip6_config (const char *name, const char *value)
00190 {
00191   static const struct config_table ip6_cfg[] = {
00192             { "HOSTS",        ARG_FUNC,  (void*)ReadHosts6File      },
00193             { "MY_IP",        ARG_FUNC,  (void*)set_my_ip6          },
00194             { "6TO4_GATEWAY", ARG_ATOIP, (void*)&icmp6_6to4_gateway },
00195             { "DEF_TTL",      ARG_ATOI,  (void*)&_default6_ttl      },
00196             { NULL,           0,         NULL                       }
00197           };
00198   if (!parse_config_table(&ip6_cfg[0], "IP6.", name, value) && prev_hook)
00199      (*prev_hook) (name, value);
00200 }
00201
00202 int _ip6_init (void)
00203 {
00204   prev_hook = usr_init;
00205   usr_init  = ip6_config;
00206   return (1);
00207 }
00208
00209 /*
00210  * Sets default (preferred link-local) IPv6 address to
00211  * FE80::201:80FF:FE <last 3 bytes of MAC-address>
00212  */
00213 static void set_default_ip (void)
00214 {
00215   BYTE *a = (BYTE*) &in6addr_my_ip.s6_addr[0];
00216
00217   memset (a, 0, sizeof(in6addr_my_ip));
00218   a[0]  = 0xFE;
00219   a[1]  = 0x80;
00220   a[8]  = 0x20;
00221   a[9]  = 0x01;
00222   a[10] = 0x80;
00223   a[11] = 0xFF;
00224   a[12] = 0xFE;
00225   a[13] = _eth_real_addr[3];
00226   a[14] = _eth_real_addr[4];
00227   a[15] = _eth_real_addr[5];
00228 }
00229
00230 /*
00231  * Called from socket.c only (I.e. IPv6 requires BSD-sockets. Core
00232  * API cannot be used for IPv6).
00233  */
00234 int _ip6_pkt_init (void)
00235 {
00236   if (!memcmp(&in6addr_my_ip,&in6addr_any,sizeof(in6addr_my_ip)))
00237      set_default_ip();
00238
00239   if (_pktserial)  /* IPv6 cannot work on any known serial drivers */
00240      return (0);
00241
00242   /* Ignore result, not much we can do if it fails anyway.
00243    */
00244   if (_pkt_rxmode < RXMODE_MULTICAST2) /* if not already set */
00245      return pkt_set_rcv_mode (RXMODE_MULTICAST2);
00246   return (1);     /* promiscous mode is okay */
00247 }
00248
00249 /*
00250  * Called from sock_ini.c after config read
00251  */
00252 void _ip6_post_init (void)
00253 {
00254   if (icmp6_6to4_gateway)
00255      icmp6_add_gateway4();
00256 }
00257 #endif  /* USE_IPV6 */
00258 /* \endif */
Generated on Wed Jan 25 15:42:35 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/IP6_IN.H Source File

SRC/IP6_IN.H

Go to the documentation of this file.
00001
00003 #ifndef _w32_IP6_IN_H
00004 #define _w32_IP6_IN_H
00005
00006 /*
00007  * `struct in6_Header::next_hdr' field.
00008  */
00009 #define IP6_NEXT_HOP       0       /* Hop-by-hop option header */
00010 #define IP6_NEXT_TCP       6       /* TCP segment */
00011 #define IP6_NEXT_UDP       17      /* UDP message */
00012 #define IP6_NEXT_IPV6      41      /* IPv6 in IPv6 */
00013 #define IP6_NEXT_ROUTING   43      /* Routing header */
00014 #define IP6_NEXT_FRAGMENT  44      /* Fragmentation/reassembly header */
00015 #define IP6_NEXT_ESP       50      /* Encapsulating security payload */
00016 #define IP6_NEXT_AUTH      51      /* Authentication header */
00017 #define IP6_NEXT_ICMP      58      /* ICMP for IPv6 */
00018 #define IP6_NEXT_NONE      59      /* No next header */
00019 #define IP6_NEXT_DEST      60      /* Destination options header */
00020 #define IP6_NEXT_COMP      108     /* Compression options header */
00021
00022 typedef struct ip6_RouteHdr {
00023                BYTE  next_hdr;
00024                BYTE  hdrlen;
00025                BYTE  type;
00026                BYTE  seg_left;
00027              } ip6_RouteHdr;
00028
00029 extern int  _ip6_handler (const in6_Header *ip, BOOL broadcast);
00030 extern int  _ip6_init (void);
00031 extern int  _ip6_pkt_init (void);
00032 extern void _ip6_post_init (void);
00033
00034 extern int _ip6_is_local_addr (const void *ip);
00035
00036 #endif
Generated on Wed Jan 25 15:42:35 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/IP6_OUT.C Source File

SRC/IP6_OUT.C

Go to the documentation of this file.
00001
00005 /*
00006  *  Copyright (c) 1997-2002 Gisle Vanem <giva@bgnett.no>
00007  *
00008  *  Redistribution and use in source and binary forms, with or without
00009  *  modification, are permitted provided that the following conditions
00010  *  are met:
00011  *  1. Redistributions of source code must retain the above copyright
00012  *     notice, this list of conditions and the following disclaimer.
00013  *  2. Redistributions in binary form must reproduce the above copyright
00014  *     notice, this list of conditions and the following disclaimer in the
00015  *     documentation and/or other materials provided with the distribution.
00016  *  3. All advertising materials mentioning features or use of this software
00017  *     must display the following acknowledgement:
00018  *       This product includes software developed by Gisle Vanem
00019  *       Bergen, Norway.
00020  *
00021  *  THIS SOFTWARE IS PROVIDED BY ME (Gisle Vanem) AND CONTRIBUTORS ``AS IS''
00022  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00023  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00024  *  ARE DISCLAIMED.  IN NO EVENT SHALL I OR CONTRIBUTORS BE LIABLE FOR ANY
00025  *  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00026  *  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00027  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00028  *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00029  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00030  *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00031  *
00032  *  Version
00033  *
00034  *  0.5 : Jul 29, 2002 : G. Vanem - created
00035  *
00036  */
00037
00038 #include <stdio.h>
00039 #include <stdlib.h>
00040
00041 #include "wattcp.h"
00042 #include "misc.h"
00043 #include "chksum.h"
00044 #include "pcsed.h"
00045 #include "ip4_out.h"
00046 #include "ip6_out.h"
00047 #include "socket.h"
00048
00049 /* \if USE_IPV6 */
00050 #if defined(USE_IPV6)
00051
00052 struct in6_addr in6addr_my_ip = {{ 0,0,0,0,0,0,0,0,
00053                                    0,0,0,0,0,0,0,0 }};
00054
00055 const struct in6_addr in6addr_loopback = {{ 0,0,0,0,0,0,0,0,
00056                                             0,0,0,0,0,0,0,1 }};
00057 const struct in6_addr in6addr_any      = {{ 0,0,0,0,0,0,0,0,
00058                                             0,0,0,0,0,0,0,0 }};
00059 const struct in6_addr in6addr_all_1    = {{ 0xFF,0xFF,0xFF,0xFF,
00060                                             0xFF,0xFF,0xFF,0xFF,
00061                                             0xFF,0xFF,0xFF,0xFF,
00062                                             0xFF,0xFF,0xFF,0xFF }};
00063 /* all nodes multicast address */
00064 const struct in6_addr in6addr_alln_mc  = {{ 0xFF,2,0,0,0,0,0,0,
00065                                             0,0,0,0,0,0,0,1 }};
00066 /* all routers multicast address */
00067 const struct in6_addr in6addr_allr_mc  = {{ 0xFF,2,0,0,0,0,0,0,
00068                                             0,0,0,0,0,0,0,2 }};
00069
00070 const BYTE in6addr_mapped[12] = { 0,0,0,0, 0,0,0,0, 0,0,0xFF,0xFF };
00071
00072 int  _default6_ttl = 255;    /* TTL on outgoing packets */
00073
00074 int _ip6_output (in6_Header  *ip,       /* IPv6-structure to fill in */
00075                  ip6_address *src_ip,   /* Source address */
00076                  ip6_address *dst_ip,   /* Destination address */
00077                  BYTE         protocol, /* Upper-level protocol */
00078                  unsigned     data_len, /* Length of data after IPv6 header */
00079                  int          hop_lim,  /* Hop limit, 0 means default */
00080                  const void  *sock,     /* Which socket is this */
00081                  const char  *file,     /* Debug: from what file */
00082                  unsigned     line)     /*  and line we where called */
00083 {
00084   unsigned total = data_len + sizeof(*ip);
00085
00086   if (total > _mtu)
00087      return (0);
00088
00089   if (!src_ip)
00090      src_ip = (ip6_address*)&in6addr_my_ip;
00091
00092   ip->pri       = 0;
00093   ip->ver       = 6;
00094   ip->len       = intel16 ((WORD)data_len);
00095   ip->hop_limit = hop_lim ? hop_lim : _default6_ttl;
00096
00097   if (protocol == 0 || data_len == 0)  /* Only an IP6 header */
00098        ip->next_hdr = IP6_NEXT_NONE;
00099   else ip->next_hdr = protocol;
00100
00101   memset (&ip->flow_lbl, 0, sizeof(ip->flow_lbl));
00102
00103   if (&ip->source != src_ip)   /* assumes ptr set by caller */
00104      memcpy (&ip->source, src_ip, sizeof(ip->source));
00105
00106   if (&ip->destination != dst_ip)
00107      memcpy (&ip->destination, dst_ip, sizeof(ip->destination));
00108
00109   if (IN6_IS_ADDR_LOOPBACK(&ip->destination) ||
00110       IN6_IS_ADDR_MULTICAST(&ip->source))
00111      return (0);
00112
00115   return _eth_send (total, sock, file, line);
00116 }
00117 #endif  /* USE_IPV6 */
00118 /* \endif */
Generated on Wed Jan 25 15:42:35 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/IP6_OUT.H Source File

SRC/IP6_OUT.H

Go to the documentation of this file.
00001
00003 #ifndef _w32_IP6_OUTPUT_H
00004 #define _w32_IP6_OUTPUT_H
00005
00006 #ifndef __NETINET_IN_H
00007 #include <netinet/in.h> /* struct in6_addr */
00008 #endif
00009
00010 W32_DATA struct in6_addr in6addr_my_ip;
00011
00012 extern const struct in6_addr in6addr_all_1;
00013 extern const struct in6_addr in6addr_alln_mc;
00014 extern const struct in6_addr in6addr_allr_mc;
00015 extern const BYTE            in6addr_mapped[12];
00016
00017 extern int _default6_ttl;
00018
00019 extern int _ip6_output (in6_Header *ip, ip6_address *src_ip,
00020                         ip6_address *dst_ip, BYTE next_hdr,
00021                         unsigned data_len, int hop_lim, const void *sock,
00022                         const char *file, unsigned line);
00023
00024 #define IP6_OUTPUT(ip, src, dst, next_hdr, data_len, hop_lim, sock) \
00025        _ip6_output(ip, src, dst, next_hdr, data_len, hop_lim, sock, \
00026                    __FILE__, __LINE__)
00027
00028 #endif
00029
Generated on Wed Jan 25 15:42:35 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/LANGUAGE.H Source File

SRC/LANGUAGE.H

Go to the documentation of this file.
00001 #ifndef _w32_LANGUAGE_H
00002 #define _w32_LANGUAGE_H
00003
00014 #if defined(USE_LANGUAGE)
00015   extern void        lang_init  (const char *value);
00016   extern const char *lang_xlate (const char *str);
00017   #define _LANG(str) lang_xlate (str)
00018 #else
00019   #define _LANG(str) str
00020 #endif
00021
00022 /*
00023  * __LANG() must be used for array string constants. This macro is used by
00024  * the `mklang' to generate an entry in the language database.
00025  */
00026 #define __LANG(str)  str
00027
00028 #endif
Generated on Wed Jan 25 15:42:35 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/LANGUAGE.L Source File

SRC/LANGUAGE.L

Go to the documentation of this file.
00001
00008 %{
00009
00010 #include <stdio.h>
00011 #include <stdlib.h>
00012 #include <string.h>
00013 #include <ctype.h>
00014 #include <setjmp.h>
00015
00016 #include "wattcp.h"
00017 #include "strings.h"
00018 #include "sock_ini.h"
00019 #include "misc.h"
00020
00021 #if defined(USE_LANGUAGE)
00022
00023 #if defined(TEST_PROG)
00024   #include <conio.h>
00025   #define INCLINE()       fprintf (stderr, "<line %lu>\n", lang.line++)
00026   #define DEBUG(str,arg)  fprintf (stderr, str, arg)
00027 #else
00028   #define INCLINE()       lang.line++
00029   #define DEBUG(str,arg)  ((void)0)
00030 #endif
00031
00032 #define BUF_SIZE    500
00033
00034 static int   yylex      (void);
00035 static void  AddChar    (int ch);
00036 static void  AddDecimal (const char *buf);
00037 static void  AddHexcode (const char *buf);
00038 static void  AddOctal   (const char *buf);
00039 static void  AddEntry   (void);
00040 static void  Abort      (const char *s1, const char *s2);
00041 static void  error      (const char *err);
00042
00043 static char    buf [BUF_SIZE];
00044 static char   *ptr       = NULL;
00045 static char   *end       = buf+BUF_SIZE;
00046 static int     line_cont = 0;
00047 static DWORD   crc_ref   = 0;
00048 static BOOL    do_ref    = TRUE;
00049 static jmp_buf bail_out;
00050
00051 struct Node {
00052        DWORD        crc;
00053        const  char *string;
00054        struct Node *next;
00055      };
00056
00057 struct Elem {
00058        DWORD crc;
00059        const char *string;
00060      };
00061
00062 static struct Language {
00063        struct Node *list;
00064        struct Elem *array;
00065        char         prefix[4];     /* "en:" etc. */
00066        size_t       entries;
00067        unsigned     line;
00068      } lang = {
00069        NULL, NULL, "en", 0L, 0L
00070      };
00071
00072 /*---------------------------------------------------------------------*/
00073
00074 %}
00075
00088 %option prefix = "_w32_"
00089
00090 %x STRING EO_LINE PREFIX
00091
00092 NL         \r?\n
00093 WS         [\t ]+
00094 HEX        (x[0-9a-fA-F]{1,2})
00095 OCTAL      (0[0-7]{1,3})
00096 DECIMAL    ([0-9]{1,3})
00097 LANG       "de"|"no"|"sv"
00098
00170 %%
00171
00172 <INITIAL>{                             /* get reference string */
00173         {WS}         /* discard */
00174         [#;].*{NL}   INCLINE();
00175         {NL}         INCLINE();
00176         \"           {
00177                        if (!line_cont)
00178                           ptr = buf;
00179                        BEGIN (STRING);
00180                      }
00181         .            {
00182                        unput (yytext[0]);
00183                        BEGIN (PREFIX);
00184                      }
00185 }
00186
00187 <STRING>{
00188         \"           line_cont = 0; BEGIN (EO_LINE);
00189         \\a          AddChar ('\7');
00190         \\b          AddChar ('\b');
00191         \\t          AddChar ('\t');
00192         \\f          AddChar ('\f');
00193         \\e          AddChar (27);
00194         \\r          AddChar ('\r');
00195         \\n          AddChar ('\n');
00196         \\\\         AddChar ('\\');
00197         \\\"         AddChar ('\"');
00198         \\{HEX}      AddHexcode (yytext+2);
00199         \\{OCTAL}    AddOctal   (yytext+1);
00200         \\{DECIMAL}  AddDecimal (yytext+1);
00201         \\.          Abort ("Unknown ESC code: ", yytext);
00202         {NL}         Abort ("unterminated line", NULL);
00203         .            AddChar (yytext[0]);
00204         <<EOF>>      Abort ("Unexpected end-of-file", NULL);
00205 }
00206
00207 <EO_LINE>{
00208         \\\\         {
00209                        line_cont = 1;
00210                        BEGIN (INITIAL);
00211                      }
00212         {NL}         {
00213                        *ptr = '\0';
00214                        ptr  = NULL;
00215                        if (do_ref)
00216                             crc_ref = crc_bytes (buf, strlen(buf));
00217                        else AddEntry();
00218                        INCLINE();
00219                        BEGIN (INITIAL);
00220                      }
00221         .            /* discard */
00222         <<EOF>>      Abort ("Unexpected end-of-string", NULL);
00223 }
00224
00225 <PREFIX>{
00226         {LANG}":"    {
00227                        DEBUG ("lang `%s',\n", yytext);
00228                        if (!strncmp(yytext,lang.prefix,3))
00229                        {
00230                          ptr    = buf;
00231                          do_ref = FALSE;
00232                        }
00233                        else
00234                        {
00235                          ptr    = NULL;
00236                          do_ref = TRUE;
00237                        }
00238                        BEGIN (INITIAL);
00239                      }
00240         [#;].*{NL}   INCLINE();
00241         {NL}         INCLINE();
00242         .            Abort ("unknown language prefix: ", yytext);
00243 }
00244
00245 %%
00246
00247 /*---------------------------------------------------------------------*/
00248
00252 int yywrap (void)
00253 {
00254   return (1);
00255 }
00256
00260 static void AddChar (int ch)
00261 {
00262   if (ptr)
00263   {
00264     DEBUG ("%c", ch);
00265     *ptr++ = ch;
00266     if (ptr >= end)
00267        error ("string too large");
00268   }
00269 }
00270
00274 static void AddDecimal (const char *buf)
00275 {
00276   if (ptr)
00277   {
00278     int dec;
00279     sscanf (buf, "%d", &dec);
00280     DEBUG ("dec <%d>", dec);
00281     *ptr++ = dec;
00282     if (dec > 255)
00283        Abort ("Illegal decimal", NULL);
00284     if (ptr >= end)
00285        error ("string too large");
00286   }
00287 }
00288
00292 static void AddHexcode (const char *buf)
00293 {
00294   if (ptr)
00295   {
00296     WORD hex;
00297     sscanf (buf, "%hx", &hex);
00298     DEBUG ("hex <%X>", hex);
00299     *ptr++ = loBYTE (hex);
00300     if (ptr >= end)
00301        error ("string too large");
00302   }
00303 }
00304
00308 static void AddOctal (const char *buf)
00309 {
00310   if (ptr)
00311   {
00312     unsigned oct;
00313     sscanf (buf, "%o", &oct);
00314     DEBUG ("oct <%o>", oct);
00315     *ptr++ = loBYTE (oct);
00316     if (ptr >= end)
00317        error ("string too large");
00318   }
00319 }
00320
00324 static void AddEntry (void)
00325 {
00326   const  char *str;
00327   struct Node *list = NULL;
00328
00329   if ((str = strdup(buf)) == NULL ||
00330      (list = (struct Node*) calloc(sizeof(*list),1)) == NULL)
00331   {
00332     outsnl ("Language file too big!");
00333     longjmp (bail_out, 1);
00334   }
00335
00336   list->next   = lang.list;
00337   list->crc    = crc_ref;
00338   list->string = str;
00339   lang.list    = list;
00340   lang.entries++;
00341   do_ref = TRUE;
00342 }
00343
00348 static int Compare (const struct Elem *a, const struct Elem *b)
00349 {
00350   return ((long)a->crc - (long)b->crc);
00351 }
00352
00356 static int SortLanguageEntries (DWORD num)
00357 {
00358   struct Node *lng, *next;
00359   struct Elem *array = (struct Elem*) calloc ((size_t)num, sizeof(*array));
00360
00361   lang.array = array;
00362   if (!array)
00363      return (0);
00364
00365   for (lng = lang.list; lng; lng = next, array++)
00366   {
00367     array->crc    = lng->crc;
00368     array->string = lng->string;
00369     next = lng->next;
00370     free (lng);
00371   }
00372   lang.list = NULL;
00373   qsort (lang.array, (size_t)num, sizeof(*array),
00374          (int(*)(const void *, const void *))Compare);
00375   return (1);
00376 }
00377
00389 void lang_init (const char *value)
00390 {
00391   FILE *langf;
00392   char *s, *fname;
00393
00394   if (!value)
00395      return;
00396
00397   s = strchr (value, ',');
00398   if (!s || (s - value) != 2)
00399      Abort ("Illegal LANGUAGE syntax", NULL);
00400
00401   lang.line = 1;
00402   lang.prefix[0] = value[0];
00403   lang.prefix[1] = value[1];
00404   lang.prefix[2] = ':';
00405   lang.prefix[3] = '\0';
00406   strlwr (lang.prefix);
00407
00408   if (!strnicmp(lang.prefix,"en",2))  /* english is default language */
00409      return;
00410
00411   if (!crc_init())
00412   {
00413     outsnl ("CRC init failed");
00414     return;
00415   }
00416
00417   fname = ++s;
00418   langf = fopen (fname, "rb");
00419   if (!langf)
00420   {
00421     outs ("Cannot open language file ");
00422     outsnl (fname);
00423     return;
00424   }
00425
00426   if (!setjmp(bail_out))
00427   {
00428     yyin = langf;
00429     yylex();
00430     fclose (langf);
00431
00432     if (!SortLanguageEntries(lang.entries))
00433     {
00434       outsnl ("Could not sort LANGUAGE entries");
00435       lang.entries = 0;
00436     }
00437 #if defined(TEST_PROG)
00438     printf ("file-name    = `%s'\n",   fname);
00439     printf ("lang.prefix  = `%s'\n",   lang.prefix);
00440     printf ("lang.entries = %u\n",     lang.entries);
00441     printf ("lang.lines   = %u\n",     lang.line);
00442     printf ("lang.list    = %08lX\n",  (DWORD)lang.list);
00443     printf ("lang.array   = %08lX\n\n",(DWORD)lang.array);
00444     {
00445       const struct Elem *elem;
00446       size_t i;
00447
00448       for (i = 0, elem = lang.array; i < lang.entries; i++, elem++)
00449           printf ("CRC = %08lX, <%s>\n", elem->crc, elem->string);
00450     }
00451 #endif
00452   }
00453 }
00454
00458 typedef int (*CmpFunc) (const void *, const void *);
00459
00460 const char *lang_xlate (const char *str)
00461 {
00462   const struct Elem *elem;
00463   DWORD  hash;
00464   size_t len;
00465
00466   if (!lang.entries || !str)
00467      return (str);
00468
00469   len = strlen (str);
00470   if (len == 0)
00471      return (str);
00472
00473   hash = crc_bytes (str, len);
00474
00475   elem = (const struct Elem*) bsearch (&hash, lang.array, lang.entries,
00476                                        sizeof(*elem), (CmpFunc)Compare);
00477
00478   if (!elem || !elem->string || !elem->string[0])
00479      return (str);
00480
00481   return (elem->string);
00482 }
00483
00487 static void Abort (const char *s1, const char *s2)
00488 {
00489   outs ("\n");
00490   if (lang.line > 0)
00491   {
00492     char buf [15];
00493     itoa (lang.line, buf, 10);
00494     outs ("line ");
00495     outs (buf);
00496     outs (": ");
00497   }
00498   outs (s1);
00499   if (s2)
00500      outs (s2);
00501   outs ("\n");
00502   exit (1);
00503 }
00504
00508 static void error (const char *err)
00509 {
00510   char buf [15];
00511   itoa (lang.line, buf, 10);
00512   outs (err);
00513   outs (" at line ");
00514   outsnl (buf);
00515 }
00516
00517 #if defined(TEST_PROG)
00518 int main (void)
00519 {
00520   puts ("You must define a non-english language to parse language-file.\n"
00521         "Use e.g: \"language = no,$(ETC)\\watlang.txt\" in WATTCP.CFG\n"
00522         "Press any key to initialise Watt-32.");
00523   getch();
00524   sock_init();
00525   return (0);
00526 }
00527 #endif  /* TEST_PROG    */
00528 #endif  /* USE_LANGUAGE */
Generated on Wed Jan 25 15:42:35 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/LINKADDR.C Source File

SRC/LINKADDR.C

Go to the documentation of this file.
00001
00005 /* Copyright (c) 1990, 1993
00006  *      The Regents of the University of California.  All rights reserved.
00007  *
00008  * Redistribution and use in source and binary forms, with or without
00009  * modification, are permitted provided that the following conditions
00010  * are met:
00011  * 1. Redistributions of source code must retain the above copyright
00012  *    notice, this list of conditions and the following disclaimer.
00013  * 2. Redistributions in binary form must reproduce the above copyright
00014  *    notice, this list of conditions and the following disclaimer in the
00015  *    documentation and/or other materials provided with the distribution.
00016  * 3. All advertising materials mentioning features or use of this software
00017  *    must display the following acknowledgement:
00018  *      This product includes software developed by the University of
00019  *      California, Berkeley and its contributors.
00020  * 4. Neither the name of the University nor the names of its contributors
00021  *    may be used to endorse or promote products derived from this software
00022  *    without specific prior written permission.
00023  *
00024  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
00025  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00026  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00027  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
00028  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00029  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00030  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00031  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00032  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00033  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00034  * SUCH DAMAGE.
00035  *
00036  *  $Id: linkaddr.c,v 1.2 1998/08/20 21:56:24 joel Exp $
00037  */
00038
00039 #if defined(LIBC_SCCS) && !defined(lint)
00040 static char sccsid[] = "@(#)linkaddr.c  8.1 (Berkeley) 6/4/93";
00041 #endif
00042
00043 #include "socket.h"
00044
00045 #if defined(USE_BSD_API)
00046
00047 /* States
00048  */
00049 #define NAMING  0
00050 #define GOTONE  1
00051 #define GOTTWO  2
00052 #define RESET   3
00053
00054 /* Inputs
00055  */
00056 #define DIGIT   (4*0)
00057 #define END     (4*1)
00058 #define DELIM   (4*2)
00059 #define LETTER  (4*3)
00060
00061 void link_addr (const char *addr, struct sockaddr_dl *sdl)
00062 {
00063   char *cp    = sdl->sdl_data;
00064   char *cplim = sdl->sdl_len + (char*) sdl;
00065   int   byte  = 0;
00066   int   state = NAMING;
00067   int   New   = 0;
00068
00069   memset (&sdl->sdl_family, 0, sdl->sdl_len - 1);
00070   sdl->sdl_family = AF_LINK;
00071
00072   do
00073   {
00074     state &= ~LETTER;
00075     if (*addr >= '0' && *addr <= '9')
00076        New = *addr - '0';
00077
00078     else if (*addr >= 'a' && *addr <= 'f')
00079        New = *addr - 'a' + 10;
00080
00081     else if (*addr >= 'A' && *addr <= 'F')
00082        New = *addr - 'A' + 10;
00083
00084     else if (*addr == 0)
00085        state |= END;
00086
00087     else if (state == NAMING &&
00088              ((*addr >= 'A' && *addr <= 'Z') ||
00089               (*addr >= 'a' && *addr <= 'z')))
00090        state |= LETTER;
00091
00092     else
00093        state |= DELIM;
00094
00095     addr++;
00096     switch (state)
00097     {
00098       case NAMING | DIGIT:
00099       case NAMING | LETTER:
00100            *cp++ = addr[-1];
00101            continue;
00102       case NAMING | DELIM:
00103            state = RESET;
00104            sdl->sdl_nlen = cp - sdl->sdl_data;
00105            continue;
00106       case GOTTWO | DIGIT:
00107            *cp++ = byte;
00108            /* FALLTHROUGH */
00109       case RESET | DIGIT:
00110            state = GOTONE;
00111            byte = New;
00112            continue;
00113       case GOTONE | DIGIT:
00114            state = GOTTWO;
00115            byte = New + (byte << 4);
00116            continue;
00117       default:               /* | DELIM */
00118            state = RESET;
00119            *cp++ = byte;
00120            byte = 0;
00121            continue;
00122       case GOTONE | END:
00123       case GOTTWO | END:
00124            *cp++ = byte;
00125            /* FALLTHROUGH */
00126       case RESET | END:
00127            break;
00128     }
00129     break;
00130   }
00131   while (cp < cplim);
00132
00133   sdl->sdl_alen = cp - (char*)LLADDR (sdl);
00134   New = cp - (char*) sdl;
00135   if (New > (int)sizeof(*sdl))
00136      sdl->sdl_len = New;
00137 }
00138
00139 char *link_ntoa (const struct sockaddr_dl *sdl)
00140 {
00141   static char obuf[64];
00142   char  *out        = obuf;
00143   const BYTE *in    = (const BYTE*) LLADDR (sdl);
00144   const BYTE *inlim = in + sdl->sdl_alen;
00145   BOOL  firsttime = TRUE;
00146
00147   if (sdl->sdl_nlen)
00148   {
00149     memcpy (obuf, sdl->sdl_data, sdl->sdl_nlen);
00150     out += sdl->sdl_nlen;
00151     if (sdl->sdl_alen)
00152        *out++ = ':';
00153   }
00154   while (in < inlim && out < obuf+sizeof(obuf)-3)
00155   {
00156     int byte = *in++;
00157
00158     if (firsttime)
00159          firsttime = FALSE;
00160     else *out++ = '.';
00161     if (byte > 0xF)
00162     {
00163       *out++ = hex_chars_lower [byte >> 4];
00164       *out++ = hex_chars_lower [byte & 0xf];
00165     }
00166     else
00167       *out++ = hex_chars_lower [byte];
00168   }
00169   *out = '\0';
00170   return (obuf);
00171 }
00172
00173 #endif /* USE_BSD_API */
00174
Generated on Wed Jan 25 15:42:35 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/LISTEN.C Source File

SRC/LISTEN.C

Go to the documentation of this file.
00001
00005 /*  BSD sockets functionality for Waterloo TCP/IP
00006  *
00007  *  Copyright (c) 1997-2002 Gisle Vanem <giva@bgnett.no>
00008  *
00009  *  Redistribution and use in source and binary forms, with or without
00010  *  modification, are permitted provided that the following conditions
00011  *  are met:
00012  *  1. Redistributions of source code must retain the above copyright
00013  *     notice, this list of conditions and the following disclaimer.
00014  *  2. Redistributions in binary form must reproduce the above copyright
00015  *     notice, this list of conditions and the following disclaimer in the
00016  *     documentation and/or other materials provided with the distribution.
00017  *  3. All advertising materials mentioning features or use of this software
00018  *     must display the following acknowledgement:
00019  *       This product includes software developed by Gisle Vanem
00020  *       Bergen, Norway.
00021  *
00022  *  THIS SOFTWARE IS PROVIDED BY ME (Gisle Vanem) AND CONTRIBUTORS ``AS IS''
00023  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00024  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00025  *  ARE DISCLAIMED.  IN NO EVENT SHALL I OR CONTRIBUTORS BE LIABLE FOR ANY
00026  *  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00027  *  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00028  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00029  *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00030  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00031  *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00032  *
00033  *  Version
00034  *
00035  *  0.5 : Dec 18, 1997 : G. Vanem - created
00036  *  0.6 : Aug 08, 2002 : G. Vanem - added AF_INET6 support
00037  */
00038
00039 #include "socket.h"
00040
00041 #if defined(USE_BSD_API)
00042
00043 int W32_CALL listen (int s, int backlog)
00044 {
00045   Socket *socket = _socklist_find (s);
00046
00047   SOCK_PROLOGUE (socket, "\nlisten:%d", s);
00048
00049   if (!socket->local_addr)              /* bind() not called */
00050   {
00051     SOCK_DEBUGF ((", EINVAL"));
00052     SOCK_ERRNO (EINVAL);
00053     return (-1);
00054   }
00055
00056   if (socket->so_type != SOCK_STREAM)
00057   {
00058     SOCK_DEBUGF ((", EOPNOTSUPP"));
00059     SOCK_ERRNO (EOPNOTSUPP);
00060     return (-1);
00061   }
00062
00063   _sock_set_syn_hook (_sock_append);
00064
00065 #if defined(USE_IPV6)
00066   if (socket->so_family == AF_INET6)
00067   {
00068     struct in6_addr addr;
00069
00070     memset (&addr, 0, sizeof(addr));  /* unspecified addr */
00071     _TCP6_listen (socket, &addr, socket->local_addr->sin_port);
00072   }
00073   else
00074 #endif
00075   {
00076     struct in_addr addr;
00077
00078     addr.s_addr = INADDR_ANY;
00079     _TCP_listen (socket, addr, socket->local_addr->sin_port);
00080   }
00081
00082   SOCK_DEBUGF ((", port %d", ntohs(socket->local_addr->sin_port)));
00083
00084   /* A listen socket should never time out unless
00085    * setsockopt(SO_RCVTIMEOUT) is called prior to
00086    * accept().
00087    */
00088   socket->timeout = 0;
00089   socket->so_state   |= SS_ISLISTENING;
00090   socket->so_options |= SO_ACCEPTCONN;
00091
00092   /* legal backlog range [1..SOMAXCONN>
00093    */
00094   socket->backlog = min (backlog, SOMAXCONN-1);
00095   socket->backlog = max (socket->backlog, 1);
00096   SOCK_DEBUGF ((", backlog %d ", socket->backlog));
00097   return (0);
00098 }
00099
00100 #if defined(TEST_PROG)  /* A simple finger server */
00101
00102 #include <conio.h>
00103
00104 #define FINGER_PORT 79
00105
00106 int main (void)
00107 {
00108   struct sockaddr_in addr;
00109   int    serv_sock, cli_sock = -1;
00110   BOOL   quit = FALSE;
00111
00112   dbug_init();
00113
00114   serv_sock = socket (AF_INET, SOCK_STREAM, 0);
00115   if (serv_sock < 0)
00116   {
00117     perror ("socket");
00118     return (-1);
00119   }
00120
00121   memset (&addr, 0, sizeof(addr));
00122   addr.sin_family      = AF_INET;
00123   addr.sin_port        = htons (FINGER_PORT);
00124   addr.sin_addr.s_addr = htonl (INADDR_ANY);
00125
00126   if (bind(serv_sock, (struct sockaddr*)&addr, sizeof(addr)) < 0)
00127   {
00128     perror ("bind");
00129     close_s (serv_sock);
00130     return (-1);
00131   }
00132
00133   if (listen(serv_sock, 5) == -1)
00134   {
00135     perror ("listen");
00136     close_s (serv_sock);
00137     return (-1);
00138   }
00139
00140   printf ("Watt-32 finger server.\nPress ESC to quit\n");
00141
00142   while (!quit)
00143   {
00144     struct timeval tv = { 1, 0 };
00145     struct sockaddr_in peer;
00146     const char *who = "Login   Name  Tty  Idle   Login  Time\r\n"
00147                       "root    root  *1          Aug 22 10:15\r\n"
00148                       "guest   guest *2          Aug 22 11:22\r\n";
00149     fd_set rd;
00150     int    len = sizeof(peer);
00151     int    num;
00152
00153     if (kbhit() && getch() == 27)
00154        quit = TRUE;
00155
00156     FD_ZERO (&rd);
00157     FD_SET (s, &rd);
00158
00159     num = select_s (serv_sock+1, &rd, NULL, NULL, &tv);
00160     if (num < 0)
00161     {
00162       perror ("select_s");
00163       break;
00164     }
00165     if (num == 0)
00166     {
00167       putchar ('.');
00168       fflush (stdout);
00169       continue;
00170     }
00171
00172     if (!FD_ISSET(serv_sock,&rd))
00173        continue;
00174
00175     cli_sock = accept (serv_sock, (struct sockaddr*)&peer, &len);
00176     if (cli_sock < 0)
00177     {
00178       perror ("accept");
00179       break;
00180     }
00181
00182     printf ("Finger request from %s (%u)\n",
00183             inet_ntoa(peer.sin_addr), ntohs(peer.sin_port));
00184
00185     if (send(cli_sock, who, strlen(who), 0) < 0)
00186     {
00187       perror ("write_s");
00188       break;
00189     }
00190     close_s (cli_sock);   /* ready for next client */
00191     cli_sock = -1;
00192   }
00193
00194   if (cli_sock != -1)
00195      close_s (cli_sock);
00196   close_s (serv_sock);
00197   return (0);
00198 }
00199 #endif  /* TEST_PROG */
00200 #endif  /* USE_BSD_API */
Generated on Wed Jan 25 15:42:35 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/LOOKUP.C Source File

SRC/LOOKUP.C

Go to the documentation of this file.
00001
00031 #include <stdio.h>
00032 #include <stdlib.h>
00033 #include <string.h>
00034
00035 #include "wattcp.h"
00036 #include "strings.h"
00037 #include "language.h"
00038 #include "netaddr.h"
00039 #include "udp_dom.h"
00040 #include "ip4_in.h"
00041 #include "pcconfig.h"
00042 #include "pctcp.h"
00043
00044 DWORD lookup_host (const char *host, char *ip_str)
00045 {
00046   DWORD ip;
00047
00048   if (isaddr(host))
00049      ip = aton (host);
00050   else
00051   {
00052 #if defined(USE_DEBUG)
00053     (*_printf) ("Resolving `%s'...", host);
00054     fflush (stdout);
00055     ip = resolve (host);
00056     if (ip)
00057     {
00058       if (dom_cname[0] && debug_on >= 1)
00059          (*_printf) ("CNAME %s ", dom_cname);
00060       (*_printf) ("[%s]\n", _inet_ntoa(NULL,ip));
00061     }
00062 #else
00063     outs (_LANG("Resolving "));
00064     outs (host);
00065     outs ("...");
00066     ip = resolve (host);
00067     if (ip)
00068        outsnl (_inet_ntoa(NULL,ip));
00069 #endif
00070   }
00071
00072   if (!_ip4_is_loopback_addr(ip) && _ip4_is_multihome_addr(ip))
00073   {
00074 #if defined(USE_DEBUG)
00075     (*_printf) ("Cannot connect to ourself\n");
00076 #endif
00077     return (0);
00078   }
00079
00080   if (ip_str)
00081      _inet_ntoa (ip_str, ip);
00082   return (ip);
00083 }
Generated on Wed Jan 25 15:42:35 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/LOOPBACK.C Source File

SRC/LOOPBACK.C

Go to the documentation of this file.
00001
00048 #include <stdio.h>
00049 #include <stdlib.h>
00050
00051 #include "wattcp.h"
00052 #include "misc.h"
00053 #include "chksum.h"
00054 #include "ip4_in.h"
00055 #include "ip6_in.h"
00056 #include "pcsed.h"
00057 #include "pcstat.h"
00058 #include "pcicmp.h"
00059 #include "strings.h"
00060 #include "loopback.h"
00061
00062 WORD loopback_mode = LBACK_MODE_ENABLE;
00063
00064 #if defined(USE_LOOPBACK)
00065
00066 #if 0
00067
00068   A sketch of calls involved in sending/receiving an IP-packet
00069
00070
00071   Sending an IP-packet            |             Receiving an IP-packet
00072   --------------------------------|-----------------------------------
00073       |                           |                     |
00074       |                           |               tcp_tick()
00075       |                           |                     |
00076    _eth_formatpacket() ->buffer X |               _eth_arrived()
00077       |                           |                     |
00078    _ip4_output()                  |               poll_recv_queue()
00079       |                           |                     |
00080       |                           |                     |
00081    _eth_send()                    enqueue copy of       |
00082       |                           X to IP-queue         |
00083       *----->loopback_device()--*-->>>>>>-<-------pkt_poll_recv()
00084       |      (1)                | |   |            |    |
00085       |                         | |   |            |    |
00086       |                         | |   |            |    |
00087       |                         | |   |            |    |
00088    _pkt_send()    drop buffer X \ |   |          none _ip4_handler()
00089       |                           |   |            |    |
00090       |                           |   |            \  ip4_defragment()
00091       |                           |   |                 |
00092       |                           |   |               protocol handlers
00093       |                           |   |                 |
00094       |                           |   |               _eth_free()
00095       v                           |   |                 |
00096   packet-driver                   |   `-----------<-- pkt_free_pkt()
00097       |                           |                     |
00098   Ethernet/PPP                                          \
00099
00100   From the above it evident the current design cannot easily send
00101   IP-fragments. _ip4_output() must be rewritten to handle max. 64kB
00102   packets, split them in make_fragments(), format a link-layer packet
00103   using _eth_formatpacket() and repetively call _eth_send().
00104
00105   (1): A future Win32 version could try enqueueing to the Winsock
00106        loopback handler. A TDI provider??
00107 #endif
00108
00109
00110 int (*loopback_handler) (in_Header*) = NULL;
00111
00112 static int icmp_loopback (ICMP_PKT   *icmp, unsigned icmp_len);
00113 static int udp_loopback  (udp_Header *udp,  unsigned udp_len);
00114
00122 int loopback_device (in_Header *ip)
00123 {
00124   int   ip_len = 0;
00125   DWORD ip_dst;
00126   DWORD ip_ofs;
00127   WORD  ip_flg;
00128
00129   if (!(loopback_mode & LBACK_MODE_ENABLE))
00130      return (-1);
00131
00132   if (ip->ver == 4)
00133   {
00134     int ip_hlen;
00135
00136     if (!_chk_ip4_header(ip))       /* silently discard */
00137        return (-1);
00138
00139     ip_hlen = in_GetHdrLen (ip);    /* length of IP-header (w/options) */
00140     ip_len  = intel16 (ip->length); /* total length of IP-packet */
00141     ip_dst  = ip->destination;
00142
00143     ip->destination = ip->source;   /* swap source and destination */
00144     ip->source      = ip_dst;
00145     ip->checksum    = 0;
00146     ip->checksum    = ~CHECKSUM (ip, ip_hlen);   /* redo check-sum */
00147
00148     ip_ofs = intel16 (ip->frag_ofs);
00149     ip_flg = (WORD) (ip_ofs & ~IP_OFFMASK);
00150     ip_ofs = (ip_ofs & IP_OFFMASK) << 3; /* 0 <= ip_ofs <= 65536-8 */
00151
00152     if (ip_ofs || (ip_flg & IP_MF)) /* fragment; let ip4_defragment() */
00153        return (ip_len);             /* handle it on next poll */
00154
00155     if (ip->proto == ICMP_PROTO)
00156     {
00157       ICMP_PKT *icmp = (ICMP_PKT*) ((BYTE*)ip + ip_hlen);
00158       int       len  = icmp_loopback (icmp, ip_len - ip_hlen);
00159
00160       if (len > 0)
00161          return (ip_hlen+len);
00162     }
00163     else if (ip->proto == UDP_PROTO)
00164     {
00165       udp_Header *udp = (udp_Header*) ((BYTE*)ip + ip_hlen);
00166       int         len = udp_loopback (udp, ip_len-ip_hlen);
00167
00168       if (len > 0)
00169          return (ip_hlen+len);
00170     }
00171   }
00172 #if defined(USE_IPV6)
00173   else if (ip->ver == 6)
00174   {
00175     in6_Header *ip6 = (in6_Header*)ip;
00176     ip6_address ip6_dst;
00177
00178     ip_len = intel16 (ip6->len);
00179     memcpy (&ip6_dst, &ip6->destination, sizeof(ip6_dst));
00180     memcpy (&ip6->destination, &ip6->source, sizeof(ip6->destination));
00181     memcpy (&ip6->source, &ip6_dst, sizeof(ip6->source));
00182
00183     if (ip6->next_hdr == IP6_NEXT_ICMP)
00184     {
00185       ICMP_PKT *icmp = (ICMP_PKT*) (ip6 + 1);
00186       int       len  = icmp_loopback (icmp, ip_len);
00187
00188       if (len > 0)
00189          return (len + sizeof(*ip6));
00190     }
00191     else if (ip6->next_hdr == UDP_PROTO)
00192     {
00193       udp_Header *udp = (udp_Header*) (ip6 + 1);
00194       int         len = udp_loopback (udp, ip_len);
00195
00196       if (len > 0)
00197          return (len + sizeof(*ip6));
00198     }
00199   }
00200   else
00201   {
00202     (*_printf) ("%s: Illegal IP-packet (ver %d) for loopback device\n",
00203                 __FILE__, ip->ver);
00204     return (-1);
00205   }
00206 #endif
00207
00208   if (loopback_handler)
00209      ip_len = (*loopback_handler) (ip);
00210   return (ip_len);
00211 }
00212
00213 static int icmp_loopback (ICMP_PKT *icmp, unsigned icmp_len)
00214 {
00215   if (icmp_len >= sizeof(icmp->echo)    &&
00216       CHECKSUM(icmp,icmp_len) == 0xFFFF &&
00217       icmp->echo.type == ICMP_ECHO)
00218   {
00219     static WORD echo_seq_num = 0;
00220
00221     icmp->echo.type     = ICMP_ECHOREPLY;
00222     icmp->echo.sequence = echo_seq_num++;
00223     icmp->echo.checksum = 0;
00224     icmp->echo.checksum = ~CHECKSUM (icmp, icmp_len);
00225     STAT (icmpstats.icps_reflect++);
00226     STAT (icmpstats.icps_outhist[ICMP_ECHOREPLY]++);
00227     return (icmp_len);
00228   }
00231   return (0);
00232 }
00233
00234 static int udp_loopback (udp_Header *udp, unsigned udp_len)
00235 {
00236   if (intel16(udp->dstPort) == IPPORT_ECHO)
00237   {
00239   }
00240   else if (intel16(udp->dstPort) == IPPORT_DISCARD)
00241   {
00243   }
00244   ARGSUSED (udp_len);
00245   return (0);
00246 }
00247
00248 /*
00249  *  An example loopback handler for RPC Portmapper (udp port 111)
00250  *  (Maybe an contradiction in terms to do RPC locally :-)
00251  *
00252  *  int (*old_loopback) (const in_Header*) = NULL;
00253  *
00254  *  static int pmap_loopback (const in_Header *ip)
00255  *  {
00256  *    WORD  hlen = in_GetHdrLen (ip);
00257  *    const udp_Header *udp = (const udp_Header*) ((BYTE*)ip + hlen);
00258  *
00259  *    if (ip->proto == UDP_PROTO && intel16(udp->dstPort) == 111)
00260  *       return do_portmapper (udp); // return length of IP reply packet
00261  *
00262  *    if (old_loopback)
00263  *       return (*old_loopback) (ip);
00264  *    return intel16 (ip->length);
00265  *  }
00266  *
00267  *  void init_pmap_loopback (void)
00268  *  {
00269  *    old_loopback = loopback_handler;
00270  *    loopback_handler = pmap_loopback;
00271  *  }
00272  */
00273
00274 #endif /* USE_LOOPBACK */
Generated on Wed Jan 25 15:42:35 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/LOOPBACK.H Source File

SRC/LOOPBACK.H

Go to the documentation of this file.
00001
00003 #ifndef _w32_LOOPBACK_H
00004 #define _w32_LOOPBACK_H
00005
00006 #ifndef IPPORT_ECHO
00007 #define IPPORT_ECHO     7
00008 #endif
00009
00010 #ifndef IPPORT_DISCARD
00011 #define IPPORT_DISCARD  9
00012 #endif
00013
00014 #define LBACK_MODE_ENABLE  0x01
00015 #define LBACK_MODE_WINSOCK 0x10    /* highly experimental */
00016
00017 extern WORD  loopback_mode;
00018 extern int (*loopback_handler)(in_Header *);
00019 extern int   loopback_device  (in_Header *);
00020
00021 #endif
Generated on Wed Jan 25 15:42:35 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/MISC.C Source File

SRC/MISC.C

Go to the documentation of this file.
00001
00014 #include <stdio.h>
00015 #include <stdlib.h>
00016 #include <signal.h>
00017 #include <math.h>
00018
00019 #ifdef __HIGHC__
00020 #include <init.h>  /* _mwlsl(), _msgetcs() */
00021 #endif
00022
00023 #if defined(WIN32) || defined(_WIN32)
00024 #include <io.h>
00025 #include <fcntl.h>
00026 #include <share.h>
00027 #include <sys/stat.h>
00028 #endif
00029
00030 #include "wattcp.h"
00031 #include "wdpmi.h"
00032 #include "x32vm.h"
00033 #include "powerpak.h"
00034 #include "strings.h"
00035 #include "sock_ini.h"
00036 #include "cpumodel.h"
00037 #include "pcsed.h"
00038 #include "pcpkt.h"
00039 #include "pcconfig.h"
00040 #include "pcdbug.h"
00041 #include "bsddbug.h"
00042 #include "ioport.h"
00043 #include "btrace.h"
00044 #include "timer.h"
00045 #include "misc.h"
00046
00047 /* These arrays are used in several places (save some space)
00048  */
00049 const char hex_chars_lower[] = "0123456789abcdef";
00050 const char hex_chars_upper[] = "0123456789ABCDEF";
00051
00052 BOOL win32_dos_box     = FALSE;
00053 BOOL _watt_fatal_error = FALSE;
00054 WORD _watt_os_ver      = 0x622;
00055 char _watt_assert_buf[256];
00057 /*
00058  * Set through macro SOCK_ERRNO() in <sys/werrno.h>.
00059  */
00060 int _w32_errno = 0;
00061
00062 #if !defined(__DJGPP__)
00063   int __bss_count = 0;
00064 #endif
00065
00066 #if (DOSX & (PHARLAP|X32VM)) && defined(HAS_FP) /* has 48-bit far-pointers */
00067   FARPTR _watt_dosFp;
00068 #endif
00069
00070 #if defined(__LCC__)
00071   static _CPUID lcc_cpuid;
00072   char          cdecl x86_type = 5;      /* !! */
00073   char          cdecl x86_vendor_id[13];
00074   DWORD         cdecl x86_capability;
00075 #endif
00076
00077 #if (DOSX)
00078   static void setup_dos_xfer_buf (void);
00079   static void is_in_stack_init (void);
00080 #endif
00081
00082 #if defined(__BORLANDC__)
00083   #pragma inline
00084   #if defined(USE_DEBUG) && (defined(__SMALL__) || defined(__LARGE__))
00085   STATIC int setup_stk_check (void);
00086   #endif
00087
00088 #elif defined(WATCOM386) && !defined(WIN32)
00089   extern char cdecl __begtext;    /* label at TEXT start */
00090   extern UINT cdecl _x386_stacklow;
00091
00092   #if defined(__SW_3S)            /* wcc386 -3s */
00093     void cdecl _fatal_runtime_error (UINT stk);
00094     #define FATAL_HANDLER _fatal_runtime_error
00095   #else
00096     void cdecl _fatal_runtime_error_ (UINT stk);
00097     #define FATAL_HANDLER _fatal_runtime_error_
00098   #endif
00099
00100
00101   /* Prevent linker (with 'option eliminate') to strip our
00102    * '_fatal_runtime_error()' function from .exe-image.
00103    */
00104   char *dummy_fatal_rte = (char*)&FATAL_HANDLER;
00105
00106 #elif defined(_MSC_VER) && defined(__LARGE__) && defined(USE_DEBUG)
00107   extern void (__cdecl *_aaltstkovr) (void);
00108   static void stk_overflow (void _far *where);
00109 #endif
00110
00111 #if (DOSX & (PHARLAP|X32VM)) || (DOSX == 0)
00112 #define CS_WRITEABLE
00113 #endif
00114
00115 #define MAKE_CS_WRITEABLE() ((void)0)
00116 #define UNDO_CS_ACCESS()    ((void)0)
00119 #if defined(USE_DEBUG) && defined(__BORLANDC__) && (defined(__SMALL__) || defined(__LARGE__))
00120 STATIC void test_stk_check (void)
00121 {
00122   char buf[1000];
00123   sprintf (buf, "In test_stk_check(): CS:IP %04X:%04X\n",
00124            _CS, FP_OFF(test_stk_check));
00125   puts (buf);
00126 }
00127 #endif
00128
00129 /*
00130  * Turn off stack-checking to avoid destroying assumptions
00131  * made in bswap patch code below. And also to make this run
00132  * a bit faster.
00133  */
00134 #include "nochkstk.h"
00135
00136 #if !defined(USE_BIGENDIAN)
00137
00141 unsigned long cdecl _w32_intel (unsigned long val)
00142 {
00143   return ((val & 0x000000FFU) << 24) |
00144          ((val & 0x0000FF00U) <<  8) |
00145          ((val & 0x00FF0000U) >>  8) |
00146          ((val & 0xFF000000U) >> 24);
00147 }
00148
00153 unsigned short cdecl _w32_intel16 (unsigned short val)
00154 {
00155   return ((val & 0x00FF) << 8) | ((val & 0xFF00) >> 8);
00156 }
00157
00158 #if (DOSX) && defined(CS_WRITEABLE)
00159 static const BYTE bswap32[] = {
00160              0x8B,0x44,0x24,0x04,       /* mov eax,[esp+4] */
00161              0x0F,0xC8,                 /* bswap eax       */
00162              0xC3                       /* ret             */
00163            };
00164
00165 static const BYTE bswap16[] = {
00166              0x8B,0x44,0x24,0x04,       /* mov eax,[esp+4] */
00167              0x0F,0xC8,                 /* bswap eax       */
00168              0xC1,0xE8,0x10,            /* shr eax,16      */
00169              0xC3                       /* ret             */
00170            };
00171
00172 /*
00173  * Modify functions intel/intel16 (htonl/htons) to use the
00174  * BSWAP instruction on 80486+ CPUs. We don't bother with real-mode
00175  * targets on a 80486+ CPU. Hope that size of overwritten functions
00176  * are big enough.
00177  */
00178 static void patch_with_bswap (void)
00179 {
00180   MAKE_CS_WRITEABLE();  /* save descriptor access, make RW */
00181   memcpy ((void*)_w32_intel,  (const void*)&bswap32, sizeof(bswap32));
00182   memcpy ((void*)_w32_intel16,(const void*)&bswap16, sizeof(bswap16));
00183   UNDO_CS_ACCESS();     /* set old descriptor access */
00184 }
00185 #endif  /* (DOSX) && defined(CS_WRITEABLE) */
00186 #endif  /* !USE_BIGENDIAN */
00187
00188
00194 DWORD get_day_num (void)
00195 {
00196 #if defined(WIN32)
00197   time_t now;
00198
00199   time (&now);
00200   return (now / (24*3600));
00201 #else
00202   struct dosdate_t d;
00203
00204   memset (&d, 0, sizeof(d));
00205   _dos_getdate (&d);
00206   --d.month;
00207   --d.day;
00208   return ((d.year-1970) * 365 + d.month * 31 + d.day);
00209 #endif
00210 }
00211
00212
00213 #if (DOSX) && !defined(USE_BIGENDIAN)
00214 /*
00215  * Safe check for an enabled RDTSC instruction.
00216  * Requires an "GenuineIntel" Pentium CPU to call Get_CR4()
00217  * (crashes on AMD K6-2 etc.).
00218  */
00219 static BOOL RDTSC_enabled (void)
00220 {
00221   const char *env = getenv ("USE_RDTSC");
00222
00223   use_rdtsc = (env && ATOI(env) > 0);
00224
00225   if (!use_rdtsc ||     /* Usage not enabled */
00226       x86_type < 5)     /* Not a Pentium class CPU */
00227      return (FALSE);
00228
00229   if (!strncmp(x86_vendor_id,"AuthenticAMD",12) &&
00230       (x86_capability & X86_CAPA_TSC))            /* AMD with TSC, okay? */
00231      return (TRUE);
00232
00233   if (!strncmp(x86_vendor_id,"CentaurHauls",12))  /* Centaur/VIA is okay */
00234   {
00235 #if 0
00236    /* The following code was originally written by
00237     * Michal Ludvig <michal@logix.cz> for VIA PadLock code
00238     * in OpenSSL. http://www.logix.cz/michal
00239     */
00240     DWORD eax, ebx, ecx, edx;
00241
00242     get_cpuid (0xC0000000, &eax, &ebx, &ecx, &edx);
00243     centaur_eflag = (eax >= 0xC0000001);
00244     if (centaur_eflag)
00245     {
00246       get_cpuid (0xC0000001, &eax, &ebx, &ecx, &edx);
00247       use_ace = ((edx & (0x3<<6)) == (0x3<<6)); /* Advanced Cryptography Engine */
00248       use_rng = ((edx & (0x3<<2)) == (0x3<<2)); /* Random Number Generator */
00249     }
00250 #endif
00251     return (TRUE);
00252   }
00253
00254   if (strncmp(x86_vendor_id,"GenuineIntel",12) || /* Not Genuine Intel or */
00255       (x86_capability & X86_CAPA_TSC) == 0)       /* RDTSC not supported */
00256      return (FALSE);
00257
00258 #if (DOSX) && !defined(__LCC__) && !defined(BORLAND_WIN32)
00259   return ((Get_CR4() & CR4_TS_DISABLE) == 0);     /* True if not disabled */
00260 #else
00261   return (TRUE);   /* RDTSC never disabled in real-mode */
00262 #endif
00263 }
00264 #endif  /* DOSX && !USE_BIGENDIAN */
00265
00266
00267 #if (DOSX == 0) && defined(USE_DEBUG)
00268
00275 #define OffsetOf(x) (unsigned)&(x)
00276
00277 static BOOL check_reg_struct (void)
00278 {
00279 #if defined(__WATCOMC__)
00280   struct IREGS   *r1 = NULL;
00281   union  REGPACK *r2 = NULL;
00282
00283   if ((OffsetOf(r2->w.ax)    != OffsetOf(r1->r_ax)) ||
00284       (OffsetOf(r2->w.bx)    != OffsetOf(r1->r_bx)) ||
00285       (OffsetOf(r2->w.cx)    != OffsetOf(r1->r_cx)) ||
00286       (OffsetOf(r2->w.dx)    != OffsetOf(r1->r_dx)) ||
00287       (OffsetOf(r2->w.bp)    != OffsetOf(r1->r_bp)) ||
00288       (OffsetOf(r2->w.si)    != OffsetOf(r1->r_si)) ||
00289       (OffsetOf(r2->w.di)    != OffsetOf(r1->r_di)) ||
00290       (OffsetOf(r2->w.ds)    != OffsetOf(r1->r_ds)) ||
00291       (OffsetOf(r2->w.es)    != OffsetOf(r1->r_es)) ||
00292       (OffsetOf(r2->x.flags) != OffsetOf(r1->r_flags)))
00293      return (FALSE);
00294
00295 #elif defined(__BORLANDC__)
00296   struct IREGS   *r1 = NULL;
00297   struct REGPACK *r2 = NULL;
00298
00299   if ((OffsetOf(r2->r_ax)    != OffsetOf(r1->r_ax)) ||
00300       (OffsetOf(r2->r_bx)    != OffsetOf(r1->r_bx)) ||
00301       (OffsetOf(r2->r_cx)    != OffsetOf(r1->r_cx)) ||
00302       (OffsetOf(r2->r_dx)    != OffsetOf(r1->r_dx)) ||
00303       (OffsetOf(r2->r_bp)    != OffsetOf(r1->r_bp)) ||
00304       (OffsetOf(r2->r_si)    != OffsetOf(r1->r_si)) ||
00305       (OffsetOf(r2->r_di)    != OffsetOf(r1->r_di)) ||
00306       (OffsetOf(r2->r_ds)    != OffsetOf(r1->r_ds)) ||
00307       (OffsetOf(r2->r_es)    != OffsetOf(r1->r_es)) ||
00308       (OffsetOf(r2->r_flags) != OffsetOf(r1->r_flags)))
00309      return (FALSE);
00310 #endif
00311   return (TRUE);
00312 }
00313 #endif /* (DOSX == 0) && USE_DEBUG */
00314
00318 void init_misc (void)
00319 {
00320   static BOOL init = FALSE;
00321
00322   if (init)
00323      return;
00324
00325   _watt_assert_buf[0] = '\0';
00326
00327 #if (DOSX)
00328   is_in_stack_init();
00329 #endif
00330
00331 #if defined(WIN32)
00332   init_winmisc();
00333
00334 #elif defined(__DJGPP__)
00335   _watt_os_ver = _get_dos_version (1);
00336
00337 #elif defined(MSC386)
00338   _watt_os_ver = 0x500;   /* Fake it for 32-bit MSVC */
00339
00340 #else
00341   _watt_os_ver = (_osmajor << 8) + _osminor;
00342 #endif
00343
00344 #if defined(WIN32)
00345   win32_dos_box = FALSE;
00346 #else
00347   win32_dos_box = (_watt_os_ver >= 0x700 || /* DOS 7.x/8.x; Win-9x/ME */
00348                    _watt_os_ver == 0x501 || /* Borland PowerPak under Win32 */
00349                    _watt_os_ver == 0x532);  /* DOS 5.50; Win-NT+ */
00350 #endif
00351
00352 #if (DOSX & PHARLAP) && defined(HAS_FP)
00353   /*
00354    * For 32-bit compilers with 48-bit far-pointers.
00355    * `init_misc' MUST be called before `PEEKx()' functions are used.
00356    */
00357   FP_SET (_watt_dosFp, 0, SS_DOSMEM);
00358
00359 #elif (DOSX & X32VM)
00360   _watt_dosFp = MK_FP (_x386_zero_base_selector, 0);
00361
00362 #elif defined(HAS_FP) /* MSVC */
00363   UNFINISHED();
00364 #endif
00365
00366 #if defined(__DJGPP__) || defined(__HIGHC__)
00367 /* backtrace_init(); */
00368 #endif
00369
00370 #if (DOSX)
00371   setup_dos_xfer_buf();  /* A no-op on djgpp+Win32 */
00372
00373 #elif defined(USE_DEBUG)  /* real-mode */
00374   if (!check_reg_struct())
00375   {
00376     outsnl (__FILE__ ": IREGS/REGPACK size mismatch!");
00377     exit (-1);
00378   }
00379
00380   #if defined(_MSC_VER) && defined(__LARGE__)
00381   (DWORD)_aaltstkovr = (DWORD)stk_overflow;
00382   #endif
00383
00384   #if defined(__BORLANDC__) && (defined(__SMALL__) || defined(__LARGE__))
00385   setup_stk_check();
00386   #endif
00387 #endif
00388
00389   /* Check CPU type. Use RDTSC instruction if not forced off and
00390    * it's not disabled. No CPU detection of big-endian machines yet.
00391    */
00392 #if (DOSX) && !defined(USE_BIGENDIAN)
00393 #if defined(__LCC__)
00394   if (_cpuidPresent())
00395   {
00396     _cpuid (&lcc_cpuid);
00397     memcpy (&x86_vendor_id, &lcc_cpuid.Vendor, sizeof(x86_vendor_id));
00398     x86_capability = X86_CAPA_TSC; /* !! this doesn't work: *(DWORD*) &lcc_cpuid.FpuPresent; */
00399   }
00400 #elif !defined(BORLAND_WIN32)
00401   CheckCpuType();
00402 #endif
00403
00404   if (RDTSC_enabled())  /* Try to use RDTSC */
00405      has_rdtsc = TRUE;
00406
00407 #if defined(CS_WRITEABLE)
00408   if (x86_type >= 4)
00409      patch_with_bswap();
00410 #endif
00411 #endif  /* DOSX && !USE_BIGENDIAN */
00412
00413 #if defined(WIN32)
00414   srand (GetTickCount()); /* should be redundant */
00415 #else
00416   srand (PEEKW(0,0x46C)); /* initialize rand() using BIOS clock */
00417 #endif
00418
00419   init_timers();
00420   init = TRUE;
00421 }
00422
00429 FILE *fopen_excl (const char *file, const char *mode)
00430 {
00431 #ifndef _O_SEQUENTIAL    /* bcc32 */
00432 #define _O_SEQUENTIAL 0
00433 #endif
00434
00435 #if defined(WIN32) && !defined(__WATCOMC__)
00436   int fd = _sopen (file, _O_CREAT | _O_TRUNC | _O_WRONLY | _O_SEQUENTIAL,
00437                    SH_DENYWR, S_IREAD | S_IWRITE);
00438   if (fd <= -1)
00439      return (NULL);
00440   return fdopen (fd, mode);
00441 #else
00442   return fopen (file, mode);
00443 #endif
00444 }
00445
00450 struct on_exit {
00451        void      (*func)(void);
00452        const char *name;
00453        int         order;
00454      };
00455
00456 static struct on_exit exit_list [40];
00457
00458 static int list_compare (const struct on_exit *a, const struct on_exit *b)
00459 {
00460   return (a->order - b->order);
00461 }
00462
00466 int rundown_add (void (*func)(void), const char *name, int order,
00467                  const char *file, unsigned line)
00468 {
00469   static int num_ins = 0;
00470   int    i;
00471
00472   for (i = 0; i < num_ins; i++)
00473   {
00474     if (!exit_list[i].func)
00475        continue;
00476
00477     if (exit_list[i].func == func)
00478        goto modify;
00479
00480     if (exit_list[i].order == order)
00481     {
00482 #if defined(USE_DEBUG)
00483       (*_printf) ("%s(%u): rundown_add (\"%s\",%d): order already "
00484                   "in exit_list[]\n", file, line, name, order);
00485       exit (-1);
00486 #else
00487       return (-1);
00488 #endif
00489     }
00490   }
00491
00492   WATT_ASSERT (num_ins < DIM(exit_list));
00493   i = num_ins++;
00494
00495 modify:
00496   exit_list[i].func  = func;
00497   exit_list[i].name  = name;
00498   exit_list[i].order = order;
00499
00500   qsort (&exit_list, DIM(exit_list), sizeof(exit_list[0]),
00501          (int(*)(const void *, const void *))list_compare);
00502
00503   ARGSUSED (file);
00504   ARGSUSED (line);
00505   return (num_ins);
00506 }
00507
00511 void rundown_run (void)
00512 {
00513   struct on_exit *oe;
00514   void (*func)(void);
00515   int  i;
00516
00517   for (i = 0, oe = exit_list; i < DIM(exit_list); i++, oe++)
00518   {
00519     if (!oe->func)
00520        continue;
00521
00522 #if defined(USE_DEBUG)
00523     if (debug_on >= 3)
00524     {
00525       (*_printf) ("Calling rundown-func `%s' at order %d\n",
00526                   oe->name, oe->order);
00527       fflush (stdout);
00528     }
00529 #endif
00530      func = oe->func;
00531      oe->func = NULL;    /* don't call it again */
00532      (*func)();
00533   }
00534 }
00535
00536 #if defined(USE_DEBUG)
00537
00540 void rundown_dump (void)
00541 {
00542   const struct on_exit *oe;
00543   int   i, num_active;
00544
00545   (*_printf) ("rundown_dump():\n");
00546   for (i = num_active = 0, oe = exit_list; i < DIM(exit_list); i++, oe++)
00547   {
00548     if (!oe->func)
00549        continue;
00550     (*_printf) ("  order %3d: %s\n", oe->order, oe->name);
00551     num_active++;
00552   }
00553   (*_printf) ("  %s\n", num_active == i ? "possible overflow" : "okay");
00554 }
00555 #endif
00556
00557
00558 /*
00559  * Consolidated memory debug for Fortify, mpatrol and MSVC CrtDbg.
00560  */
00561 #if defined(USE_CRTDBG)
00562 /*
00563  * If using MSVCRTD debug version, there's little point using Fortify too.
00564  * USE_CRTDBG is set only when building with cl -MDd or MTd etc (_DEBUG set).
00565  */
00566 #if !defined(_CRT_RPTHOOK_INSTALL) && (_MSC_VER < 1300)  /* SDK too old */
00567   #define _CRT_RPTHOOK_INSTALL 0
00568   #define _CRT_RPTHOOK_REMOVE  1
00569
00570   _CRTIMP _CRT_REPORT_HOOK __cdecl
00571    _CrtSetReportHook2 (int, _CRT_REPORT_HOOK);
00572 #endif
00573
00574 static _CrtMemState last_state;
00575 static void __cdecl crtdbg_exit (void);
00576
00577 static const char *report_name (int type)
00578 {
00579   return (type == _CRT_WARN   ? "Warn"   :
00580           type == _CRT_ERROR  ? "Error"  :
00581           type == _CRT_ASSERT ? "Assert" :
00582           type == _CRT_ERRCNT ? "ErrCnt" : "??");
00583 }
00584
00585 /*
00586  * This doesn't seem to be called (?)
00587  */
00588 static void __cdecl crtdbg_dump (const void *buf, size_t len)
00589 {
00590   const BYTE *p = (const BYTE*) buf;
00591   size_t i;
00592   int    c;
00593
00594   fprintf (stderr, "dump: buf %p, %u bytes\n", buf, len);
00595   len = min (len, 30);
00596   for (i = 0; i < len; i++)
00597   {
00598     c = *p++;
00599     fprintf (stderr, "%c", isprint(c) ? c : '.');
00600   }
00601 }
00602
00603 static int __cdecl crtdbg_report (int type, char *message, int *ret_val)
00604 {
00605   BOOL stop;
00606
00607   fprintf (stderr, "%s: %s\n", report_name(type), message);
00608   stop = (type == _CRT_ASSERT);
00609   if (stop)
00610   {
00611     _CrtMemDumpAllObjectsSince (&last_state);
00612     crtdbg_exit();
00613  /* StackWalk (&ret_val); */
00614   }
00615   if (ret_val)
00616      *ret_val = stop;  /* stopping forces a breakpoint (int 3) */
00617   return (stop);
00618 }
00619
00620 static void __cdecl crtdbg_exit (void)
00621 {
00622 #if 0
00623   _CrtMemDumpStatistics (&last_state);
00624   _CrtCheckMemory();
00625   _CrtDumpMemoryLeaks();
00626 #endif
00627
00628 #if (_MSC_VER >= 1300) && 0
00629   _CrtSetReportHook2 (_CRT_RPTHOOK_REMOVE, crtdbg_report);
00630 #else
00631   _CrtSetReportHook (NULL);
00632 #endif
00633 }
00634
00635 void memdbg_init (void)
00636 {
00637   _HFILE file = _CRTDBG_FILE_STDERR;
00638   int    mode = _CRTDBG_MODE_FILE;
00639   int    flags = _CRTDBG_LEAK_CHECK_DF |
00640                  _CRTDBG_DELAY_FREE_MEM_DF |
00641               /* _CRTDBG_CHECK_CRT_DF | */    /* Don't report allocs in CRT */
00642                  _CRTDBG_CHECK_ALWAYS_DF |
00643                  _CRTDBG_ALLOC_MEM_DF;
00644
00645   _CrtSetReportFile (_CRT_ASSERT, file);
00646   _CrtSetReportMode (_CRT_ASSERT, mode);
00647   _CrtSetReportFile (_CRT_ERROR, file);
00648   _CrtSetReportMode (_CRT_ERROR, mode);
00649   _CrtSetReportFile (_CRT_WARN, file);
00650   _CrtSetReportMode (_CRT_WARN, mode);
00651
00652   _CrtSetDbgFlag (flags | _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG));
00653
00654 #if (_MSC_VER >= 1300) && 0
00655   _CrtSetReportHook2 (_CRT_RPTHOOK_INSTALL, crtdbg_report);
00656 #else
00657   _CrtSetReportHook (crtdbg_report);
00658 #endif
00659
00660   _CrtMemCheckpoint (&last_state);
00661   _CrtSetDumpClient (crtdbg_dump);
00662
00663   RUNDOWN_ADD (crtdbg_exit, 305);
00664 }
00665
00666 #elif defined(USE_FORTIFY)
00667
00672 static void fortify_report (void)
00673 {
00674   if (debug_on >= 2)
00675   {
00676     Fortify_SetOutputFunc ((Fortify_OutputFuncPtr)printf);
00677     Fortify_OutputStatistics();
00678   }
00679   else
00680     Fortify_SetOutputFunc (NULL);
00681   Fortify_LeaveScope();
00682 }
00683
00684 void memdbg_init (void)
00685 {
00686   const char *env = getenv ("FORTIFY_FAIL");
00687
00688   Fortify_EnterScope();
00689   if (env)
00690      Fortify_SetAllocateFailRate (atoi(env));
00691
00692 #if defined(USE_DEBUG) && defined(USE_BSD_API)
00693   Fortify_SetOutputFunc (bsd_fortify_print);
00694 #endif
00695
00696   RUNDOWN_ADD (fortify_report, 305);
00697 #if defined(WIN32)
00698   LoadLibrary ("exchndl.dll");  /* Dr. MingW */
00699 #endif
00700 }
00701 #endif   /* USE_CRTDBG */
00702
00703
00704 #if defined(USE_DEBUG) && !defined(NDEBUG)
00705
00708 void assert_fail (const char *file, unsigned line, const char *what)
00709 {
00710 #if defined(SNPRINTF)
00711   SNPRINTF (_watt_assert_buf, sizeof(_watt_assert_buf)-1,
00712 #else
00713   sprintf (_watt_assert_buf,
00714 #endif
00715            "%s (%u): Assertion `%s' failed.\n", file, line, what);
00716
00717   (*_printf) ("%s\n", _watt_assert_buf);
00718
00719 #ifdef __DJGPP__
00720   /*
00721    * abort() doesn't call atexit() functions but makes a handy traceback.
00722    */
00723   rundown_run();
00724   abort();
00725 #else
00726   exit (-1);
00727 #endif
00728 }
00729 #endif  /* USE_DEBUG && !NDEBUG */
00730
00731
00735 unsigned Random (unsigned a, unsigned b)
00736 {
00737   if (a == b)
00738      return (a);
00739
00740   if (a > b)
00741   {
00742     unsigned tmp = b;
00743     b = a;
00744     a = tmp;
00745   }
00746   return (a + (unsigned)(rand() % (b-a+1)));
00747 }
00748
00752 void RandomWait (unsigned a, unsigned b)
00753 {
00754   DWORD t = set_timeout (Random(a, b));
00755
00756   while (!chk_timeout(t))
00757   {
00758 #if defined(WIN32)
00759     Sleep (1);
00760 #else
00761     ENABLE();
00762 #endif
00763   }
00764 }
00765
00769 void Wait (unsigned msec)
00770 {
00771   DWORD t = set_timeout (msec);
00772
00773   while (!chk_timeout(t))
00774   {
00775 #if defined(WIN32)
00776     Sleep (1);
00777 #else
00778     ENABLE();
00779 #endif
00780   }
00781 }
00782
00783 /*
00784  * Return a sensible name for running DOS-extender or subsystem.
00785  */
00786 const char *dos_extender_name (void)
00787 {
00788 #if (DOSX & DOS4GW)
00789   return dos4gw_extender_name();
00790 #elif (DOSX & DJGPP)
00791   return ("djgpp");
00792 #elif (DOSX & PHARLAP)
00793   return ("PharLap");
00794 #elif (DOSX & POWERPAK)
00795   return ("PowerPak");
00796 #elif (DOSX & X32VM)
00797   return ("X32VM");
00798 #elif (DOSX & WINWATT)
00799   return ("Win32");
00800 #else
00801   return (NULL);
00802 #endif
00803 }
00804
00805
00806 void os_yield (void)
00807 {
00808 #if defined(WIN32)
00809   /* SwitchToThread(); */ /* This doesn't really help reduce CPU usage */
00810   Sleep (1);
00811 #else
00812   static BOOL do_yield = TRUE;
00813
00814 #if defined(__DJGPP__)
00815   if (do_yield)
00816   {
00817     __dpmi_yield();
00818     do_yield = (errno != ENOSYS);
00819   }
00820 #else
00821   if (!watt_kbhit() && do_yield)  /* watt_kbhit() to permit ^C */
00822   {
00823     IREGS reg;
00824     memset (&reg, 0, sizeof(reg));
00825     reg.r_ax = 0x1680;
00826     GEN_INTERRUPT (0x2F, &reg);
00827     do_yield = (loBYTE(reg.r_ax) != 0x80);
00828   }
00829 #endif
00830 #endif  /* WIN32 */
00831 }
00832
00833
00834 #if defined(NOT_USED)
00835 BOOL watt_check_break (void)
00836 {
00837   WORD head = 0x400 + PEEKW (0, 0x41A);
00838   WORD tail = 0x400 + PEEKW (0, 0x41C);
00839   int  ofs, num;
00840
00841   printf ("\nwatt_check_break(): head %04X, tail %04X, keys:\n",
00842           head, tail);
00843   for (num = 0, ofs = head; ofs != tail && num < 32; num++)
00844   {
00845     printf ("  ofs %04X: %02X\n", ofs, PEEKB(0,ofs));
00846     if (++ofs > 32+0x41E)
00847        ofs = 0x41E;
00848   }
00849   puts ("");
00850   return (FALSE);
00851 }
00852 #endif
00853
00854
00858 int watt_kbhit (void)
00859 {
00860   if (_watt_cbroke)
00861      return (1);
00862
00863 #if defined(WIN32)
00864   Sleep (1);
00865   return kbhit();
00866
00867 #else
00868   if (PEEKW(0,0x41A) == PEEKW(0,0x41C))
00869      return (0);
00870
00871   /* RTL's kbhit() calls INT16/11 or INT21/0B which triggers INT 23
00872    * which in turn should raise SIGINT in RTL. Except for djgpp under
00873    * Windows where normal/extended BREAK checking is turned off (since
00874    * SIGINT delivery by pressing ^C is so unreliable under Windows).
00875    */
00876   return kbhit();
00877 #endif
00878 }
00879
00880
00881 #if defined(USE_DEBUG)
00882
00885 const char *list_lookup (DWORD type, const struct search_list *list, int num)
00886 {
00887   static char buf[15];
00888
00889   while (num > 0 && list->name)
00890   {
00891     if (list->type == type)
00892        return (list->name);
00893     num--;
00894     list++;
00895   }
00896   sprintf (buf, "?%lu", type);
00897   return (buf);
00898 }
00899
00900
00905 const char *MAC_address (const void *addr)
00906 {
00907   static char buf[2][25];
00908   static int  idx = 0;
00909   char  *rc = buf [idx];
00910   char  *p  = rc;
00911   const char *a = (const char*)addr;
00912
00913   p += sprintf (p, "%02X:%02X:%02X:%02X:%02X:%02X",
00914                 a[0] & 255, a[1] & 255, a[2] & 255,
00915                 a[3] & 255, a[4] & 255, a[5] & 255);
00916
00917   /* assume '*addr' is an 7-byte AX25 address
00918    */
00919   if (_pktdevclass == PDCLASS_AX25)
00920      sprintf (p, ":%02X", a[6] & 255);
00921
00922   idx ^= 1;
00923   return (rc);
00924 }
00925
00926 void unfinished (const char *func, const char *file, unsigned line)
00927 {
00928   if (func)
00929      fprintf (stderr, "In `%s' ", func);
00930   fprintf (stderr, "%s (%u):\7 Help! Unfinished code.\n", file, line);
00931   exit (-1);
00932 }
00933
00938 const char *dword_str (DWORD val)
00939 {
00940   static char buf[20];
00941   char   tmp[20];
00942
00943   if (val < 1000UL)
00944   {
00945     sprintf (buf, "%lu", val);
00946     return (buf);
00947   }
00948   if (val < 1000000UL)       /* 1E6 */
00949   {
00950     sprintf (buf, "%lu,%03lu", val/1000UL, val % 1000UL);
00951     return (buf);
00952   }
00953   if (val < 1000000000UL)    /* 1E9 */
00954   {
00955     sprintf (tmp, "%9lu", val);
00956     sprintf (buf, "%.3s,%.3s,%.3s", tmp, tmp+3, tmp+6);
00957     return strltrim (buf);
00958   }
00959   sprintf (tmp, "%12lu", val);
00960   sprintf (buf, "%.3s,%.3s,%.3s,%.3s", tmp, tmp+3, tmp+6, tmp+9);
00961   return strltrim (buf);
00962 }
00963 #endif /* USE_DEBUG */
00964
00965
00966 #if (DOSX)
00967 #if defined(BORLAND386) || defined(DMC386) || defined(MSC386)
00968 DWORD get_ds_limit (void)
00969 {
00970   DWORD res;
00971   asm mov ax, ds
00972   asm and eax, 0FFFFh
00973   asm lsl eax, eax
00974   asm mov res, eax
00975   return (res);
00976 }
00977
00978 DWORD get_cs_limit (void)
00979 {
00980   DWORD res;
00981   asm mov ax, cs
00982   asm and eax, 0FFFFh
00983   asm lsl eax, eax
00984   asm mov res, eax
00985   return (res);
00986 }
00987
00988 DWORD get_ss_limit (void)
00989 {
00990   DWORD res;
00991   asm mov ax, ss
00992   asm and eax, 0FFFFh
00993   asm lsl eax, eax
00994   asm mov res, eax
00995   return (res);
00996 }
00997
00998 #elif defined(__CCDL__)
00999 DWORD get_ds_limit (void)
01000 {
01001   asm {
01002     mov ax, ds
01003     and eax, 0xFFFF
01004     lsl eax, eax
01005   }
01006   return (_EAX);
01007 }
01008
01009 DWORD get_cs_limit (void)
01010 {
01011   asm {
01012     mov ax, cs
01013     and eax, 0xFFFF
01014     lsl eax, eax
01015   }
01016   return (_EAX);
01017 }
01018
01019 DWORD get_ss_limit (void)
01020 {
01021   asm {
01022     mov ax, ss
01023     and eax, 0xFFFF
01024     lsl eax, eax
01025   }
01026   return (_EAX);
01027 }
01028 #endif
01029
01030 /*
01031  * The is_in_stack() function is by
01032  * Jani Kajala (jani.kajala@helsinki.fi)
01033  * Feb 7, 2002,
01034  */
01035 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
01036   #define THREADLOCAL __declspec(thread)
01037 #else
01038   #define THREADLOCAL
01039 #endif
01040
01041 THREADLOCAL static const char *stack_bottom = 0;
01042
01043 #if defined(__DJGPP__) && 0 /* not needed */
01044   extern unsigned dj_end asm ("end");
01045   extern unsigned _stklen, __djgpp_stack_limit;
01046   #define STK_START()  (DWORD)&dj_end
01047 #endif
01048
01049 static unsigned get_frame_size (const char *x)
01050 {
01051   char y = 0;
01052   return (unsigned)(x - &y);
01053 }
01054
01055 static void is_in_stack_init (void)
01056 {
01057   char x = 0;
01058   stack_bottom = &x + get_frame_size(&x) * 2;
01059 }
01060
01061 BOOL is_in_stack (const void *ptr)
01062 {
01063   char  x;
01064   char *stack_top = &x;
01065   char *p         = (char*) ptr;
01066
01067   if (stack_top > stack_bottom)
01068      return (p > stack_bottom && p < stack_top);  /* stack grows up */
01069   return (p > stack_top && p < stack_bottom);     /* stack grows down */
01070 }
01071
01072 unsigned used_stack (void)
01073 {
01074   char  x;
01075   char *stack_top = &x;
01076
01077   if (stack_top > stack_bottom)
01078       return (stack_top - stack_bottom);
01079   return (stack_bottom - stack_top);
01080 }
01081
01082 /*
01083  * Test for valid read/write data address.
01084  * We assume linear address 'addr' is both readable and writeable.
01085  *
01086  * \note MingW (and other Win32 compilers?) puts 'const' data in
01087  *       read-only sections (.rdata). Detectible with IsBadWritePtr().
01088  */
01089 BOOL valid_addr (DWORD addr, unsigned len)
01090 {
01091 #if defined(WIN32)
01092   if (IsBadWritePtr((void*)addr,len) && IsBadReadPtr((const void*)addr,len))
01093      return (FALSE);
01094
01095 #else
01096   DWORD limit;
01097
01098   if (addr < 4096)  /* Valid in DOS4GW, but we never uses such address */
01099      return (FALSE);
01100
01101  /* In X32VM: DS != SS. addr may be in data or stack.
01102   */
01103 #if defined(DMC386) && (DOSX & X32VM) && 0  /* Doesn't work :-( */
01104   if (selector == MY_SS())
01105   {
01106     limit = get_ss_limit();
01107     if (addr < _x386_stacklow || addr + len >= limit)
01108        return (FALSE);
01109     if (limit > len && addr >= limit - len)  /* Segment wrap */
01110        return (FALSE);
01111   }
01112   else if (selector != MY_DS())
01113     return (FALSE);
01114 #endif
01115
01116 #if defined (__DJGPP__)
01117   limit = __dpmi_get_segment_limit (_my_ds());
01118 #elif defined (__HIGHC__)
01119   limit = _mwlsl (_mwgetcs());   /* DS & CS are aliases */
01120 #else
01121   limit = get_ds_limit();
01122 #endif
01123
01124   if (addr + len >= limit)
01125      return (FALSE);
01126   if (limit > len && addr >= limit - len)  /* Segment wrap */
01127      return (FALSE);
01128 #endif  /* WIN32 */
01129
01130   return (TRUE);
01131 }
01132 #endif  /* DOSX */
01133
01134
01135 /*
01136  * Pharlap/X32VM targets:   Get location of (or allocate a) transfer buffer.
01137  * DOS4GW/PowerPak targets: Allocate a small (1kB) transfer buffer.
01138  * djgpp/Win32:             Nothing special to do.
01139  */
01140 #if (DOSX & (PHARLAP|X32VM))
01141   REALPTR _watt_dosTbr;
01142   DWORD   _watt_dosTbSize = 0;
01143   static WORD rm_seg = 0;
01144
01145   static void free_selector (void)
01146   {
01147     if (rm_seg)
01148        _dx_real_free (rm_seg);
01149     rm_seg = 0;
01150     _watt_dosTbr = 0;
01151     _watt_dosTbSize = 0;
01152   }
01153
01154   static void setup_dos_xfer_buf (void)
01155   {
01156     FARPTR  dos_tbp;     /* pmode transfer-buffer address */
01157     REALPTR r2p_addr;    /* rmode to pmode call address */
01158     WORD    temp;
01159     int     len = 1024;  /* min size we need */
01160
01161     _dx_rmlink_get (&r2p_addr, &_watt_dosTbr,
01162                     &_watt_dosTbSize, &dos_tbp);
01163
01164     if (_watt_dosTbSize < len &&
01165         _dx_real_above(len, &rm_seg, &temp) == 0)
01166     {
01167       RP_SET (_watt_dosTbr, 0, rm_seg);
01168       _watt_dosTbSize = len;
01169       RUNDOWN_ADD (free_selector, 15);
01170     }
01171   }
01172
01173 #elif (DOSX & DOS4GW)
01174   WORD  _watt_dosTbSeg  = 0;   /* paragraph address of xfer buffer */
01175   WORD  _watt_dosTbSel  = 0;   /* selector for transfer buffer */
01176   DWORD _watt_dosTbSize = 0;   /* size of transfer buffer */
01177
01178   static void free_selector (void)
01179   {
01180     if (_watt_dosTbSel)
01181   #ifdef __CCDL__
01182        dpmi_free_selector (_watt_dosTbSel);
01183   #else
01184        dpmi_real_free (_watt_dosTbSel);
01185   #endif
01186     _watt_dosTbSel = 0;
01187   }
01188
01189   static void setup_dos_xfer_buf (void)
01190   {
01191     _watt_dosTbSize = 1024;
01192   #ifdef __CCDL__
01193     if (dpmi_alloc_real_memory (&_watt_dosTbSel, &_watt_dosTbSeg, _watt_dosTbSize) >= 0)
01194        _watt_dosTbSeg = 0;
01195   #else
01196     _watt_dosTbSeg = dpmi_real_malloc (_watt_dosTbSize, &_watt_dosTbSel);
01197   #endif
01198
01199     if (!_watt_dosTbSeg)
01200          _watt_dosTbSize = 0;
01201     else RUNDOWN_ADD (free_selector, 15);
01202   }
01203
01204 #elif (DOSX & POWERPAK)
01205   WORD  _watt_dos_ds;
01206   WORD  _watt_dosTbSeg  = 0;
01207   WORD  _watt_dosTbSel  = 0;
01208   DWORD _watt_dosTbr    = 0;
01209   DWORD _watt_dosTbSize = 0;
01210
01211   static void free_selector (void)
01212   {
01213     if (_watt_dosTbSel)
01214        dpmi_real_free (_watt_dosTbSel);
01215     _watt_dosTbSel = 0;
01216     if (_watt_dos_ds)
01217        dpmi_free_dos_selector (_watt_dos_ds);
01218     _watt_dos_ds = 0;
01219     _watt_dosTbr = 0;
01220   }
01221
01222   static void setup_dos_xfer_buf (void)
01223   {
01224     _watt_dos_ds = dpmi_create_dos_selector();
01225     if (!_watt_dos_ds)
01226     {
01227       fprintf (stderr, "Fatal: Failed to create DOS selector. "
01228                "DPMI error 0x%04X.\n", __dpmi_errno);
01229       exit (-1);
01230     }
01231     _watt_dosTbSize = 1024;
01232     _watt_dosTbSeg  = dpmi_real_malloc (_watt_dosTbSize, &_watt_dosTbSel);
01233     if (!_watt_dosTbSeg)
01234        _watt_dosTbSize = 0;
01235     else
01236     {
01237       RUNDOWN_ADD (free_selector, 15);
01238       _watt_dosTbr = (_watt_dosTbSeg << 16);
01239     }
01240   }
01241
01242 #elif (DOSX)
01243   static void setup_dos_xfer_buf (void)
01244   {
01245     /* no-op */
01246   }
01247 #endif
01248
01249
01250 #if defined(USE_BSD_API)
01251 /*
01252  * ffs() isn't needed yet, but could be used in select_s()
01253  *
01254  * Copyright (C) 1991, 1992 Free Software Foundation, Inc.
01255  * Contributed by Torbjorn Granlund (tege@sics.se).
01256  *
01257  * The GNU C Library is free software; you can redistribute it and/or
01258  * modify it under the terms of the GNU Library General Public License as
01259  * published by the Free Software Foundation; either version 2 of the
01260  * License, or (at your option) any later version.
01261  *
01262  * The GNU C Library is distributed in the hope that it will be useful,
01263  * but WITHOUT ANY WARRANTY; without even the implied warranty of
01264  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
01265  * Library General Public License for more details.
01266  *
01267  * You should have received a copy of the GNU Library General Public
01268  * License along with the GNU C Library; see the file COPYING.LIB.  If
01269  * not, write to the Free Software Foundation, Inc., 675 Mass Ave,
01270  * Cambridge, MA 02139, USA.
01271  */
01272
01273 /*
01274  * Returns the index of first bit set in 'i'. Counting from 1 at
01275  * "right side". Returns 0 if 'i' is 0.
01276  */
01277 int _w32_ffs (int i)
01278 {
01279   static BYTE table[] = {
01280     0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
01281     6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
01282     7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
01283     7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
01284     8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
01285     8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
01286     8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
01287     8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8
01288   };
01289   DWORD a, x;
01290
01291 #if (DOSX) && !defined(__LCC__) && !defined(BORLAND_WIN32)
01292   if (x86_type >= 3)
01293      return asm_ffs (i);  /* BSF requires 386+ */
01294 #endif
01295
01296   x = i & -i;
01297   a = x <= 0xFFFFUL ? (x <= 0xFF ? 0 : 8) : (x <= 0xFFFFFF ? 16 : 24);
01298   return (table[x >> a] + a);
01299 }
01300 #endif  /* USE_BSD_API */
01301
01302
01303 /*
01304  * Checks for bugs when compiling in large model C compiler
01305  *
01306  * Borland C uses a 4K stack by default. In all memory models the
01307  * stack grows down toward the heap.
01308  *
01309  * If you accidentally place _tcp_Socket onto the stack, then you
01310  * will have already used up that whole 4K and then some!
01311  *
01312  * In large model, this will mess up the data space in a major way
01313  * because the stack starts at SS:_stklen, or SS:1000, so you will
01314  * wrap the SP pointer back around to FFFE and start writing over
01315  * the far heap.  Yuck.
01316  *
01317  * In small model it usually doesn't kill your application because
01318  * you would have to be down to your last 4K of memory and this is
01319  * not as common.
01320  *
01321  * The solutions: declare your sockets as static, or put them on the
01322  * heap, or bump up your stack size by using the global special variable:
01323  *
01324  * unsigned _stklen = 16536;
01325  */
01326
01327 #if defined(__LARGE__)
01328 void watt_large_check (const void *sock, int size,
01329                        const char *file, unsigned line)
01330 {
01331   if ((unsigned)(FP_OFF(sock)) > (unsigned)(-size))
01332   {
01333 #if defined(USE_DEBUG)
01334     fprintf (stderr, "%s (%d): user stack size error", file, line);
01335 #else
01336     outsnl ("user stack size error");
01337     ARGSUSED (file);
01338     ARGSUSED (line);
01339 #endif
01340     exit (3);
01341   }
01342 }
01343 #endif
01344
01345
01346 #if defined(USE_DEBUG)
01347 #if defined(NOT_USED)
01348 int isbigendian (void)
01349 {
01350  /* From Harbison & Steele.
01351   */
01352   union {
01353     long l;
01354     char c[sizeof(long)];
01355   } u;
01356
01357   u.l = 1;
01358   return (u.c[sizeof(long)-1] == 1);
01359 }
01360
01364 #include <sys/packon.h>
01365
01366 struct cmd_block {
01367        BYTE len;
01368        char buf[256];
01369      };
01370
01371 #include <sys/packoff.h>
01372
01373 BOOL shell_exec (const char *cmd)
01374 {
01375   struct cmd_block blk;
01376   size_t i = sizeof(blk.buf)-1;
01377   IREGS  regs;
01378
01379   StrLcpy (blk.buf, cmd, i);
01380   i = min (i, strlen(blk.buf));
01381   blk.len    = i;
01382   blk.buf[i] = '\r';
01383
01384 #if (DOSX & DJGPP)
01385   regs.r_ds = __tb / 16;
01386   regs.r_si = __tb & 15;
01387   dosmemput (&blk, sizeof(blk), __tb);
01388
01389 #elif (DOSX == 0)
01390   regs.r_ds = FP_SEG (&blk);
01391   regs.r_si = FP_OFF (&blk);
01392 #endif
01393
01394   GEN_INTERRUPT (0x2E, &regs);
01395   return (regs.r_ax != 0xFFFF);
01396 }
01397 #endif  /* NOT_USED */
01398
01399
01400 #if defined(TEST_PROG)
01401 /*
01402  * Get/set DOS' memory allocation strategy.
01403  */
01404 BOOL get_mem_strat (BYTE *strat)
01405 {
01406   IREGS reg;
01407
01408   memset (&reg, 0, sizeof(reg));
01409   reg.r_ax = 0x5800;
01410   GEN_INTERRUPT (0x21, &reg);
01411   if (reg.r_flags & CARRY_BIT)
01412      return (FALSE);
01413   *strat = loBYTE (reg.r_ax);
01414   return (TRUE);
01415 }
01416
01417 BOOL set_mem_strat (BYTE strat)
01418 {
01419   IREGS reg;
01420
01421   memset (&reg, 0, sizeof(reg));
01422   reg.r_ax = 0x5801;
01423   reg.r_bx = strat;
01424   GEN_INTERRUPT (0x21, &reg);
01425   if (reg.r_flags & CARRY_BIT)
01426      return (FALSE);
01427   return (TRUE);
01428 }
01429 #endif  /* TEST_PROG */
01430
01434 #if (defined(_MSC_VER) || defined(__DMC__)) && (DOSX == 0)
01435 #undef intr
01436 void _w32_intr (int int_no, IREGS *reg)
01437 {
01438   union  REGS  r;
01439   struct SREGS s;
01440
01441   r.x.ax = reg->r_ax;
01442   r.x.bx = reg->r_bx;
01443   r.x.cx = reg->r_cx;
01444   r.x.dx = reg->r_dx;
01445   r.x.si = reg->r_si;
01446   r.x.di = reg->r_di;
01447   s.ds   = reg->r_ds;
01448   s.es   = reg->r_es;
01449   int86x (int_no, &r, &r, &s);
01450   reg->r_flags = r.x.cflag;
01451   reg->r_ax    = r.x.ax;
01452   reg->r_bx    = r.x.bx;
01453   reg->r_cx    = r.x.cx;
01454   reg->r_dx    = r.x.dx;
01455   reg->r_si    = r.x.si;
01456   reg->r_di    = r.x.di;
01457   reg->r_ds    = s.ds;
01458   reg->r_es    = s.es;
01459 }
01460 #endif
01461
01462
01463 #if defined(__BORLANDC__) && defined(__LARGE__)
01464 /*
01465  * Large model with option '-N' generates code like:
01466  *                      < .. standard prologue ...>
01467  *   39 26 00 00        cmp       DGROUP:__stklen,sp
01468  *   77 05              ja        Lxx
01469  *   9A 00 00 00 00     call      F_OVERFLOW@
01470  *                    Lxx:
01471  *
01472  * We need to find the address of F_OVERFLOW@ (it cannot be addressed
01473  * from C).
01474  */
01475 STATIC void stk_overflow (WORD ret_addr)
01476 {
01477   static WORD cs, ip;
01478   static WORD stk[128];
01479
01480   cs = *(WORD*) (&ret_addr-1);
01481   ip = *(WORD*) (&ret_addr-2);
01482
01483   _SS = FP_SEG (stk);
01484   _SP = (WORD) &stk [DIM(stk)-1];
01485   _stklen = 0x7FFF;
01486   _watt_fatal_error = TRUE;
01487   fprintf (stderr, "\nStack overflow at %04X:%04X!\n", cs, ip);
01488   _eth_release();
01489   _exit (-1);
01490 }
01491
01492 STATIC int setup_stk_check (void)
01493 {
01494   BYTE  sign[] = { 0x39, 0x26, 0,0, 0x77, 5, 0x9A };
01495   BYTE *p      = (BYTE*) _eth_arrived;
01496   int   i;
01497
01498   *(WORD*)&sign[2] = FP_OFF (&_stklen);
01499   for (i = 0; i < 10; i++, p++)
01500       if (!memcmp(p, sign, sizeof(sign)))
01501       {
01502         DWORD addr = *(DWORD*) (p + sizeof(sign));
01503         BYTE *patch;
01504
01505      /* printf ("F_OVERFLOW@ at %04X:%04X\n", (WORD)(addr >> 16), (WORD)addr); */
01506         patch = (BYTE*) addr;
01507         *patch++ = 0x2E;
01508         *patch++ = 0xFF;
01509         *patch++ = 0x2E;
01510         *(WORD*)patch = 6 - 1 + (WORD)addr;  /* relocation of [where] */
01511         patch += 2;
01512         *(WORD*)patch = FP_OFF (stk_overflow);
01513         patch += 2;
01514         *(WORD*)patch = FP_SEG (stk_overflow);
01515
01516         /*
01517          *  0001                    F_OVERFLOW@:
01518          *  0001  2E: FF 2E 0006r     jmp dword ptr cs:[where]
01519          *  0006  ????????            where dd ?
01520          */
01521 #if 0
01522         printf ("test_stk_check() at CS:IP %04X:%04X\n",
01523                 _CS, FP_OFF(test_stk_check));
01524         _stklen = 10;
01525         test_stk_check();
01526 #endif
01527         return (1);
01528       }
01529   return (0);
01530 }
01531
01532 #elif defined(__BORLANDC__) && defined(__SMALL__)
01533 /*
01534  * Small model with option '-N' generates code like:
01535  *                      < .. standard prologue ...>
01536  *   39 26 00 00        cmp       ___brklvl,sp
01537  *   72 03              jb        L$1
01538  *   E8 00 00           call      N_OVERFLOW@
01539  *                    L$1:
01540  *
01541  * We need to find the address of N_OVERFLOW@ (it cannot be addressed
01542  * from C). It should be the same code as in large model.
01543  */
01544 extern int __brklvl;
01545
01546 static void stk_overflow (UINT ret_addr)
01547 {
01548   static WORD cs, ip;
01549   static WORD stk[128];
01550
01551   cs = _CS;
01552   ip = *(WORD*) (&ret_addr-1);
01553
01554   _SS = FP_SEG (stk);
01555   _SP = (WORD) &stk [DIM(stk)-1];
01556
01557   _stklen = 0x7FFF;
01558   _watt_fatal_error = TRUE;
01559   fprintf (stderr, "\nStack overflow at %04X:%04X!\n", cs, ip);
01560   _eth_release();
01561   _exit (1);     /* do minimal work, no rundown_run() */
01562 }
01563
01564 static int stk_check_setup (void)
01565 {
01566   BYTE  sign[] = { 0x39, 0x26, 0,0, 0x72, 3, 0xE8 };
01567   BYTE *p      = (BYTE*) _eth_arrived;
01568   int   i;
01569
01570   *(WORD*)&sign[2] = FP_OFF (&__brklvl);
01571   for (i = 0; i < 10; i++, p++)
01572       if (!memcmp(p, sign, sizeof(sign)))
01573       {
01574         BYTE *addr = *(BYTE*)(++p);
01575         *addr = (BYTE*) stk_overflow;
01576         return (1);
01577       }
01578   return (0);
01579 }
01580
01581 #elif defined(WATCOM386) && !defined(WIN32)
01582 /*
01583  * For tracking down stack overflow bugs.
01584  * Stack checker __CHK is pascal-style with stack-size at [esp+4].
01585  * __CHK calls __STK which in turn may call _fatal_runtime_error()
01586  *
01587  * Compiling with stack-checking on, this prologue is in every function:
01588  *  (*) push <stack size needed>   <- 68h, dword size at EIP-9
01589  *      call __CHK                 <- 5 bytes
01590  *      ...                        <- extracted EIP of return
01591  */
01592 static void stk_overflow (WORD cs, UINT eip)
01593 {
01594   UINT size = *(UINT*)(eip-9);
01595
01596   eip -= (UINT)&__begtext - 9; /* print .map-file address of (*) */
01597
01598   _watt_fatal_error = TRUE;
01599   fprintf (stderr, "Stack overflow (%u bytes needed) detected at %X:%08lXh\n",
01600            size, cs, (DWORD)eip);
01601   _eth_release();
01602   _exit (1);     /* do minimal work, no rundown_run() */
01603 }
01604
01605 void FATAL_HANDLER (UINT stk)
01606 {
01607 #if defined(__SMALL__)
01608   _x386_stacklow = stk + 2;
01609   stk_overflow (MY_CS(), *(DWORD*)(&stk+1));
01610
01611 #elif defined(__LARGE__)
01612   _x386_stacklow = stk + 4;
01613   stk_overflow (*(WORD*)(&stk+1), *(WORD*)(&stk+2)); /* far-call */
01614
01615 #else     /* wcc386/DOS */
01616   _x386_stacklow = stk + 4;
01617   stk_overflow (MY_CS(), *(WORD*)(&stk+1));
01618 #endif
01619 }
01620
01621 #elif defined(_MSC_VER) && defined(__LARGE__)
01622 static void stk_overflow (void _far *where)
01623 {
01624   fprintf (stderr, "Stack overflow detected at %04X:%04Xh\n",
01625            FP_SEG(where), FP_OFF(where));
01626   _eth_release();
01627   _exit (1);
01628 }
01629 #endif
01630 #endif  /* USE_DEBUG */
01631
01632 /*
01633  * Functions needed for "gcc -O0". These are inlined on -O1 or above.
01634  */
01635 #if defined(__GNUC__)
01636 #undef __SYS_SWAP_BYTES_H
01637 #undef _w32_SYS_SWAP_BYTES_H
01638 #undef _w32_CPUMODEL_H
01639 #undef _w32_MISC_H
01640 #undef _w32_IOPORT_H
01641 #undef BEEP
01642 #undef WIN_ASSERT
01643
01644 #define extern
01645 #define __inline__
01646 #define __inline
01647
01648 #if defined(__MINGW32__) || defined(__CYGWIN__)
01649   #undef intel
01650   #undef intel16
01651   #define __NO_INLINE__  /* emulate -O0 */
01652 #endif
01653
01654 #include <sys/swap.h>
01655 #include "misc.h"
01656 #include "cpumodel.h"
01657
01658 #if defined(__EMX__)
01659 #include "ioport.h"
01660 #endif
01661
01662 #endif  /* __GNUC__ */
01663
01664
01665 #if defined(TEST_PROG)
01666
01667 void foo_10 (void) { puts ("I'm foo_10()"); }
01668 void foo_20 (void) { puts ("I'm foo_20()"); }
01669 void foo_30 (void) { puts ("I'm foo_30()"); }
01670 void foo_40 (void) { puts ("I'm foo_40()"); }
01671 void foo_50 (void) { puts ("I'm foo_50()"); }
01672 void foo_60 (void) { puts ("I'm foo_60()"); }
01673 void foo_70 (void) { puts ("I'm foo_70()"); }
01674
01675 int main (void)
01676 {
01677   BYTE strat;
01678
01679   printf ("DOS memory allocation strategy: ");
01680   if (!get_mem_strat(&strat))
01681        puts ("failed");
01682   else printf ("0x%02X\n", strat);
01683
01684   printf ("Setting \"low memory best fit\" ");
01685   if (!set_mem_strat(1))
01686        puts ("failed");
01687   else puts ("okay");
01688
01689   set_mem_strat (strat);
01690
01691   RUNDOWN_ADD (foo_40, 40);
01692   RUNDOWN_ADD (foo_10, 10);
01693   RUNDOWN_ADD (foo_60, 60);
01694   RUNDOWN_ADD (foo_30, 30);
01695   RUNDOWN_ADD (foo_20, 20);
01696   RUNDOWN_ADD (foo_50, 50);
01697   RUNDOWN_ADD (foo_70, 70);
01698   debug_on = 2;
01699   rundown_run();
01700   return (0);
01701 }
01702 #endif
01703
Generated on Wed Jan 25 15:42:35 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/MISC.H Source File

SRC/MISC.H

Go to the documentation of this file.
00001
00003 #ifndef _w32_MISC_H
00004 #define _w32_MISC_H
00005
00006 #ifndef __SYS_SWAP_BYTES_H
00007 #include <sys/swap.h>       /* intel() etc. */
00008 #endif
00009
00010 #ifndef __SYS_WTIME_H
00011 #include <sys/wtime.h>      /* struct timeval */
00012 #endif
00013
00014 #if defined(__DJGPP__) || defined(__HIGHC__) || defined(__WATCOMC__) || \
00015     defined(__DMC__)
00016   #undef _WIN32       /* Needed for __DMC__ */
00017   #include <unistd.h>
00018 #endif
00019
00020 #if defined(__LCC__) && !defined(W32_LCC_INTRINSICS_INCLUDED)
00021   #include <intrinsics.h>
00022 #elif defined(__POCC__) && 0
00023   #include <intrin.h>
00024 #endif
00025
00026 /*
00027  * In misc.c
00028  *
00029  * Protect internal symbols with a namespace
00030  */
00031 #define init_misc       NAMESPACE (init_misc)
00032 #define Random          NAMESPACE (Random)
00033 #define RandomWait      NAMESPACE (RandomWait)
00034 #define Wait            NAMESPACE (Wait)
00035 #define valid_addr      NAMESPACE (valid_addr)
00036 #define is_in_stack     NAMESPACE (is_in_stack)
00037 #define used_stack      NAMESPACE (used_stack)
00038 #define os_yield        NAMESPACE (os_yield)
00039 #define hex_chars_lower NAMESPACE (hex_chars_lower)
00040 #define hex_chars_upper NAMESPACE (hex_chars_upper)
00041 #define win32_dos_box   NAMESPACE (win32_dos_box)
00042 #define get_day_num     NAMESPACE (get_day_num)
00043 #define dword_str       NAMESPACE (dword_str)
00044 #define shell_exec      NAMESPACE (shell_exec)
00045 #define get_mem_strat   NAMESPACE (get_mem_strat)
00046 #define set_mem_strat   NAMESPACE (set_mem_strat)
00047 #define rundown_add     NAMESPACE (rundown_add)
00048 #define rundown_run     NAMESPACE (rundown_run)
00049 #define rundown_dump    NAMESPACE (rundown_dump)
00050 #define assert_fail     NAMESPACE (assert_fail)
00051 #define memdbg_init     NAMESPACE (memdbg_init)
00052 #define fopen_excl      NAMESPACE (fopen_excl)
00053
00054 #if !defined(SEARCH_LIST_DEFINED)
00055   #define SEARCH_LIST_DEFINED
00056   struct search_list {
00057          DWORD       type;
00058          const char *name;
00059        };
00060 #endif
00061
00062 #define DO_FREE(x)  do {           \
00063                       if (x) {     \
00064                          free (x); \
00065                          x = NULL; \
00066                       }            \
00067                     } while (0)
00068
00069 #if defined(WIN32)
00070   #define SOCK_ERRNO(err)  WSASetLastError (err)
00071 #else
00072   #define SOCK_ERRNO(err)  errno = _w32_errno = err
00073 #endif
00074
00075
00076 #if !defined(__DJGPP__)
00077   W32_DATA int __bss_count;
00078 #endif
00079
00080 W32_DATA BOOL     win32_dos_box;
00081 W32_DATA BOOL    _watt_fatal_error;
00082 W32_DATA WORD    _watt_os_ver;
00083 W32_DATA char    _watt_assert_buf[256];
00084
00085 extern const char hex_chars_lower[];
00086 extern const char hex_chars_upper[];
00087
00088 W32_FUNC void     init_misc    (void);
00089 W32_FUNC unsigned Random       (unsigned a, unsigned b);
00090 W32_FUNC void     RandomWait   (unsigned msec_a, unsigned msec_b);
00091 W32_FUNC void     Wait         (unsigned msec);
00092 W32_FUNC BOOL     valid_addr   (DWORD addr, unsigned len);
00093 W32_FUNC BOOL     is_in_stack  (const void *ptr);
00094 W32_FUNC unsigned used_stack   (void);
00095
00096 W32_FUNC void     os_yield     (void);
00097 W32_FUNC BOOL     watt_kbhit   (void);
00098
00099 extern   DWORD    get_day_num  (void);
00100 extern   BOOL     shell_exec   (const char *cmd);
00101 extern   BOOL     get_mem_strat(BYTE *strat);
00102 extern   BOOL     set_mem_strat(BYTE strat);
00103 extern   void     memdbg_init  (void);
00104 extern   int      rundown_add  (void (*func)(void), const char *name,
00105                                 int order, const char *file, unsigned line);
00106 extern   void     rundown_run  (void);
00107 extern   void     rundown_dump (void);
00108 extern   FILE    *fopen_excl   (const char *file, const char *mode);
00109
00110 extern const char *dos_extender_name (void);
00111 extern void assert_fail (const char *file, unsigned line, const char *what);
00112
00113 extern const char *dword_str (DWORD val);
00114
00115 #define RUNDOWN_ADD(func,order) \
00116         rundown_add ((void(*)(void))func, #func, order, __FILE__, __LINE__)
00117
00118 /*
00119  * Yielding while waiting on network reduces CPU-loading.
00120  */
00121 #if (DOSX & (DJGPP|DOS4GW|PHARLAP|X32VM|WINWATT))
00122   #define WATT_YIELD()   os_yield()  /* includes kbhit() for non-djgpp */
00123 #else
00124   #define WATT_YIELD()   watt_kbhit()
00125 #endif
00126
00127 #if defined(USE_DEBUG)
00128   #define list_lookup    NAMESPACE (list_lookup)
00129   #define MAC_address    NAMESPACE (MAC_address)
00130   #define unfinished     NAMESPACE (unfinished)
00131
00132   extern const char *list_lookup (DWORD, const struct search_list *, int);
00133   extern const char *MAC_address (const void *addr);
00134   extern void        unfinished (const char *func, const char *file, unsigned line);
00135
00136   #define UNFINISHED()  unfinished (__FUNCTION__, __FILE__, __LINE__)
00137 #else
00138   #define UNFINISHED()  ((void)0)
00139 #endif
00140
00141 #if defined(__LARGE__)
00142   extern void watt_large_check (const void *sock, int size,
00143                                 const char *file, unsigned line);
00144   #define WATT_LARGE_CHECK(sock, size) \
00145           watt_large_check(sock, size, __FILE__, __LINE__)
00146 #else
00147   #define WATT_LARGE_CHECK(sock, size)  ((void)0)
00148 #endif
00149
00150 #if defined(USE_DEBUG) && !defined(NDEBUG)
00151   #define WATT_ASSERT(x)  do { \
00152                             if (!(x)) \
00153                                assert_fail (__FILE__, __LINE__, #x); \
00154                           } while (0)
00155 #else
00156   #define WATT_ASSERT(x)  ((void)0)
00157 #endif
00158
00159
00160 #if defined(WIN32)
00161   /*
00162    * In winmisc.c
00163    */
00164   #define init_winmisc       NAMESPACE (init_winmisc)
00165   #define win_strerror       NAMESPACE (win_strerror)
00166   #define assert_fail_win    NAMESPACE (assert_fail_win)
00167
00168   #define WinDnsQueryA4      NAMESPACE (WinDnsQueryA4)
00169   #define WinDnsQueryA6      NAMESPACE (WinDnsQueryA6)
00170   #define WinDnsQueryPTR4    NAMESPACE (WinDnsQueryPTR4)
00171   #define WinDnsQueryPTR6    NAMESPACE (WinDnsQueryPTR6)
00172   #define WinDnsCachePut_A4  NAMESPACE (WinDnsCachePut_A4)
00173   #define WinDnsCachePut_A6  NAMESPACE (WinDnsCachePut_A6)
00174
00175   extern BOOL  _watt_is_win9x;
00176
00177   extern BOOL  init_winmisc    (void);
00178   extern char *win_strerror    (DWORD err);
00179   extern void  assert_fail_win (const char *file, unsigned line,
00180                                 const char *what);
00181
00182   extern BOOL  WinDnsQuery_A4    (const char *name, DWORD *ip4);
00183   extern BOOL  WinDnsQuery_A6    (const char *name, void *ip6);
00184   extern BOOL  WinDnsQuery_PTR4  (DWORD ip4, char *name, size_t size);
00185   extern BOOL  WinDnsQuery_PTR6  (const void *ip6, char *name, size_t size);
00186   extern BOOL  WinDnsCachePut_A4 (const char *name, DWORD ip4);
00187   extern BOOL  WinDnsCachePut_A6 (const char *name, const void *ip6);
00188
00189   #if defined(USE_DEBUG) && !defined(NDEBUG)
00190     #define WIN_ASSERT(x)   do {        \
00191                               if (!(x)) \
00192                                  assert_fail_win (__FILE__, __LINE__, #x); \
00193                             } while (0)
00194   #else
00195     #define WIN_ASSERT(x)  ((void)0)
00196   #endif
00197 #endif
00198
00199
00200 #if defined(HAVE_UINT64)
00201   /*
00202    * Format for printing 64-bit types. E.g. "%10"S64_FMT
00203    */
00204   #if defined(_MSC_VER) || defined(_MSC_EXTENSIONS) || defined(__WATCOMC__) || \
00205       defined(__LCC__) || defined(__BORLANDC__)
00206     #define S64_FMT        "I64d"
00207     #define U64_FMT        "I64u"
00208     #define S64_SUFFIX(x)  (x##i64)
00209     #define U64_SUFFIX(x)  (x##Ui64)
00210   #else
00211     #define S64_FMT        "Ld"
00212     #define U64_FMT        "Lu"
00213     #define S64_SUFFIX(x)  (x##LL)
00214     #define U64_SUFFIX(x)  (x##ULL)
00215   #endif
00216 #endif
00217
00218
00219
00220 /*
00221  * In pc_cbrk.c
00222  */
00223 W32_DATA WORD         _watt_handle_cbreak;
00224 W32_DATA volatile int _watt_cbroke;
00225
00226 W32_FUNC int           tcp_cbreak (int mode);
00227 extern   int           set_cbreak (int want_brk);
00228 extern   void MS_CDECL sig_handler_watt (int sig);
00229
00230 #define NEW_BREAK_MODE(old,new) \
00231         old = _watt_handle_cbreak, \
00232         _watt_handle_cbreak = new,  /* enable special interrupt mode */ \
00233         _watt_cbroke = 0
00234
00235 #define OLD_BREAK_MODE(old) \
00236         _watt_cbroke = 0,   /* always clean up */ \
00237         _watt_handle_cbreak = old
00238
00239
00240 /*
00241  * In country.c (no longer used. Maybe use with IDNA code?)
00242  */
00243 #define GetCountryCode  NAMESPACE (GetCountryCode)
00244 #define GetCodePage     NAMESPACE (GetCodePage)
00245
00246 extern int GetCountryCode (void);
00247 extern int GetCodePage (void);
00248
00249
00250 #if !defined(WIN32)
00251   /*
00252    * In crit.c; Sets up a critical error handler.
00253    * No longer used.
00254    */
00255   #define CRIT_VECT      0x24
00256   #define int24_init     NAMESPACE (int24_init)
00257   #define int24_restore  NAMESPACE (int24_restore)
00258
00259   extern void int24_init (void);
00260   extern void int24_restore (void);
00261
00262   /*
00263    * In qmsg.c
00264    */
00265   #define dbg_colour    NAMESPACE (dbg_colour)
00266   #define dbg_scrpos    NAMESPACE (dbg_scrpos)
00267   #define dbg_scrstart  NAMESPACE (dbg_scrstart)
00268   #define dputch        NAMESPACE (dputch)
00269   #define dmsg          NAMESPACE (dmsg)
00270   #define dhex1int      NAMESPACE (dhex1int)
00271   #define dhex2int      NAMESPACE (dhex2int)
00272   #define dhex4int      NAMESPACE (dhex4int)
00273   #define dhex8int      NAMESPACE (dhex8int)
00274
00275   extern BYTE dbg_colour;
00276   extern WORD dbg_scrpos;
00277   extern WORD dbg_scrstart;
00278
00279   extern void dputch   (char x);
00280   extern void dmsg     (const char *s);
00281   extern void dhex1int (int x);
00282   extern void dhex2int (int x);
00283   extern void dhex4int (int x);
00284   extern void dhex8int (DWORD x);
00285
00286 #endif
00287
00288
00289 /*
00290  * In version.c
00291  */
00292 W32_DATA const char *wattcpCopyright;
00293 W32_FUNC const char *wattcpVersion (void);
00294 W32_FUNC const char *wattcpCapabilities (void);
00295
00296
00297 /*
00298  * In crc.c
00299  */
00300 #define crc_init   NAMESPACE (crc_init)
00301 #define crc_bytes  NAMESPACE (crc_bytes)
00302
00303 extern BOOL  crc_init  (void);
00304 extern DWORD crc_bytes (const char *buf, unsigned len);
00305
00306 /*
00307  * In neterr.c
00308  */
00309 #define short_strerror      NAMESPACE (short_strerror)
00310 #define pull_neterr_module  NAMESPACE (pull_neterr_module)
00311
00312 extern int         pull_neterr_module;
00313 extern const char *short_strerror (int errnum);
00314
00315
00316 /*
00317  * IREGS structures for pkt_api_entry() etc.
00318  * Defines to simplify issuing real-mode interrupts
00319  */
00320 #if (DOSX & PHARLAP)
00321   #define IREGS      SWI_REGS     /* in Pharlap's <pharlap.h> */
00322   #define r_flags    flags
00323   #define r_ax       eax
00324   #define r_bx       ebx
00325   #define r_dx       edx
00326   #define r_cx       ecx
00327   #define r_si       esi
00328   #define r_di       edi
00329   #define r_ds       ds
00330   #define r_es       es
00331   #define r_fs       fs
00332   #define r_gs       gs
00333
00334 #elif (DOSX & DJGPP)
00335   #define IREGS      __dpmi_regs  /* in <dpmi.h> */
00336   #define r_flags    x.flags
00337   #define r_ax       d.eax
00338   #define r_bx       d.ebx
00339   #define r_dx       d.edx
00340   #define r_cx       d.ecx
00341   #define r_si       d.esi
00342   #define r_di       d.edi
00343   #define r_ip       x.ip
00344   #define r_cs       x.cs
00345   #define r_ds       x.ds
00346   #define r_es       x.es
00347   #define r_fs       x.fs
00348   #define r_gs       x.gs
00349   #define r_ss       x.ss
00350   #define r_sp       x.sp
00351
00352 #elif (DOSX & X32VM)
00353   #define IREGS      SWI_REGS           /* in "x32vm.h" */
00354
00355 #elif defined(__CCDL__)
00356   #define IREGS      union _dpmi_regs_  /* in <dpmi.h> */
00357   #define r_flags    h.flags
00358   #define r_ax       d.eax
00359   #define r_bx       d.ebx
00360   #define r_dx       d.edx
00361   #define r_cx       d.ecx
00362   #define r_si       d.esi
00363   #define r_di       d.edi
00364   #define r_ds       h.ds
00365   #define r_es       h.es
00366   #define r_fs       h.fs
00367   #define r_gs       h.gs
00368
00369 #elif (DOSX & (DOS4GW|POWERPAK))
00370   typedef struct DPMI_regs {
00371           DWORD  r_di;
00372           DWORD  r_si;
00373           DWORD  r_bp;
00374           DWORD  reserved;
00375           DWORD  r_bx;
00376           DWORD  r_dx;
00377           DWORD  r_cx;
00378           DWORD  r_ax;
00379           WORD   r_flags;
00380           WORD   r_es, r_ds, r_fs, r_gs;
00381           WORD   r_ip, r_cs, r_sp, r_ss;
00382         } IREGS;
00383
00384 #elif (DOSX & WINWATT)
00385
00386 #else  /* r-mode targets */
00387
00388   /* IREGS must have same layout and size as Borland's 'struct REGPACK'
00389    * and Watcom's 'union REGPACK'. This is checked in `check_reg_struct()'.
00390    */
00391   #include <sys/packon.h>
00392
00393   typedef struct IREGS {
00394           WORD  r_ax, r_bx, r_cx, r_dx, r_bp;
00395           WORD  r_si, r_di, r_ds, r_es, r_flags;
00396         } IREGS;
00397
00398   #include <sys/packoff.h>
00399
00400   #if (defined(_MSC_VER) || defined(__DMC__)) && (DOSX == 0)
00401     #define intr NAMESPACE (intr)
00402     extern void intr (int int_no, IREGS *regs);
00403   #endif
00404 #endif
00405
00406 #define CARRY_BIT  1   /* LSB in r_flags */
00407
00408
00409 /* Macro to ease gneration of real-mode interrupts.
00410  * `_r' should be `IREGS'.
00411  */
00412 #if (DOSX & DJGPP)
00413   #define GEN_INTERRUPT(_i,_r)   __dpmi_int ((int)(_i), _r)
00414
00415 #elif (DOSX & (PHARLAP|X32VM))
00416   #define GEN_INTERRUPT(_i,_r)   _dx_real_int ((UINT)(_i), _r)
00417
00418 #elif defined(__CCDL__)
00419   #define GEN_INTERRUPT(_i,_r)   dpmi_simulate_real_interrupt (_i, _r)
00420
00421 #elif (DOSX & (DOS4GW|POWERPAK))
00422   #define GEN_INTERRUPT(_i,_r)   dpmi_real_interrupt ((_i), _r)
00423
00424 #elif (DOSX == 0)
00425   #if defined(_MSC_VER) || defined(__DMC__)
00426     #define GEN_INTERRUPT(_i,_r)  intr ((int)(_i), _r) /* our own version */
00427
00428   #elif defined(__WATCOMC__)
00429     #define GEN_INTERRUPT(_i,_r)  intr ((int)(_i), (union REGPACK*)(_r))
00430
00431   #else
00432     #define GEN_INTERRUPT(_i,_r)  intr ((int)(_i), (struct REGPACK*)(_r))
00433   #endif
00434
00435 #elif (DOSX & WINWATT)
00436   /* No interrupts on Win32 */
00437
00438 #else
00439   #error Help, unknown target.
00440 #endif
00441
00442
00443 /*
00444  * Fixes for Quick-C and Digital Mars to allow an address as lvalue
00445  * in FP_SEG/OFF macros (only used in wdpmi.c)
00446  */
00447 #if (!DOSX)
00448   #if defined(_MSC_VER)
00449   /*#pragma warning (disable:4759) */
00450     #undef  FP_SEG
00451     #undef  FP_OFF
00452     #define FP_SEG(p) ((unsigned)(_segment)(void _far *)(p))
00453     #define FP_OFF(p) ((unsigned)(p))
00454
00455   #elif defined(__DMC__)
00456     #undef  FP_SEG
00457     #undef  FP_OFF
00458     #define FP_SEG(p) ((unsigned)((DWORD)(void _far*)(p) >> 16))
00459     #define FP_OFF(p) ((unsigned)(p))
00460   #endif
00461
00462 #elif defined(BORLAND386)
00463   #undef  FP_SEG
00464   #undef  FP_OFF
00465   #define FP_SEG(p)   _DS  /* segment of something is always our DS */
00466   #define FP_OFF(p)   (DWORD)(p)
00467
00468 #elif (defined(DMC386) || defined(MSC386)) && !defined(WIN32)
00469   #undef  FP_SEG
00470   #undef  FP_OFF
00471   #define FP_SEG(p)   ((unsigned)((DWORD)(void _far*)(p) >> 16))
00472   #define FP_OFF(p)   ((unsigned)(p))
00473 #endif
00474
00475
00476 #if (defined(MSC386) || defined(__HIGHC__)) && !defined(WIN32)
00477   #include <pldos32.h>
00478   #define dosdate_t  _dosdate_t
00479   #define dostime_t  _dostime_t
00480 #endif
00481
00482 #if defined(__DMC__) && !defined(WIN32)
00483   #define dosdate_t  dos_date_t
00484   #define dostime_t  dos_time_t
00485 #endif
00486
00487
00488 /*
00489  * The Watcom STACK_SET() function is from Dan Kegel's RARP implementation
00490  */
00491 #if defined(__WATCOMC__) && !defined(__386__)  /* 16-bit Watcom */
00492   extern void STACK_SET (void far *stack);
00493   #pragma aux STACK_SET = \
00494           "mov  ax, ss"   \
00495           "mov  bx, sp"   \
00496           "mov  ss, dx"   \
00497           "mov  sp, si"   \
00498           "push ax"       \
00499           "push bx"       \
00500           parm [dx si]    \
00501           modify [ax bx];
00502
00503   extern void STACK_RESTORE (void);
00504   #pragma aux STACK_RESTORE = \
00505           "pop bx"            \
00506           "pop ax"            \
00507           "mov ss, ax"        \
00508           "mov sp, bx"        \
00509           modify [ax bx];
00510
00511   extern void PUSHF_CLI (void);
00512   #pragma aux PUSHF_CLI = \
00513           "pushf"         \
00514           "cli";
00515
00516   extern void POPF (void);
00517   #pragma aux POPF = \
00518           "popf";
00519
00520 #elif defined(WATCOM386)       /* 32-bit Watcom targets */
00521   extern void STACK_SET (void *stack);
00522   #pragma aux STACK_SET =  \
00523           "mov  ax, ss"    \
00524           "mov  ebx, esp"  \
00525           "mov  cx, ds"    \
00526           "mov  ss, cx"    \
00527           "mov  esp, esi"  \
00528           "push eax"       \
00529           "push ebx"       \
00530           parm [esi]       \
00531           modify [eax ebx ecx];
00532
00533   extern void STACK_RESTORE (void);
00534   #pragma aux STACK_RESTORE = \
00535           "lss esp, [esp]";
00536
00537   extern void PUSHF_CLI (void);
00538   #pragma aux PUSHF_CLI = \
00539           "pushfd"        \
00540           "cli";
00541
00542   extern void POPF (void);
00543   #pragma aux POPF = \
00544           "popfd";
00545
00546   extern WORD watcom_MY_CS (void);
00547   #pragma aux watcom_MY_CS = \
00548           "mov ax, cs"       \
00549           modify [ax];
00550
00551   extern WORD watcom_MY_DS(void);
00552   #pragma aux watcom_MY_DS = \
00553           "mov ax, ds"       \
00554           modify [ax];
00555
00556   extern DWORD GET_LIMIT (WORD sel);
00557   #pragma aux GET_LIMIT = \
00558           ".386p"         \
00559           "lsl eax, eax"  \
00560           parm [eax];
00561
00562   #define get_cs_limit() GET_LIMIT (watcom_MY_CS())
00563   #define get_ds_limit() GET_LIMIT (watcom_MY_DS())
00564
00565 #elif defined(BORLAND386) || defined(DMC386) || defined(MSC386)
00566   #define STACK_SET(stk)  __asm { mov  ax, ss;   \
00567                                   mov  ebx, esp; \
00568                                   mov  cx, ds;   \
00569                                   mov  ss, cx;   \
00570                                   mov  esp, stk; \
00571                                   push eax;      \
00572                                   push ebx       \
00573                                 }
00574
00575   #define STACK_RESTORE() __asm lss esp, [esp]
00576   #define PUSHF_CLI()     __emit__ (0x9C,0xFA)  /* pushfd; cli */
00577   #define POPF()          __emit__ (0x9D)       /* popfd */
00578
00579   extern DWORD get_ds_limit (void);
00580   extern DWORD get_cs_limit (void);
00581   extern DWORD get_ss_limit (void);  /* only needed for X32 */
00582
00583 #elif defined(__CCDL__)
00584   #define STACK_SET(stk)  asm { mov  ax, ss;   \
00585                                 mov  ebx, esp; \
00586                                 mov  cx, ds;   \
00587                                 mov  ss, cx;   \
00588                                 mov  esp, stk; \
00589                                 push eax;      \
00590                                 push ebx       \
00591                               }
00592
00593   #define STACK_RESTORE() asm lss esp, [esp]
00594   #define PUSHF_CLI()     asm { pushfd; cli }
00595   #define POPF()          asm popfd
00596
00597   extern DWORD get_ds_limit (void);
00598   extern DWORD get_cs_limit (void);
00599
00600 #elif defined(__HIGHC__)
00601   #define PUSHF_CLI()     _inline (0x9C,0xFA)  /* pushfd; cli */
00602   #define POPF()          _inline (0x9D)       /* popfd */
00603
00604 #elif defined(__GNUC__)
00605   #define PUSHF_CLI()     __asm__ __volatile__ ("pushfl; cli" ::: "memory")
00606   #define POPF()          __asm__ __volatile__ ("popfl"       ::: "memory")
00607
00608 #elif defined(__SMALL16__) || defined(__LARGE__)
00609   #if defined(__BORLANDC__) /* prevent spawning tasm.exe */
00610     #define PUSHF_CLI()   __emit__ (0x9C,0xFA)
00611     #define POPF()        __emit__ (0x9D)
00612
00613   #elif defined(__DMC__) || (defined(_MSC_VER) && !defined(NO_INLINE_ASM))
00614     #define PUSHF_CLI()   __asm pushf; \
00615                           __asm cli
00616     #define POPF()        __asm popf
00617   #endif
00618 #endif
00619
00620 #if !defined(__WATCOMC__)
00621   #ifndef PUSHF_CLI
00622   #define PUSHF_CLI() ((void)0)
00623   #endif
00624
00625   #ifndef POPF
00626   #define POPF()      ((void)0)
00627   #endif
00628 #endif
00629
00630
00631 #define BEEP_FREQ   7000
00632 #define BEEP_MSEC   1
00633
00634 #if defined(WIN32)
00635   #define BEEP()    MessageBeep (MB_OK)
00636
00637 #elif defined(_MSC_VER)
00638   #define BEEP()    ((void)0) /* doesn't even have delay() :-< */
00639
00640 #elif defined(__DMC__)
00641   #define BEEP()    sound_note (BEEP_FREQ, BEEP_MSEC)
00642
00643 #elif defined(__DJGPP__)
00644   #define BEEP()    do { \
00645                       sound (BEEP_FREQ); \
00646   /* delay() don't */ usleep (1000*BEEP_MSEC); \
00647   /* work under NT */ nosound(); \
00648                     } while (0)
00649
00650 #elif defined(__CCDL__)
00651   #define BEEP()    do { \
00652                       _sound (BEEP_FREQ); \
00653                       _delay (BEEP_MSEC); \
00654                       _nosound(); \
00655                     } while (0)
00656 #else
00657   #define BEEP()    do { \
00658                       sound (BEEP_FREQ); \
00659                       delay (BEEP_MSEC); \
00660                       nosound(); \
00661                     } while (0)
00662 #endif
00663
00664 /*
00665  * Defines for real/pmode-mode interrupt handlers (crit.c/netback.c/pcintr.c)
00666  */
00667 #if !defined(INTR_PROTOTYPE)
00668 #if (DOSX == 0)
00669   #if (__WATCOMC__ >= 1200)   /* OpenWatcom 1.0+ */
00670     #define INTR_PROTOTYPE  void interrupt far
00671     typedef INTR_PROTOTYPE (*W32_IntrHandler)();
00672
00673   #elif defined(__TURBOC__)
00674     #define INTR_PROTOTYPE  void cdecl interrupt
00675     typedef void interrupt (*W32_IntrHandler)(void);
00676
00677   #else
00678     #define INTR_PROTOTYPE  void cdecl interrupt
00679     typedef void (cdecl interrupt *W32_IntrHandler)();
00680   #endif
00681
00682 #elif defined(WIN32)
00683   /* No need for this on Windows */
00684
00685 #elif defined(WATCOM386)
00686   #define INTR_PROTOTYPE  void __interrupt __far
00687   typedef INTR_PROTOTYPE (*W32_IntrHandler)();
00688
00689 #elif defined(__HIGHC__)
00690   #define INTR_PROTOTYPE  _Far void _CC (_INTERRUPT|_CALLING_CONVENTION)
00691   typedef INTR_PROTOTYPE (*W32_IntrHandler)();
00692
00693 #elif defined(__DJGPP__)
00694   #define INTR_PROTOTYPE  void   /* simply a SIGALRM handler */
00695   typedef void (*W32_IntrHandler)(int);
00696
00697 #else
00698   /* Figure out what to do for others .. */
00699 #endif
00700 #endif  /* INTR_PROTOTYPE */
00701
00702
00703 #if defined(__GNUC__) && defined(__i386__) /* also for gcc -m486 and better */
00704  /*
00705   * This is not used yet since the benefit/drawbacks are unknown.
00706   * Define 32-bit multiplication asm macros.
00707   *
00708   * umul_ppmm (high_prod, low_prod, multiplier, multiplicand)
00709   * multiplies two unsigned long integers multiplier and multiplicand,
00710   * and generates a two unsigned word product in high_prod and
00711   * low_prod.
00712   */
00713   #define umul_ppmm(w1,w0,u,v)                           \
00714           __asm__ __volatile__ (                         \
00715                  "mull %3"                               \
00716                : "=a" ((DWORD)(w0)), "=d" ((DWORD)(w1))  \
00717                : "%0" ((DWORD)(u)),  "rm" ((DWORD)(v)))
00718
00719   #define mul32(u,v) ({ union ulong_long w;               \
00720                         umul_ppmm (w.s.hi, w.s.lo, u, v); \
00721                         w.ull; })
00722   /* Use as:
00723    *  DWORD x,y;
00724    *  ..
00725    *  uint64 z = mul32 (x,y);
00726    */
00727
00728   /* Borrowed from djgpp's <sys/farptr.h>
00729    * Needed in pkt_receiver_pm() because djgpp 2.03 doesn't
00730    * save/restore FS/GS registers in the rmode callback stub.
00731    * Not needed if 'USE_FAST_PKT' is used.
00732    */
00733   extern __inline__ WORD get_fs_reg (void)
00734   {
00735      WORD sel;
00736      __asm__ __volatile__ (
00737              "movw %%fs, %w0"
00738            : "=r" (sel) : );
00739      return (sel);
00740   }
00741   extern __inline__ WORD get_gs_reg (void)
00742   {
00743      WORD sel;
00744      __asm__ __volatile__ (
00745              "movw %%gs, %w0"
00746            : "=r" (sel) : );
00747      return (sel);
00748   }
00749   extern __inline__ void set_fs_reg (WORD sel)
00750   {
00751     __asm__ __volatile__ (
00752             "movw %w0, %%fs"
00753          :: "rm" (sel));
00754   }
00755   extern __inline__ void set_gs_reg (WORD sel)
00756   {
00757     __asm__ __volatile__ (
00758             "movw %w0, %%gs"
00759          :: "rm" (sel));
00760   }
00761 #else
00762   #define get_fs_reg()    (1)
00763   #define get_gs_reg()    (1)
00764   #define set_fs_reg(fs)  ((void)0)
00765   #define set_gs_reg(gs)  ((void)0)
00766 #endif /* __GNUC__ && __i386__ */
00767
00768
00769 /*
00770  * Various macros
00771  *
00772  * Note: Some versions of snprintf return -1 if they truncate
00773  *       the output. Others return size of truncated output.
00774  */
00775 #undef SNPRINTF
00776 #undef VSNPRINTF
00777
00778 #if defined(WIN32)
00779   #define SNPRINTF   _snprintf
00780   #define VSNPRINTF  _vsnprintf
00781
00782 #elif defined(__HIGHC__) || defined(__WATCOMC__)
00783   #define SNPRINTF   _bprintf
00784   #define VSNPRINTF  _vbprintf
00785
00786 #elif defined(__DMC__) || (defined(_MSC_VER) && (_MSC_VER >= 700))
00787   #define SNPRINTF   _snprintf
00788   #define VSNPRINTF  _vsnprintf
00789
00790 #elif defined(__DJGPP__) && (__DJGPP_MINOR__ >= 4)
00791   #define SNPRINTF   snprintf
00792   #define VSNPRINTF  vsnprintf
00793 #endif
00794
00795 #define UNCONST(type, var, val)   (*(type *)&(var)) = val
00796
00797 /*
00798  * Some prototypes not found in SP-lint's libraries
00799  */
00800 #if defined(lint) || defined(_lint)
00801   extern char *strupr (char*);
00802   extern char *strlwr (char*);
00803   extern char *strdup (const char*);
00804   extern int   stricmp (const char*, const char*);
00805   extern int   strnicmp (const char*, const char*, size_t);
00806   extern char *itoa (int, char*, int);
00807   extern void *alloca (size_t);
00808   extern int   gettimeofday (struct timeval*, struct timezone*);
00809   extern int   fileno (FILE*);
00810   extern int   isascii (int);
00811   extern void  psignal (int, const char*);
00812   extern int   vsscanf (const char*, const char*, va_list);
00813
00814   /*@constant int SIGALRM; @*/
00815   /*@constant int SIGTRAP; @*/
00816   /*@constant int EINVAL;  @*/
00817   /*@constant int EFAULT;  @*/
00818 #endif
00819
00820 #endif /* _w32_MISC_H */
00821
Generated on Wed Jan 25 15:42:35 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/NETADDR.C Source File

SRC/NETADDR.C

Go to the documentation of this file.
00001
00020 #include <stdio.h>
00021 #include <stdlib.h>
00022 #include <string.h>
00023 #include <ctype.h>
00024
00025 #include "wattcp.h"
00026 #include "misc.h"
00027 #include "strings.h"
00028 #include "netaddr.h"
00029
00030 #if defined(USE_BSD_API)
00031   #include <arpa/inet.h>
00032   #include <sys/socket.h>
00033 #endif
00034
00040 char *_inet_ntoa (char *s, DWORD ip)
00041 {
00042   static char buf[2][20];
00043   static int idx = 0;
00044
00045   if (!s)
00046   {
00047     s = buf [idx];
00048     idx ^= 1;
00049   }
00050   itoa ((int)(ip >> 24), s, 10);
00051   strcat (s, ".");
00052   itoa ((int)(ip >> 16) & 0xFF, strchr(s,'\0'), 10);
00053   strcat (s, ".");
00054   itoa ((int)(ip >> 8) & 0xFF, strchr(s,'\0'), 10);
00055   strcat (s, ".");
00056   itoa ((int)(ip & 0xFF), strchr(s,'\0'), 10);
00057   return (s);
00058 }
00059
00065 DWORD _inet_addr (const char *s)
00066 {
00067   DWORD addr = 0;
00068
00069   if (isaddr(s))
00070      return aton (s);
00071   if (isaddr_dotless(s,&addr))
00072      return (addr);
00073   return (0);
00074 }
00075
00076
00082 DWORD aton (const char *str)
00083 {
00084   DWORD ip = 0;
00085   int   i;
00086   char *s = (char*)str;
00087
00088   if (*s == '[')
00089      ++s;
00090
00091   for (i = 24; i >= 0; i -= 8)
00092   {
00093     int cur = ATOI (s);
00094
00095     ip |= (DWORD)(cur & 0xFF) << i;
00096     if (!i)
00097        return (ip);
00098
00099     s = strchr (s, '.');
00100     if (!s)
00101        return (0);      /* return 0 on error */
00102     s++;
00103   }
00104   return (0);           /* cannot happen ??  */
00105 }
00106
00111 DWORD aton_dotless (const char *str)
00112 {
00113   DWORD ip = 0UL;
00114
00115   isaddr_dotless (str, &ip);
00116   return (ip);
00117 }
00118
00124 BOOL isaddr (const char *str)
00125 {
00126   int ch;
00127
00128   while ((ch = *str++) != 0)
00129   {
00130     if (isdigit(ch))
00131        continue;
00132     if (ch == '.' || ch == ' ' || ch == '[' || ch == ']')
00133        continue;
00134     return (FALSE);
00135   }
00136   return (TRUE);
00137 }
00138
00144 BOOL isaddr_dotless (const char *str, DWORD *ip)
00145 {
00146   char  buf[10] = { 0 };
00147   int   ch, i = 0;
00148   DWORD addr;
00149
00150   while ((ch = *str++) != '\0')
00151   {
00152     if (ch == '.' || i == SIZEOF(buf))
00153        return (FALSE);
00154
00155     if (isdigit(ch))
00156     {
00157       buf[i++] = ch;
00158       continue;
00159     }
00160     if (ch == ' ' || ch == '[' || ch == ']')
00161        continue;
00162     return (FALSE);
00163   }
00164
00165   buf[i] = '\0';
00166   addr = atol (buf);
00167   if (addr == 0)
00168      return (FALSE);
00169
00170   if ((addr % 256) == 0)         /* LSB must be non-zero */
00171      return (FALSE);
00172
00173   if (((addr >> 24) % 256) == 0) /* MSB must be non-zero */
00174      return (FALSE);
00175
00176   if (ip)
00177      *ip = addr;
00178   return (TRUE);
00179 }
00180
00181 char * W32_CALL inet_ntoa (struct in_addr addr)
00182 {
00183   static char buf [4][20];   /* use max 4 at a time */
00184   static int  idx = 0;
00185   char       *rc  = buf [idx++];
00186
00187   idx &= 3;
00188   return _inet_ntoa (rc, ntohl(addr.s_addr));
00189 }
00190
00201 const char *_inet_atoeth (const char *src, eth_address *p_eth)
00202 {
00203   BYTE *eth = (BYTE*)p_eth;
00204
00205 #if (DOSX)
00206   int tmp [sizeof(eth_address)];
00207
00208   if (!sscanf(src,"%02x:%02x:%02x:%02x:%02x:%02x",
00209               &tmp[0], &tmp[1], &tmp[2],
00210               &tmp[3], &tmp[4], &tmp[5]) != DIM(tmp))
00211      return (NULL);
00212
00213   eth [0] = tmp [0];
00214   eth [1] = tmp [1];
00215   eth [2] = tmp [2];
00216   eth [3] = tmp [3];
00217   eth [4] = tmp [4];
00218   eth [5] = tmp [5];
00219   src = strrchr (src, ':') + 3;
00220 #else
00221   eth [0] = atox (src-2);      /*   xx:xx:xx:xx:xx:xx */
00222   eth [1] = atox (src+1);      /* ^src-2              */
00223   eth [2] = atox (src+4);      /*    ^src+1           */
00224   eth [3] = atox (src+7);
00225   eth [4] = atox (src+10);
00226   eth [5] = atox (src+13);
00227
00228   src += strlen ("xx:xx:xx:xx:xx:xx");
00229 #endif
00230
00231   if (*src == ',')
00232      ++src;
00233   return strltrim (src);
00234 }
00235
00236 #if defined(USE_BSD_API)
00237
00238 char * W32_CALL inet_ntoa_r (struct in_addr addr, char *buf, int buflen)
00239 {
00240   if (buf && buflen >= SIZEOF("255.255.255.255"))
00241      return _inet_ntoa (buf, ntohl(addr.s_addr));
00242   return (NULL);
00243 }
00244
00245 int W32_CALL inet_aton (const char *name, struct in_addr *addr)
00246 {
00247   u_long ip = inet_addr (name);
00248
00249   if (ip == INADDR_NONE && strcmp(name,"255.255.255.255"))
00250      return (0);
00251   addr->s_addr = ip;
00252   return (1);
00253 }
00254
00255 u_long W32_CALL inet_addr (const char *addr)
00256 {
00257   DWORD ip = htonl (_inet_addr(addr));
00258
00259   if (ip)
00260      return (ip);
00261   return (INADDR_NONE);
00262 }
00263
00264 u_long W32_CALL inet_network (const char *name)
00265 {
00266   u_long  val, base;
00267   u_long  parts[4];
00268   u_long *pp = parts;
00269   int     i, c, n;
00270
00271 again:
00272   /* Collect number up to ``.''. Values are specified as for C:
00273    * 0x=hex, 0=octal, other=decimal.
00274    */
00275   val  = 0;
00276   base = 10;
00277
00278   /* The 4.4BSD version of this file also accepts 'x__' as a hexa
00279    * number.  I don't think this is correct.  -- Uli
00280    */
00281   if (*name == '0')
00282   {
00283     if (*++name == 'x' || *name == 'X')
00284          base = 16, name++;
00285     else base = 8;
00286   }
00287   while ((c = *name) != '\0')
00288   {
00289     if (isdigit(c))
00290     {
00291       val = (val * base) + (c - '0');
00292       name++;
00293       continue;
00294     }
00295     if (base == 16 && isxdigit(c))
00296     {
00297       val = (val << 4) + (c + 10 - (islower(c) ? 'a' : 'A'));
00298       name++;
00299       continue;
00300     }
00301     break;
00302   }
00303   if (*name == '.')
00304   {
00305     if (pp >= parts + 4)
00306        return (INADDR_NONE);
00307
00308     *pp++ = val;
00309     name++;
00310     goto again;
00311   }
00312   if (*name && !isspace((int)*name))
00313      return (INADDR_NONE);
00314
00315   *pp++ = val;
00316   n = pp - parts;
00317   if (n > 4)
00318      return (INADDR_NONE);
00319
00320   for (val = 0, i = 0; i < n; i++)
00321   {
00322     val <<= 8;
00323     val |= parts[i] & 0xff;
00324   }
00325   return (val);
00326 }
00327
00332 u_int32_t W32_CALL inet_netof (struct in_addr addr)
00333 {
00334   u_long a = ntohl (addr.s_addr);
00335
00336   if (IN_CLASSA(a))
00337      return ((a & IN_CLASSA_NET) >> IN_CLASSA_NSHIFT);
00338
00339   if (IN_CLASSB(a))
00340      return ((a & IN_CLASSB_NET) >> IN_CLASSB_NSHIFT);
00341
00342   return ((a & IN_CLASSC_NET) >> IN_CLASSC_NSHIFT);
00343 }
00344
00351 u_long W32_CALL inet_lnaof (struct in_addr addr)
00352 {
00353   u_long a = ntohl (addr.s_addr);
00354
00355   if (IN_CLASSA(a))
00356      return (a & IN_CLASSA_HOST);
00357
00358   if (IN_CLASSB(a))
00359      return (a & IN_CLASSB_HOST);
00360
00361   return (a & IN_CLASSC_HOST);
00362 }
00363
00368 struct in_addr W32_CALL inet_makeaddr (u_long net, u_long host)
00369 {
00370   u_long addr;
00371
00372   if (net < 128)
00373        addr = (net << IN_CLASSA_NSHIFT) | (host & IN_CLASSA_HOST);
00374
00375   else if (net < 65536)
00376        addr = (net << IN_CLASSB_NSHIFT) | (host & IN_CLASSB_HOST);
00377
00378   else if (net < 16777216L)
00379        addr = (net << IN_CLASSC_NSHIFT) | (host & IN_CLASSC_HOST);
00380
00381   else addr = (net | host);
00382
00383   addr = htonl (addr);
00384   return (*(struct in_addr*) &addr);
00385 }
00386
00392 const char *_inet6_ntoa (const void *ip)
00393 {
00394   static char buf [4][50];   /* use max 4 at a time */
00395   static int  idx = 0;
00396   char  *rc = buf [idx++];
00397
00398   /* inet_ntop() should never return NULL
00399    */
00400   idx &= 3;
00401   rc = (char*) inet_ntop (AF_INET6, ip, rc, sizeof(buf[0]));
00402   return (const char*)rc;
00403 }
00404
00410 const ip6_address *_inet6_addr (const char *str)
00411 {
00412   static ip6_address ip6;
00413
00414   if (!inet_pton(AF_INET6, str, &ip6))
00415      return (NULL);
00416   return (const ip6_address*)ip6;
00417 }
00418 #endif  /* USE_BSD_API */
00419
00420
00421 #ifdef NOT_USED
00422 BOOL priv_addr (DWORD ip)
00423 {
00424   /*
00425    * private addresses in the "blackhole range" (ref. RFC-1918):
00426    *   10.0.0.0    - 10.255.255.255
00427    *   172.16.0.0  - 172.31.255.255
00428    *   192.168.0.0 - 192.168.255.255
00429    */
00430   if (ip >= aton("10.0.0.0") && ip <= aton("10.255.255.255"))
00431      return (TRUE);
00432
00433   if (ip >= aton("172.16.0.0") && ip <= aton("172.31.255.255"))
00434      return (TRUE);
00435
00436   if (ip >= aton("192.168.0.0") && ip <= aton("192.168.255.255"))
00437      return (TRUE);
00438
00439   return (FALSE);
00440 }
00441
00442 /*
00443  * Lev Walkin <vlm@lionet.info> provided these handy mask-checking
00444  * macros/routines.
00445  */
00446
00447 /* Masklen to mask convertor.
00448  */
00449 #define MLEN2MASK(mlen) ((mlen) ? (((DWORD)-1) << (32 - (mlen))) : 0)
00450
00451 /* Determine number of bits set in an IP mask.
00452  */
00453 #define BITSSET(v) ( {                                         \
00454         DWORD __n = v;                                         \
00455         __n = (__n & 0x55555555) + ((__n & 0xaaaaaaaa) >> 1);  \
00456         __n = (__n & 0x33333333) + ((__n & 0xcccccccc) >> 2);  \
00457         __n = (__n & 0x0f0f0f0f) + ((__n & 0xf0f0f0f0) >> 4);  \
00458         __n = (__n & 0x00ff00ff) + ((__n & 0xff00ff00) >> 8);  \
00459         __n = (__n & 0x0000ffff) + ((__n & 0xffff0000) >> 16); \
00460         __n; } )
00461
00462 /*
00463  * Check the mask for correctness.
00464  */
00465 int check_mask (DWORD mask)
00466 {
00467   return MLEN2MASK (BITSSET(mask)) == mask;
00468 }
00469
00470 /*
00471  * The string-based version of above function.
00472  */
00473 int check_mask2 (const char *mask)
00474 {
00475   struct in_addr imask;
00476
00477   if (inet_aton(mask,&imask) != 1)
00478      return (-1);
00479   return check_mask (imask.s_addr);
00480 }
00481 #endif
00482
00483
Generated on Wed Jan 25 15:42:35 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/NETADDR.H Source File

SRC/NETADDR.H

Go to the documentation of this file.
00001
00003 #ifndef _w32_NETADDR_H
00004 #define _w32_NETADDR_H
00005
00006 #define aton            NAMESPACE (aton)
00007 #define aton_dotless    NAMESPACE (aton_dotless)
00008 #define isaddr          NAMESPACE (isaddr)
00009 #define isaddr_dotless  NAMESPACE (isaddr_dotless)
00010 #define priv_addr       NAMESPACE (priv_addr)
00011 #define _inet_ntoa      NAMESPACE (_inet_ntoa)
00012 #define _inet_addr      NAMESPACE (_inet_addr)
00013 #define _inet_atoeth    NAMESPACE (_inet_atoeth)
00014
00015 W32_FUNC DWORD aton      (const char *str);
00016 W32_FUNC BOOL  isaddr    (const char *text);
00017 W32_FUNC int   priv_addr (DWORD ip);
00018
00019 W32_FUNC DWORD aton_dotless   (const char *str);
00020 W32_FUNC BOOL  isaddr_dotless (const char *str, DWORD *ip);
00021
00022 W32_FUNC char *_inet_ntoa (char *s, DWORD x);
00023 W32_FUNC DWORD _inet_addr (const char *s);
00024
00025 W32_FUNC const char *_inet_atoeth (const char *src, eth_address *eth);
00026
00027 W32_FUNC const char        *_inet6_ntoa (const void *ip);
00028 W32_FUNC const ip6_address *_inet6_addr (const char *str);
00029
00030 #endif
Generated on Wed Jan 25 15:42:35 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/NETBACK.C Source File

SRC/NETBACK.C

Go to the documentation of this file.
00001
00004 #include <stdio.h>
00005 #include <stdlib.h>
00006
00007 #include "wattcp.h"
00008 #include "language.h"
00009 #include "strings.h"
00010 #include "pctcp.h"
00011 #include "wdpmi.h"
00012 #include "misc.h"
00013
00014 #define TIMER_INTR 8
00015 #define STK_SIZE   1024
00016
00017
00018 #if (DOSX)
00019   void backgroundon (void)
00020   {
00021     outsnl (_LANG("Use wintr_init() / wintr_enable() instead"));
00022     exit (3);
00023   }
00024
00025 #elif !defined(NO_INLINE_ASM)  /* MSC <=6 unsupported */
00026
00027   static void (*user_routine)(void) = NULL;
00028   static int inside = 0;
00029
00030   static W32_IntrHandler oldinterrupt;
00031
00032   static INTR_PROTOTYPE newinterrupt (void)
00033   {
00034     (*oldinterrupt)();
00035     DISABLE();
00036     if (inside)
00037     {
00038       static UINT tempstack [STK_SIZE];
00039   #ifdef __WATCOMC__
00040       STACK_SET (&tempstack[STK_SIZE-1]);
00041   #else
00042         static UINT old_SP;
00043         static WORD old_SS;
00044         asm  mov ax, ss
00045         asm  mov old_SS, ax
00046         asm  mov ax, sp
00047         asm  mov old_SP, ax
00048         asm  mov ax, ds
00049         asm  mov ss, ax
00050         asm  lea sp, tempstack[STK_SIZE-1]
00051
00052   #endif
00053       ENABLE();
00054
00055       if (user_routine)
00056         (*user_routine)();
00057       tcp_tick (NULL);
00058
00059       DISABLE();
00060
00061   #ifdef __WATCOMC__
00062       STACK_RESTORE();
00063   #else
00064       asm  mov ax, old_SS
00065       asm  mov ss, ax
00066       asm  mov ax, old_SP
00067       asm  mov sp, ax
00068
00069   #endif
00070       inside = 0;
00071     }
00072     ENABLE();
00073   }
00074
00075   void backgroundon (void)
00076   {
00077     oldinterrupt = getvect (TIMER_INTR);
00078     setvect (TIMER_INTR, newinterrupt);
00079   }
00080
00081   void backgroundoff (void)
00082   {
00083     setvect (TIMER_INTR, oldinterrupt);
00084   }
00085
00086   void backgroundfn (void (*fn)(void))
00087   {
00088     user_routine = fn;
00089   }
00090 #endif  /* DOSX */
Generated on Wed Jan 25 15:42:35 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/NETERR.C Source File

SRC/NETERR.C

Go to the documentation of this file.
00001
00038 #include "socket.h"
00039
00040 char __syserr00[] = "No Error";
00041
00042 #if defined(__WATCOMC__)   /* data-modifier; near/far depending on model */
00043   #define DATA_MOD _WCNEAR
00044 #elif defined(_MSC_VER) && (_MSC_VER <= 800)
00045   #define DATA_MOD _near   /* even for large model */
00046 #else
00047   #define DATA_MOD
00048 #endif
00049
00050 #if defined(__TURBOC__) && (__TURBOC__ <= 0x410) /* TCC/BCC <= 3.1 */
00051   #define SYS_ERRLIST sys_errlist
00052   #define SYS_NERR    sys_nerr
00053   #include "borland/syserr.c" /* @NO_DEP */
00054
00055 #elif defined(__BORLANDC__)
00056   #define SYS_ERRLIST _sys_errlist
00057   #define SYS_NERR    _sys_nerr
00058   #include "borland/syserr.c" /* @NO_DEP */
00059
00060 #elif defined(__HIGHC__)
00061   #define SYS_ERRLIST _sys_errlist
00062   #define SYS_NERR    _sys_nerr
00063   #include "highc/syserr.c"   /* @NO_DEP */
00064
00065 #elif defined(__POCC__)
00066   #define SYS_ERRLIST sys_errlist
00067   #define SYS_NERR    EILSEQ
00068   #include "pellesc/syserr.c" /* @NO_DEP */
00069
00070 #elif defined(__WATCOMC__)
00071   #if defined(WIN32)
00072     #define SYS_ERRLIST _w32_sys_errlist
00073     #define SYS_NERR    _w32_sys_nerr
00074   #else
00075     #define SYS_ERRLIST _sys_errlist
00076     #define SYS_NERR    _sys_nerr
00077   #endif
00078
00079   #include "watcom/syserr.c"  /* @NO_DEP */
00080
00081 #elif defined(__DMC__)
00082   #if defined(WIN32)
00083     #define SYS_ERRLIST _w32_sys_errlist
00084     #define SYS_NERR    _w32_sys_nerr
00085   #else
00086     #define SYS_ERRLIST sys_errlist
00087     #define SYS_NERR    sys_nerr
00088   #endif
00089
00090   char __syserr37[] = "No Error"; /* !!fixme: isn't generated by dm_err.exe */
00091   #include "digmars/syserr.c" /* @NO_DEP */
00092
00093 #elif defined(_MSC_VER) && (_MSC_VER <= 800)
00094   #define SYS_ERRLIST DATA_MOD sys_errlist
00095   #define SYS_NERR             sys_nerr
00096   #include "quickc/syserr.c"  /* @NO_DEP */
00097
00098   #undef  SYS_ERRLIST
00099   #define SYS_ERRLIST sys_errlist
00100
00101 #elif defined(_MSC_VER) && (_MSC_VER > 800)    /* Visual C, assuming Win32 */
00102   #define SYS_ERRLIST DATA_MOD _w32_sys_errlist
00103   #define SYS_NERR             _w32_sys_nerr
00104   #include "visualc/syserr.c" /* @NO_DEP */
00105
00106   #undef  SYS_ERRLIST
00107   #define SYS_ERRLIST sys_errlist
00108
00109 #elif defined(__DJGPP__)
00110   #define SYS_ERRLIST sys_errlist
00111   #define SYS_NERR    sys_nerr
00112   #include "djgpp/syserr.c"   /* @NO_DEP */
00113
00114 #elif defined(__CCDL__)
00115   #define SYS_ERRLIST sys_errlist
00116   #define SYS_NERR    sys_nerr
00117   #include "ladsoft/syserr.c" /* @NO_DEP */
00118
00119 #elif defined(__LCC__)
00120   #define SYS_ERRLIST _w32_sys_errlist
00121   #define SYS_NERR    _w32_sys_nerr
00122   #include "lcc/syserr.c"     /* @NO_DEP */
00123
00124 #elif defined(__MINGW32__)
00125   #define SYS_ERRLIST _w32_sys_errlist
00126   #define SYS_NERR    _w32_sys_nerr
00127   #include "mingw32/syserr.c" /* @NO_DEP */
00128
00129 #else
00130   #error Unknown target!
00131 #endif
00132
00133 /*
00134  * A hack to make the linker use this sys_errlist[]
00135  * and not the normal one in the C-library.
00136  * Is there a better way?
00137  */
00138 int pull_neterr_module = 0;
00139
00140 #if defined(__POCC__)
00141   int _w32_sys_nerr = 120; /* pocc bug */
00142
00143 #elif defined(WIN32) && !defined(__LCC__) && !defined(__BORLANDC__)
00144   int _w32_sys_nerr    = DIM(_w32_sys_errlist);
00145   int *_sys_nerr_dll   = &_w32_sys_nerr;
00146   int *_imp___sys_nerr = &_w32_sys_nerr;
00147 #else
00148   int DATA_MOD SYS_NERR = DIM(SYS_ERRLIST);
00149 #endif
00150
00151 #if !defined(_MSC_VER) && !defined(WIN32)
00152 void MS_CDECL perror (const char *str)
00153 {
00154   if (str && *str)
00155      fprintf (stderr, "%s: ", str);
00156
00157 #if defined(__GNUC__) /* Posix (?) dictates a newline */
00158   fprintf (stderr, "%s\n", strerror(errno));
00159 #else
00160   fprintf (stderr, "%s", strerror(errno));
00161 #endif
00162 }
00163
00164 /*
00165  * For Win32, this doesn't replace the strerror() in the RTL,
00166  * but replacing sys_nerr (*_sys_nerr_dll) should give the same effect (?).
00167  */
00168 char * MS_CDECL strerror (int errnum)
00169 {
00170   static char buf[70];
00171
00172   if (errnum >= 0 && errnum < SYS_NERR)
00173        StrLcpy (buf, SYS_ERRLIST[errnum], sizeof(buf));
00174   else sprintf (buf, "Unknown error: %d", errnum);
00175
00176 #if !defined(__DJGPP__) && !defined(__MINGW32__)
00177  /*
00178   * Posix doesn't specify a newline at the end.
00179   */
00180   strcat (buf, "\n");
00181 #endif
00182
00183   return (buf);
00184 }
00185 #endif  /* !_MSC_VER && !WIN32 */
00186
00187 /*
00188  * For non-Win32 errno == _w32_errno for all network calls
00189  */
00190 #if defined(WIN32)
00191 /*
00192  * Winsock compatibility.
00193  */
00194 int __stdcall WSAGetLastError (void)
00195 {
00196   int err = _w32_errno;
00197   _w32_errno = 0;
00198   return (err);
00199 }
00200
00201 void __stdcall WSASetLastError (int err)
00202 {
00203 #if defined(__POCC__)
00204   #if defined(_DLL) || defined(_MT)
00205     *__errno() = err;
00206   #else
00207     errno = err;
00208   #endif
00209
00210 #elif defined(_MSC_VER) || defined(__DMC__)
00211   #if defined(_DLL) || defined(_MT)
00212     *_errno() = err;
00213   #else
00214     errno = err;
00215   #endif
00216
00217 #elif defined(__MINGW32__)
00218   *_errno() = err;
00219
00220 #elif defined(__BORLANDC__)
00221   int * _RTLENTRY _EXPFUNC __errno(void);
00222   *__errno() = err;
00223
00224 #elif defined(__LCC__)
00225   #undef errno
00226   *errno() = err;
00227
00228 #elif defined(__WATCOMC__)
00229   *__get_errno_ptr() = err;
00230
00231 #else
00232   #error Help me!
00233 #endif
00234
00235   _w32_errno = err;
00236 }
00237 #endif  /* WIN32 */
00238
00239
00240 #if defined(USE_DEBUG)
00241 /*
00242  * Return only the Exx part of strerror()
00243  */
00244 const char *short_strerror (int errnum)
00245 {
00246   static char buf[256];
00247   char  *l_par, *r_par;
00248
00249   StrLcpy (buf, strerror(errnum), sizeof(buf));
00250   l_par = strchr (buf, '(');
00251   if (!l_par)
00252   {
00253     strcpy (buf, "errno ");
00254     return itoa (errnum, buf+6, 10);
00255   }
00256
00257   r_par = strchr (l_par, ')');
00258   if (r_par)
00259      *r_par = '\0';
00260   return (l_par+1);
00261 }
00262 #endif
00263
00264
00265 #if defined(__GNUC__) && 0
00266   #define ALIAS(func) __attribute__((weak, alias(func)))
00267
00268   char *strerror_s (int err) ALIAS(strerror);
00269 #endif
00270
00271
00272 /*
00273  * Incase you have trouble with multiple defined symbols,
00274  * make sure the following functions are used before
00275  * perror/strerror/sys_errlist in your C-library.
00276  */
00277 void perror_s (const char *str)
00278 {
00279 #if defined(__LCC__)
00280   perror ((char*)str);
00281 #else
00282   perror (str);
00283 #endif
00284 }
00285
00286 char *strerror_s (int errnum)
00287 {
00288   return strerror (errnum);
00289 }
00290
Generated on Wed Jan 25 15:42:35 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/NETTIME.C Source File

SRC/NETTIME.C

Go to the documentation of this file.
00001
00005 /*  BSD sockets functionality for Waterloo TCP/IP
00006  *
00007  *  Copyright (c) 1997-2002 Gisle Vanem <giva@bgnett.no>
00008  *
00009  *  Redistribution and use in source and binary forms, with or without
00010  *  modification, are permitted provided that the following conditions
00011  *  are met:
00012  *  1. Redistributions of source code must retain the above copyright
00013  *     notice, this list of conditions and the following disclaimer.
00014  *  2. Redistributions in binary form must reproduce the above copyright
00015  *     notice, this list of conditions and the following disclaimer in the
00016  *     documentation and/or other materials provided with the distribution.
00017  *  3. All advertising materials mentioning features or use of this software
00018  *     must display the following acknowledgement:
00019  *       This product includes software developed by Gisle Vanem
00020  *       Bergen, Norway.
00021  *
00022  *  THIS SOFTWARE IS PROVIDED BY ME (Gisle Vanem) AND CONTRIBUTORS ``AS IS''
00023  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00024  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00025  *  ARE DISCLAIMED.  IN NO EVENT SHALL I OR CONTRIBUTORS BE LIABLE FOR ANY
00026  *  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00027  *  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00028  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00029  *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00030  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00031  *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00032  *
00033  *
00034  *  14.may 1999 (GV)  - Created
00035  *
00036  *  This module implements time counters for "user" and "system"
00037  *  calls. NOTE: "system" time is counted only when signals are
00038  *  trapped. i.e. around select_s(), connect() loops.
00039  *
00040  *  Based on djgpp version of times().
00041  *
00042  */
00043
00044 #include "socket.h"
00045
00046 #if defined(USE_BSD_API)
00047
00048 static DWORD sock_sys_time;
00049 static DWORD start;
00050
00051 void _sock_start_timer (void)
00052 {
00053   start = set_timeout (0);
00054 }
00055
00056 void _sock_stop_timer (void)
00057 {
00058   DWORD now = set_timeout (0);
00059
00060   if (now > start)
00061        sock_sys_time += (now - start);
00062   else sock_sys_time += (start - now); /* msec/tick counter wrapped */
00063 }
00064
00065 static DWORD sys_time (void)
00066 {
00067   return (sock_sys_time);
00068 }
00069
00070 static DWORD usr_time (void)
00071 {
00072   return (set_timeout(0) - start_time - sock_sys_time);
00073 }
00074
00075 unsigned long net_times (struct tms *tms)
00076 {
00077   if (!tms)
00078   {
00079     SOCK_ERRNO (EINVAL);
00080     return (unsigned long)(-1);
00081   }
00082   memset (tms, 0, sizeof(*tms));
00083   if (_watt_is_init)
00084   {
00085     DWORD divisor = (has_8254 || has_rdtsc) ? 1000 : 18;
00086
00087     tms->tms_utime = (CLOCKS_PER_SEC * usr_time()) / divisor;
00088     tms->tms_stime = (CLOCKS_PER_SEC * sys_time()) / divisor;
00089   }
00090   return (tms->tms_utime);
00091 }
00092 #endif  /* USE_BSD_API */
00093
Generated on Wed Jan 25 15:42:35 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/NOCHKSTK.H Source File

SRC/NOCHKSTK.H

Go to the documentation of this file.
00001
00005 #if defined(__HIGHC__) || defined(__WATCOMC__)
00006   #pragma Off (check_stack)
00007
00008 #elif defined(_MSC_VER) && (_MSC_VER >= 800)
00009   #pragma check_stack (off)
00010
00011 #elif defined(__DMC__)
00012   /* #pragma ..  */
00013
00014 #elif defined(__TURBOC__) || defined(__BORLANDC__)
00015   #if !defined(OLD_TURBOC) && !defined(BORLAND_WIN32)
00016   #pragma option -N-
00017   #endif
00018 #endif
Generated on Wed Jan 25 15:42:35 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/NSAPADDR.C Source File

SRC/NSAPADDR.C

Go to the documentation of this file.
00001
00005 /* Copyright (c) 1996 by Internet Software Consortium.
00006  *
00007  * Permission to use, copy, modify, and distribute this software for any
00008  * purpose with or without fee is hereby granted, provided that the above
00009  * copyright notice and this permission notice appear in all copies.
00010  *
00011  * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
00012  * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
00013  * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
00014  * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
00015  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
00016  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
00017  * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
00018  * SOFTWARE.
00019  */
00020
00021 #include "socket.h"
00022
00023 #if defined(USE_BSD_API) || defined(USE_BIND)
00024
00025 static __inline char xtob (int c)
00026 {
00027   return (c - (((c >= '0') && (c <= '9')) ? '0' : '7'));
00028 }
00029
00030 u_int W32_CALL inet_nsap_addr (const char *ascii, u_char *binary, int maxlen)
00031 {
00032   u_char c, nib;
00033   int    len = 0;
00034
00035   while ((c = *ascii++) != '\0' && len < maxlen)
00036   {
00037     if (c == '.' || c == '+' || c == '/')
00038        continue;
00039
00040     c = toupper (c);
00041     if (!isxdigit(c))
00042        return (0);
00043
00044     nib = xtob (c);
00045     if ((c = *ascii++) == '\0')
00046        return (0);
00047
00048     c = toupper (c);
00049     if (!isxdigit(c))
00050        return (0);
00051
00052     *binary++ = (nib << 4) | xtob(c);
00053     len++;
00054   }
00055   return (u_int)len;
00056 }
00057
00058 char * W32_CALL inet_nsap_ntoa (int binlen, const u_char *binary, char *ascii)
00059 {
00060   static char tmpbuf[255*3+1];
00061   char  *start;
00062   int    i;
00063
00064   if (ascii)
00065      start = ascii;
00066   else
00067   {
00068     ascii = tmpbuf;
00069     start = tmpbuf;
00070   }
00071
00072   if (binlen > 255)
00073       binlen = 255;
00074
00075   for (i = 0; i < binlen; i++)
00076   {
00077     int nib = *binary >> 4;
00078
00079     *ascii++ = nib + (nib < 10 ? '0' : '7');
00080     nib = *binary++ & 0x0f;
00081     *ascii++ = nib + (nib < 10 ? '0' : '7');
00082     if (((i % 2) == 0 && (i + 1) < binlen))
00083        *ascii++ = '.';
00084   }
00085   *ascii = '\0';
00086   return (start);
00087 }
00088
00089 #endif
Generated on Wed Jan 25 15:42:35 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/Ntddndis.h Source File

SRC/Ntddndis.h

00001 /*
00002  *++ BUILD Version: 0001
00003  * Copyright (c) 1990-1993  Microsoft Corporation
00004  * Module Name:
00005  * ntddndis.h
00006  * Abstract:
00007  * This is the include file that defines all constants and types for
00008  * accessing the Network driver interface device.
00009  * Author:
00010  * Steve Wood (stevewo) 27-May-1990
00011  * Revision History:
00012  * Adam Barr (adamba)     04-Nov-1992             added the correct values for NDIS 3.0.
00013  * Jameel Hyder (jameelh) 01-Aug-95               added Pnp IoCTLs and structures
00014  * Kyle Brandon (kyleb)   09/24/96                added general co ndis oids.
00015  *--
00016  */
00017
00018 #ifndef _w32_NTDDNDIS_H
00019 #define _w32_NTDDNDIS_H
00020
00021 //
00022 // Device Name - this string is the name of the device.  It is the name
00023 // that should be passed to NtOpenFile when accessing the device.
00024 //
00025 // Note:  For devices that support multiple units, it should be suffixed
00026 //                with the Ascii representation of the unit number.
00027 //
00028 #define DD_NDIS_DEVICE_NAME "\\Device\\UNKNOWN"
00029
00030 //
00031 // NtDeviceIoControlFile IoControlCode values for this device.
00032 //
00033 // Warning:  Remember that the low two bits of the code specify how the
00034 //                       buffers are passed to the driver!
00035 //
00036 #define _NDIS_CONTROL_CODE(request,method) \
00037             CTL_CODE(FILE_DEVICE_PHYSICAL_NETCARD, request, method, FILE_ANY_ACCESS)
00038 #define IOCTL_NDIS_QUERY_GLOBAL_STATS   _NDIS_CONTROL_CODE( 0, METHOD_OUT_DIRECT )
00039 #define IOCTL_NDIS_QUERY_ALL_STATS      _NDIS_CONTROL_CODE( 1, METHOD_OUT_DIRECT )
00040 #define IOCTL_NDIS_ADD_DEVICE           _NDIS_CONTROL_CODE( 2, METHOD_BUFFERED )
00041 #define IOCTL_NDIS_DELETE_DEVICE        _NDIS_CONTROL_CODE( 3, METHOD_BUFFERED )
00042 #define IOCTL_NDIS_TRANSLATE_NAME       _NDIS_CONTROL_CODE( 4, METHOD_BUFFERED )
00043 #define IOCTL_NDIS_ADD_TDI_DEVICE       _NDIS_CONTROL_CODE( 5, METHOD_BUFFERED )
00044 #define IOCTL_NDIS_NOTIFY_PROTOCOL      _NDIS_CONTROL_CODE( 6, METHOD_BUFFERED )
00045 #define IOCTL_NDIS_GET_LOG_DATA         _NDIS_CONTROL_CODE( 7, METHOD_OUT_DIRECT )
00046
00047 //
00048 // NtDeviceIoControlFile InputBuffer/OutputBuffer record structures for
00049 // this device.
00050 //
00051 //
00052 // This is the type of an NDIS OID value.
00053 //
00054 typedef ULONG NDIS_OID, *PNDIS_OID;
00055
00056 //
00057 // IOCTL_NDIS_QUERY_ALL_STATS returns a sequence of these, packed
00058 // together (no padding is required since statistics all have
00059 // four or eight bytes of data).
00060 //
00061 typedef struct _NDIS_STATISTICS_VALUE {
00062   NDIS_OID Oid;
00063   ULONG    DataLength;
00064   UCHAR    Data[1];              // variable length
00065 } NDIS_STATISTICS_VALUE, *PNDIS_STATISTICS_VALUE;
00066
00067 //
00068 // Structure used by TRANSLATE_NAME IOCTL
00069 //
00070 typedef struct _NET_PNP_ID {
00071   ULONG ClassId;
00072   ULONG Token;
00073 } NET_PNP_ID, *PNET_PNP_ID;
00074
00075 typedef struct _NET_PNP_TRANSLATE_LIST {
00076   ULONG       BytesNeeded;
00077   NET_PNP_ID  IdArray[ANYSIZE_ARRAY];
00078 } NET_PNP_TRANSLATE_LIST, *PNET_PNP_TRANSLATE_LIST;
00079
00080 //
00081 // Structure used to define a self-contained variable data structure
00082 //
00083 typedef struct _NDIS_VAR_DATA_DESC {
00084   USHORT  Length;                // # of octects of data
00085   USHORT  MaximumLength;         // # of octects available
00086   LONG    Offset;                // Offset of data relative to the descriptor
00087 } NDIS_VAR_DATA_DESC, *PNDIS_VAR_DATA_DESC;
00088
00089 //
00090 // Object Identifiers used by NdisRequest Query/Set Information
00091 //
00092 //
00093 // General Objects
00094 //
00095 #define OID_GEN_SUPPORTED_LIST                  0x00010101
00096 #define OID_GEN_HARDWARE_STATUS                 0x00010102
00097 #define OID_GEN_MEDIA_SUPPORTED                 0x00010103
00098 #define OID_GEN_MEDIA_IN_USE                    0x00010104
00099 #define OID_GEN_MAXIMUM_LOOKAHEAD               0x00010105
00100 #define OID_GEN_MAXIMUM_FRAME_SIZE              0x00010106
00101 #define OID_GEN_LINK_SPEED                      0x00010107
00102 #define OID_GEN_TRANSMIT_BUFFER_SPACE           0x00010108
00103 #define OID_GEN_RECEIVE_BUFFER_SPACE            0x00010109
00104 #define OID_GEN_TRANSMIT_BLOCK_SIZE             0x0001010A
00105 #define OID_GEN_RECEIVE_BLOCK_SIZE              0x0001010B
00106 #define OID_GEN_VENDOR_ID                       0x0001010C
00107 #define OID_GEN_VENDOR_DESCRIPTION              0x0001010D
00108 #define OID_GEN_CURRENT_PACKET_FILTER           0x0001010E
00109 #define OID_GEN_CURRENT_LOOKAHEAD               0x0001010F
00110 #define OID_GEN_DRIVER_VERSION                  0x00010110
00111 #define OID_GEN_MAXIMUM_TOTAL_SIZE              0x00010111
00112 #define OID_GEN_PROTOCOL_OPTIONS                0x00010112
00113 #define OID_GEN_MAC_OPTIONS                     0x00010113
00114 #define OID_GEN_MEDIA_CONNECT_STATUS            0x00010114
00115 #define OID_GEN_MAXIMUM_SEND_PACKETS            0x00010115
00116 #define OID_GEN_VENDOR_DRIVER_VERSION           0x00010116
00117 #define OID_GEN_XMIT_OK                         0x00020101
00118 #define OID_GEN_RCV_OK                          0x00020102
00119 #define OID_GEN_XMIT_ERROR                      0x00020103
00120 #define OID_GEN_RCV_ERROR                       0x00020104
00121 #define OID_GEN_RCV_NO_BUFFER                   0x00020105
00122 #define OID_GEN_DIRECTED_BYTES_XMIT             0x00020201
00123 #define OID_GEN_DIRECTED_FRAMES_XMIT            0x00020202
00124 #define OID_GEN_MULTICAST_BYTES_XMIT            0x00020203
00125 #define OID_GEN_MULTICAST_FRAMES_XMIT           0x00020204
00126 #define OID_GEN_BROADCAST_BYTES_XMIT            0x00020205
00127 #define OID_GEN_BROADCAST_FRAMES_XMIT           0x00020206
00128 #define OID_GEN_DIRECTED_BYTES_RCV              0x00020207
00129 #define OID_GEN_DIRECTED_FRAMES_RCV             0x00020208
00130 #define OID_GEN_MULTICAST_BYTES_RCV             0x00020209
00131 #define OID_GEN_MULTICAST_FRAMES_RCV            0x0002020A
00132 #define OID_GEN_BROADCAST_BYTES_RCV             0x0002020B
00133 #define OID_GEN_BROADCAST_FRAMES_RCV            0x0002020C
00134 #define OID_GEN_RCV_CRC_ERROR                   0x0002020D
00135 #define OID_GEN_TRANSMIT_QUEUE_LENGTH           0x0002020E
00136 #define OID_GEN_GET_TIME_CAPS                   0x0002020F
00137 #define OID_GEN_GET_NETCARD_TIME                0x00020210
00138
00139 //
00140 // These are connection-oriented general OIDs.
00141 // These replace the above OIDs for connection-oriented media.
00142 //
00143 #define OID_GEN_CO_SUPPORTED_LIST               0x00010101
00144 #define OID_GEN_CO_HARDWARE_STATUS              0x00010102
00145 #define OID_GEN_CO_MEDIA_SUPPORTED              0x00010103
00146 #define OID_GEN_CO_MEDIA_IN_USE                 0x00010104
00147 #define OID_GEN_CO_LINK_SPEED                   0x00010105
00148 #define OID_GEN_CO_VENDOR_ID                    0x00010106
00149 #define OID_GEN_CO_VENDOR_DESCRIPTION           0x00010107
00150 #define OID_GEN_CO_DRIVER_VERSION               0x00010108
00151 #define OID_GEN_CO_PROTOCOL_OPTIONS             0x00010109
00152 #define OID_GEN_CO_MAC_OPTIONS                  0x0001010A
00153 #define OID_GEN_CO_MEDIA_CONNECT_STATUS         0x0001010B
00154 #define OID_GEN_CO_VENDOR_DRIVER_VERSION        0x0001010C
00155 #define OID_GEN_CO_MINIMUM_LINK_SPEED           0x0001010D
00156 #define OID_GEN_CO_GET_TIME_CAPS                0x00010201
00157 #define OID_GEN_CO_GET_NETCARD_TIME             0x00010202
00158
00159 //
00160 // These are connection-oriented statistics OIDs.
00161 //
00162 #define OID_GEN_CO_XMIT_PDUS_OK                 0x00020101
00163 #define OID_GEN_CO_RCV_PDUS_OK                  0x00020102
00164 #define OID_GEN_CO_XMIT_PDUS_ERROR              0x00020103
00165 #define OID_GEN_CO_RCV_PDUS_ERROR               0x00020104
00166 #define OID_GEN_CO_RCV_PDUS_NO_BUFFER           0x00020105
00167 #define OID_GEN_CO_RCV_CRC_ERROR                0x00020201
00168 #define OID_GEN_CO_TRANSMIT_QUEUE_LENGTH        0x00020202
00169 #define OID_GEN_CO_BYTES_XMIT                   0x00020203
00170 #define OID_GEN_CO_BYTES_RCV                    0x00020204
00171 #define OID_GEN_CO_BYTES_XMIT_OUTSTANDING       0x00020205
00172 #define OID_GEN_CO_NETCARD_LOAD                 0x00020206
00173
00174 //
00175 // These are objects for Connection-oriented media call-managers and are not
00176 // valid for ndis drivers. Under construction.
00177 //
00178 #define OID_CO_ADD_PVC                          0xFF000001
00179 #define OID_CO_DELETE_PVC                       0xFF000002
00180 #define OID_CO_GET_CALL_INFORMATION             0xFF000003
00181 #define OID_CO_ADD_ADDRESS                      0xFF000004
00182 #define OID_CO_DELETE_ADDRESS                   0xFF000005
00183 #define OID_CO_GET_ADDRESSES                    0xFF000006
00184 #define OID_CO_ADDRESS_CHANGE                   0xFF000007
00185 #define OID_CO_SIGNALING_ENABLED                0xFF000008
00186 #define OID_CO_SIGNALING_DISABLED               0xFF000009
00187
00188 //
00189 // 802.3 Objects (Ethernet)
00190 //
00191 #define OID_802_3_PERMANENT_ADDRESS             0x01010101
00192 #define OID_802_3_CURRENT_ADDRESS               0x01010102
00193 #define OID_802_3_MULTICAST_LIST                0x01010103
00194 #define OID_802_3_MAXIMUM_LIST_SIZE             0x01010104
00195 #define OID_802_3_MAC_OPTIONS                   0x01010105
00196
00197 #define NDIS_802_3_MAC_OPTION_PRIORITY          0x00000001
00198 #define OID_802_3_RCV_ERROR_ALIGNMENT           0x01020101
00199 #define OID_802_3_XMIT_ONE_COLLISION            0x01020102
00200 #define OID_802_3_XMIT_MORE_COLLISIONS          0x01020103
00201 #define OID_802_3_XMIT_DEFERRED                 0x01020201
00202 #define OID_802_3_XMIT_MAX_COLLISIONS           0x01020202
00203 #define OID_802_3_RCV_OVERRUN                   0x01020203
00204 #define OID_802_3_XMIT_UNDERRUN                 0x01020204
00205 #define OID_802_3_XMIT_HEARTBEAT_FAILURE        0x01020205
00206 #define OID_802_3_XMIT_TIMES_CRS_LOST           0x01020206
00207 #define OID_802_3_XMIT_LATE_COLLISIONS          0x01020207
00208
00209 //
00210 // 802.5 Objects (Token-Ring)
00211 //
00212 #define OID_802_5_PERMANENT_ADDRESS             0x02010101
00213 #define OID_802_5_CURRENT_ADDRESS               0x02010102
00214 #define OID_802_5_CURRENT_FUNCTIONAL            0x02010103
00215 #define OID_802_5_CURRENT_GROUP                 0x02010104
00216 #define OID_802_5_LAST_OPEN_STATUS              0x02010105
00217 #define OID_802_5_CURRENT_RING_STATUS           0x02010106
00218 #define OID_802_5_CURRENT_RING_STATE            0x02010107
00219 #define OID_802_5_LINE_ERRORS                   0x02020101
00220 #define OID_802_5_LOST_FRAMES                   0x02020102
00221 #define OID_802_5_BURST_ERRORS                  0x02020201
00222 #define OID_802_5_AC_ERRORS                     0x02020202
00223 #define OID_802_5_ABORT_DELIMETERS              0x02020203
00224 #define OID_802_5_FRAME_COPIED_ERRORS           0x02020204
00225 #define OID_802_5_FREQUENCY_ERRORS              0x02020205
00226 #define OID_802_5_TOKEN_ERRORS                  0x02020206
00227 #define OID_802_5_INTERNAL_ERRORS               0x02020207
00228
00229 //
00230 // FDDI Objects
00231 //
00232 #define OID_FDDI_LONG_PERMANENT_ADDR            0x03010101
00233 #define OID_FDDI_LONG_CURRENT_ADDR              0x03010102
00234 #define OID_FDDI_LONG_MULTICAST_LIST            0x03010103
00235 #define OID_FDDI_LONG_MAX_LIST_SIZE             0x03010104
00236 #define OID_FDDI_SHORT_PERMANENT_ADDR           0x03010105
00237 #define OID_FDDI_SHORT_CURRENT_ADDR             0x03010106
00238 #define OID_FDDI_SHORT_MULTICAST_LIST           0x03010107
00239 #define OID_FDDI_SHORT_MAX_LIST_SIZE            0x03010108
00240 #define OID_FDDI_ATTACHMENT_TYPE                0x03020101
00241 #define OID_FDDI_UPSTREAM_NODE_LONG             0x03020102
00242 #define OID_FDDI_DOWNSTREAM_NODE_LONG           0x03020103
00243 #define OID_FDDI_FRAME_ERRORS                   0x03020104
00244 #define OID_FDDI_FRAMES_LOST                    0x03020105
00245 #define OID_FDDI_RING_MGT_STATE                 0x03020106
00246 #define OID_FDDI_LCT_FAILURES                   0x03020107
00247 #define OID_FDDI_LEM_REJECTS                    0x03020108
00248 #define OID_FDDI_LCONNECTION_STATE              0x03020109
00249 #define OID_FDDI_SMT_STATION_ID                 0x03030201
00250 #define OID_FDDI_SMT_OP_VERSION_ID              0x03030202
00251 #define OID_FDDI_SMT_HI_VERSION_ID              0x03030203
00252 #define OID_FDDI_SMT_LO_VERSION_ID              0x03030204
00253 #define OID_FDDI_SMT_MANUFACTURER_DATA          0x03030205
00254 #define OID_FDDI_SMT_USER_DATA                  0x03030206
00255 #define OID_FDDI_SMT_MIB_VERSION_ID             0x03030207
00256 #define OID_FDDI_SMT_MAC_CT                     0x03030208
00257 #define OID_FDDI_SMT_NON_MASTER_CT              0x03030209
00258 #define OID_FDDI_SMT_MASTER_CT                  0x0303020A
00259 #define OID_FDDI_SMT_AVAILABLE_PATHS            0x0303020B
00260 #define OID_FDDI_SMT_CONFIG_CAPABILITIES        0x0303020C
00261 #define OID_FDDI_SMT_CONFIG_POLICY              0x0303020D
00262 #define OID_FDDI_SMT_CONNECTION_POLICY          0x0303020E
00263 #define OID_FDDI_SMT_T_NOTIFY                   0x0303020F
00264 #define OID_FDDI_SMT_STAT_RPT_POLICY            0x03030210
00265 #define OID_FDDI_SMT_TRACE_MAX_EXPIRATION       0x03030211
00266 #define OID_FDDI_SMT_PORT_INDEXES               0x03030212
00267 #define OID_FDDI_SMT_MAC_INDEXES                0x03030213
00268 #define OID_FDDI_SMT_BYPASS_PRESENT             0x03030214
00269 #define OID_FDDI_SMT_ECM_STATE                  0x03030215
00270 #define OID_FDDI_SMT_CF_STATE                   0x03030216
00271 #define OID_FDDI_SMT_HOLD_STATE                 0x03030217
00272 #define OID_FDDI_SMT_REMOTE_DISCONNECT_FLAG     0x03030218
00273 #define OID_FDDI_SMT_STATION_STATUS             0x03030219
00274 #define OID_FDDI_SMT_PEER_WRAP_FLAG             0x0303021A
00275 #define OID_FDDI_SMT_MSG_TIME_STAMP             0x0303021B
00276 #define OID_FDDI_SMT_TRANSITION_TIME_STAMP      0x0303021C
00277 #define OID_FDDI_SMT_SET_COUNT                  0x0303021D
00278 #define OID_FDDI_SMT_LAST_SET_STATION_ID        0x0303021E
00279 #define OID_FDDI_MAC_FRAME_STATUS_FUNCTIONS     0x0303021F
00280 #define OID_FDDI_MAC_BRIDGE_FUNCTIONS           0x03030220
00281 #define OID_FDDI_MAC_T_MAX_CAPABILITY           0x03030221
00282 #define OID_FDDI_MAC_TVX_CAPABILITY             0x03030222
00283 #define OID_FDDI_MAC_AVAILABLE_PATHS            0x03030223
00284 #define OID_FDDI_MAC_CURRENT_PATH               0x03030224
00285 #define OID_FDDI_MAC_UPSTREAM_NBR               0x03030225
00286 #define OID_FDDI_MAC_DOWNSTREAM_NBR             0x03030226
00287 #define OID_FDDI_MAC_OLD_UPSTREAM_NBR           0x03030227
00288 #define OID_FDDI_MAC_OLD_DOWNSTREAM_NBR         0x03030228
00289 #define OID_FDDI_MAC_DUP_ADDRESS_TEST           0x03030229
00290 #define OID_FDDI_MAC_REQUESTED_PATHS            0x0303022A
00291 #define OID_FDDI_MAC_DOWNSTREAM_PORT_TYPE       0x0303022B
00292 #define OID_FDDI_MAC_INDEX                      0x0303022C
00293 #define OID_FDDI_MAC_SMT_ADDRESS                0x0303022D
00294 #define OID_FDDI_MAC_LONG_GRP_ADDRESS           0x0303022E
00295 #define OID_FDDI_MAC_SHORT_GRP_ADDRESS          0x0303022F
00296 #define OID_FDDI_MAC_T_REQ                      0x03030230
00297 #define OID_FDDI_MAC_T_NEG                      0x03030231
00298 #define OID_FDDI_MAC_T_MAX                      0x03030232
00299 #define OID_FDDI_MAC_TVX_VALUE                  0x03030233
00300 #define OID_FDDI_MAC_T_PRI0                     0x03030234
00301 #define OID_FDDI_MAC_T_PRI1                     0x03030235
00302 #define OID_FDDI_MAC_T_PRI2                     0x03030236
00303 #define OID_FDDI_MAC_T_PRI3                     0x03030237
00304 #define OID_FDDI_MAC_T_PRI4                     0x03030238
00305 #define OID_FDDI_MAC_T_PRI5                     0x03030239
00306 #define OID_FDDI_MAC_T_PRI6                     0x0303023A
00307 #define OID_FDDI_MAC_FRAME_CT                   0x0303023B
00308 #define OID_FDDI_MAC_COPIED_CT                  0x0303023C
00309 #define OID_FDDI_MAC_TRANSMIT_CT                0x0303023D
00310 #define OID_FDDI_MAC_TOKEN_CT                   0x0303023E
00311 #define OID_FDDI_MAC_ERROR_CT                   0x0303023F
00312 #define OID_FDDI_MAC_LOST_CT                    0x03030240
00313 #define OID_FDDI_MAC_TVX_EXPIRED_CT             0x03030241
00314 #define OID_FDDI_MAC_NOT_COPIED_CT              0x03030242
00315 #define OID_FDDI_MAC_LATE_CT                    0x03030243
00316 #define OID_FDDI_MAC_RING_OP_CT                 0x03030244
00317 #define OID_FDDI_MAC_FRAME_ERROR_THRESHOLD      0x03030245
00318 #define OID_FDDI_MAC_FRAME_ERROR_RATIO          0x03030246
00319 #define OID_FDDI_MAC_NOT_COPIED_THRESHOLD       0x03030247
00320 #define OID_FDDI_MAC_NOT_COPIED_RATIO           0x03030248
00321 #define OID_FDDI_MAC_RMT_STATE                  0x03030249
00322 #define OID_FDDI_MAC_DA_FLAG                    0x0303024A
00323 #define OID_FDDI_MAC_UNDA_FLAG                  0x0303024B
00324 #define OID_FDDI_MAC_FRAME_ERROR_FLAG           0x0303024C
00325 #define OID_FDDI_MAC_NOT_COPIED_FLAG            0x0303024D
00326 #define OID_FDDI_MAC_MA_UNITDATA_AVAILABLE      0x0303024E
00327 #define OID_FDDI_MAC_HARDWARE_PRESENT           0x0303024F
00328 #define OID_FDDI_MAC_MA_UNITDATA_ENABLE         0x03030250
00329 #define OID_FDDI_PATH_INDEX                     0x03030251
00330 #define OID_FDDI_PATH_RING_LATENCY              0x03030252
00331 #define OID_FDDI_PATH_TRACE_STATUS              0x03030253
00332 #define OID_FDDI_PATH_SBA_PAYLOAD               0x03030254
00333 #define OID_FDDI_PATH_SBA_OVERHEAD              0x03030255
00334 #define OID_FDDI_PATH_CONFIGURATION             0x03030256
00335 #define OID_FDDI_PATH_T_R_MODE                  0x03030257
00336 #define OID_FDDI_PATH_SBA_AVAILABLE             0x03030258
00337 #define OID_FDDI_PATH_TVX_LOWER_BOUND           0x03030259
00338 #define OID_FDDI_PATH_T_MAX_LOWER_BOUND         0x0303025A
00339 #define OID_FDDI_PATH_MAX_T_REQ                 0x0303025B
00340 #define OID_FDDI_PORT_MY_TYPE                   0x0303025C
00341 #define OID_FDDI_PORT_NEIGHBOR_TYPE             0x0303025D
00342 #define OID_FDDI_PORT_CONNECTION_POLICIES       0x0303025E
00343 #define OID_FDDI_PORT_MAC_INDICATED             0x0303025F
00344 #define OID_FDDI_PORT_CURRENT_PATH              0x03030260
00345 #define OID_FDDI_PORT_REQUESTED_PATHS           0x03030261
00346 #define OID_FDDI_PORT_MAC_PLACEMENT             0x03030262
00347 #define OID_FDDI_PORT_AVAILABLE_PATHS           0x03030263
00348 #define OID_FDDI_PORT_MAC_LOOP_TIME             0x03030264
00349 #define OID_FDDI_PORT_PMD_CLASS                 0x03030265
00350 #define OID_FDDI_PORT_CONNECTION_CAPABILITIES   0x03030266
00351 #define OID_FDDI_PORT_INDEX                     0x03030267
00352 #define OID_FDDI_PORT_MAINT_LS                  0x03030268
00353 #define OID_FDDI_PORT_BS_FLAG                   0x03030269
00354 #define OID_FDDI_PORT_PC_LS                     0x0303026A
00355 #define OID_FDDI_PORT_EB_ERROR_CT               0x0303026B
00356 #define OID_FDDI_PORT_LCT_FAIL_CT               0x0303026C
00357 #define OID_FDDI_PORT_LER_ESTIMATE              0x0303026D
00358 #define OID_FDDI_PORT_LEM_REJECT_CT             0x0303026E
00359 #define OID_FDDI_PORT_LEM_CT                    0x0303026F
00360 #define OID_FDDI_PORT_LER_CUTOFF                0x03030270
00361 #define OID_FDDI_PORT_LER_ALARM                 0x03030271
00362 #define OID_FDDI_PORT_CONNNECT_STATE            0x03030272
00363 #define OID_FDDI_PORT_PCM_STATE                 0x03030273
00364 #define OID_FDDI_PORT_PC_WITHHOLD               0x03030274
00365 #define OID_FDDI_PORT_LER_FLAG                  0x03030275
00366 #define OID_FDDI_PORT_HARDWARE_PRESENT          0x03030276
00367 #define OID_FDDI_SMT_STATION_ACTION             0x03030277
00368 #define OID_FDDI_PORT_ACTION                    0x03030278
00369 #define OID_FDDI_IF_DESCR                       0x03030279
00370 #define OID_FDDI_IF_TYPE                        0x0303027A
00371 #define OID_FDDI_IF_MTU                         0x0303027B
00372 #define OID_FDDI_IF_SPEED                       0x0303027C
00373 #define OID_FDDI_IF_PHYS_ADDRESS                0x0303027D
00374 #define OID_FDDI_IF_ADMIN_STATUS                0x0303027E
00375 #define OID_FDDI_IF_OPER_STATUS                 0x0303027F
00376 #define OID_FDDI_IF_LAST_CHANGE                 0x03030280
00377 #define OID_FDDI_IF_IN_OCTETS                   0x03030281
00378 #define OID_FDDI_IF_IN_UCAST_PKTS               0x03030282
00379 #define OID_FDDI_IF_IN_NUCAST_PKTS              0x03030283
00380 #define OID_FDDI_IF_IN_DISCARDS                 0x03030284
00381 #define OID_FDDI_IF_IN_ERRORS                   0x03030285
00382 #define OID_FDDI_IF_IN_UNKNOWN_PROTOS           0x03030286
00383 #define OID_FDDI_IF_OUT_OCTETS                  0x03030287
00384 #define OID_FDDI_IF_OUT_UCAST_PKTS              0x03030288
00385 #define OID_FDDI_IF_OUT_NUCAST_PKTS             0x03030289
00386 #define OID_FDDI_IF_OUT_DISCARDS                0x0303028A
00387 #define OID_FDDI_IF_OUT_ERRORS                  0x0303028B
00388 #define OID_FDDI_IF_OUT_QLEN                    0x0303028C
00389 #define OID_FDDI_IF_SPECIFIC                    0x0303028D
00390
00391 //
00392 // WAN objects
00393 //
00394 #define OID_WAN_PERMANENT_ADDRESS               0x04010101
00395 #define OID_WAN_CURRENT_ADDRESS                 0x04010102
00396 #define OID_WAN_QUALITY_OF_SERVICE              0x04010103
00397 #define OID_WAN_PROTOCOL_TYPE                   0x04010104
00398 #define OID_WAN_MEDIUM_SUBTYPE                  0x04010105
00399 #define OID_WAN_HEADER_FORMAT                   0x04010106
00400 #define OID_WAN_GET_INFO                        0x04010107
00401 #define OID_WAN_SET_LINK_INFO                   0x04010108
00402 #define OID_WAN_GET_LINK_INFO                   0x04010109
00403 #define OID_WAN_LINE_COUNT                      0x0401010A
00404 #define OID_WAN_GET_BRIDGE_INFO                 0x0401020A
00405 #define OID_WAN_SET_BRIDGE_INFO                 0x0401020B
00406 #define OID_WAN_GET_COMP_INFO                   0x0401020C
00407 #define OID_WAN_SET_COMP_INFO                   0x0401020D
00408 #define OID_WAN_GET_STATS_INFO                  0x0401020E
00409
00410 //
00411 // LocalTalk objects
00412 //
00413 #define OID_LTALK_CURRENT_NODE_ID               0x05010102
00414 #define OID_LTALK_IN_BROADCASTS                 0x05020101
00415 #define OID_LTALK_IN_LENGTH_ERRORS              0x05020102
00416 #define OID_LTALK_OUT_NO_HANDLERS               0x05020201
00417 #define OID_LTALK_COLLISIONS                    0x05020202
00418 #define OID_LTALK_DEFERS                        0x05020203
00419 #define OID_LTALK_NO_DATA_ERRORS                0x05020204
00420 #define OID_LTALK_RANDOM_CTS_ERRORS             0x05020205
00421 #define OID_LTALK_FCS_ERRORS                    0x05020206
00422
00423 //
00424 // Arcnet objects
00425 //
00426 #define OID_ARCNET_PERMANENT_ADDRESS            0x06010101
00427 #define OID_ARCNET_CURRENT_ADDRESS              0x06010102
00428 #define OID_ARCNET_RECONFIGURATIONS             0x06020201
00429
00430 //
00431 // TAPI objects
00432 //
00433 #define OID_TAPI_ACCEPT                         0x07030101
00434 #define OID_TAPI_ANSWER                         0x07030102
00435 #define OID_TAPI_CLOSE                          0x07030103
00436 #define OID_TAPI_CLOSE_CALL                     0x07030104
00437 #define OID_TAPI_CONDITIONAL_MEDIA_DETECTION    0x07030105
00438 #define OID_TAPI_CONFIG_DIALOG                  0x07030106
00439 #define OID_TAPI_DEV_SPECIFIC                   0x07030107
00440 #define OID_TAPI_DIAL                           0x07030108
00441 #define OID_TAPI_DROP                           0x07030109
00442 #define OID_TAPI_GET_ADDRESS_CAPS               0x0703010A
00443 #define OID_TAPI_GET_ADDRESS_ID                 0x0703010B
00444 #define OID_TAPI_GET_ADDRESS_STATUS             0x0703010C
00445 #define OID_TAPI_GET_CALL_ADDRESS_ID            0x0703010D
00446 #define OID_TAPI_GET_CALL_INFO                  0x0703010E
00447 #define OID_TAPI_GET_CALL_STATUS                0x0703010F
00448 #define OID_TAPI_GET_DEV_CAPS                   0x07030110
00449 #define OID_TAPI_GET_DEV_CONFIG                 0x07030111
00450 #define OID_TAPI_GET_EXTENSION_ID               0x07030112
00451 #define OID_TAPI_GET_ID                         0x07030113
00452 #define OID_TAPI_GET_LINE_DEV_STATUS            0x07030114
00453 #define OID_TAPI_MAKE_CALL                      0x07030115
00454 #define OID_TAPI_NEGOTIATE_EXT_VERSION          0x07030116
00455 #define OID_TAPI_OPEN                           0x07030117
00456 #define OID_TAPI_PROVIDER_INITIALIZE            0x07030118
00457 #define OID_TAPI_PROVIDER_SHUTDOWN              0x07030119
00458 #define OID_TAPI_SECURE_CALL                    0x0703011A
00459 #define OID_TAPI_SELECT_EXT_VERSION             0x0703011B
00460 #define OID_TAPI_SEND_USER_USER_INFO            0x0703011C
00461 #define OID_TAPI_SET_APP_SPECIFIC               0x0703011D
00462 #define OID_TAPI_SET_CALL_PARAMS                0x0703011E
00463 #define OID_TAPI_SET_DEFAULT_MEDIA_DETECTION    0x0703011F
00464 #define OID_TAPI_SET_DEV_CONFIG                 0x07030120
00465 #define OID_TAPI_SET_MEDIA_MODE                 0x07030121
00466 #define OID_TAPI_SET_STATUS_MESSAGES            0x07030122
00467
00468 //
00469 // ATM Connection Oriented Ndis
00470 //
00471 #define OID_ATM_SUPPORTED_VC_RATES              0x08010101
00472 #define OID_ATM_SUPPORTED_SERVICE_CATEGORY      0x08010102
00473 #define OID_ATM_SUPPORTED_AAL_TYPES             0x08010103
00474 #define OID_ATM_HW_CURRENT_ADDRESS              0x08010104
00475 #define OID_ATM_MAX_ACTIVE_VCS                  0x08010105
00476 #define OID_ATM_MAX_ACTIVE_VCI_BITS             0x08010106
00477 #define OID_ATM_MAX_ACTIVE_VPI_BITS             0x08010107
00478 #define OID_ATM_MAX_AAL0_PACKET_SIZE            0x08010108
00479 #define OID_ATM_MAX_AAL1_PACKET_SIZE            0x08010109
00480 #define OID_ATM_MAX_AAL34_PACKET_SIZE           0x0801010A
00481 #define OID_ATM_MAX_AAL5_PACKET_SIZE            0x0801010B
00482 #define OID_ATM_SIGNALING_VPIVCI                0x08010201
00483 #define OID_ATM_ASSIGNED_VPI                    0x08010202
00484 #define OID_ATM_ACQUIRE_ACCESS_NET_RESOURCES    0x08010203
00485 #define OID_ATM_RELEASE_ACCESS_NET_RESOURCES    0x08010204
00486 #define OID_ATM_ILMI_VPIVCI                     0x08010205
00487 #define OID_ATM_DIGITAL_BROADCAST_VPIVCI        0x08010206
00488 #define OID_ATM_GET_NEAREST_FLOW                0x08010207
00489 #define OID_ATM_ALIGNMENT_REQUIRED              0x08010208
00490
00491 //
00492 // ATM specific statistics OIDs.
00493 //
00494 #define OID_ATM_RCV_CELLS_OK                    0x08020101
00495 #define OID_ATM_XMIT_CELLS_OK                   0x08020102
00496 #define OID_ATM_RCV_CELLS_DROPPED               0x08020103
00497 #define OID_ATM_RCV_INVALID_VPI_VCI             0x08020201
00498 #define OID_ATM_CELLS_HEC_ERROR                 0x08020202
00499 #define OID_ATM_RCV_REASSEMBLY_ERROR            0x08020203
00500
00501 //
00502 // PCCA (Wireless) object
00503 //
00504 //
00505 // All WirelessWAN devices must support the following OIDs
00506 //
00507 #define OID_WW_GEN_NETWORK_TYPES_SUPPORTED      0x09010101
00508 #define OID_WW_GEN_NETWORK_TYPE_IN_USE          0x09010102
00509 #define OID_WW_GEN_HEADER_FORMATS_SUPPORTED     0x09010103
00510 #define OID_WW_GEN_HEADER_FORMAT_IN_USE         0x09010104
00511 #define OID_WW_GEN_INDICATION_REQUEST           0x09010105
00512 #define OID_WW_GEN_DEVICE_INFO                  0x09010106
00513 #define OID_WW_GEN_OPERATION_MODE               0x09010107
00514 #define OID_WW_GEN_LOCK_STATUS                  0x09010108
00515 #define OID_WW_GEN_DISABLE_TRANSMITTER          0x09010109
00516 #define OID_WW_GEN_NETWORK_ID                   0x0901010A
00517 #define OID_WW_GEN_PERMANENT_ADDRESS            0x0901010B
00518 #define OID_WW_GEN_CURRENT_ADDRESS              0x0901010C
00519 #define OID_WW_GEN_SUSPEND_DRIVER               0x0901010D
00520 #define OID_WW_GEN_BASESTATION_ID               0x0901010E
00521 #define OID_WW_GEN_CHANNEL_ID                   0x0901010F
00522 #define OID_WW_GEN_ENCRYPTION_SUPPORTED         0x09010110
00523 #define OID_WW_GEN_ENCRYPTION_IN_USE            0x09010111
00524 #define OID_WW_GEN_ENCRYPTION_STATE             0x09010112
00525 #define OID_WW_GEN_CHANNEL_QUALITY              0x09010113
00526 #define OID_WW_GEN_REGISTRATION_STATUS          0x09010114
00527 #define OID_WW_GEN_RADIO_LINK_SPEED             0x09010115
00528 #define OID_WW_GEN_LATENCY                      0x09010116
00529 #define OID_WW_GEN_BATTERY_LEVEL                0x09010117
00530 #define OID_WW_GEN_EXTERNAL_POWER               0x09010118
00531
00532 //
00533 // Network Dependent OIDs - Mobitex:
00534 //
00535 #define OID_WW_MBX_SUBADDR                      0x09050101
00536 // OID 0x09050102 is reserved and may not be used
00537
00538 #define OID_WW_MBX_FLEXLIST                     0x09050103
00539 #define OID_WW_MBX_GROUPLIST                    0x09050104
00540 #define OID_WW_MBX_TRAFFIC_AREA                 0x09050105
00541 #define OID_WW_MBX_LIVE_DIE                     0x09050106
00542 #define OID_WW_MBX_TEMP_DEFAULTLIST             0x09050107
00543
00544 //
00545 // Network Dependent OIDs - Pinpoint:
00546 //
00547 #define OID_WW_PIN_LOC_AUTHORIZE                0x09090101
00548 #define OID_WW_PIN_LAST_LOCATION                0x09090102
00549 #define OID_WW_PIN_LOC_FIX                      0x09090103
00550
00551 //
00552 // Network Dependent - CDPD:
00553 //
00554 #define OID_WW_CDPD_SPNI                        0x090D0101
00555 #define OID_WW_CDPD_WASI                        0x090D0102
00556 #define OID_WW_CDPD_AREA_COLOR                  0x090D0103
00557 #define OID_WW_CDPD_TX_POWER_LEVEL              0x090D0104
00558 #define OID_WW_CDPD_EID                         0x090D0105
00559 #define OID_WW_CDPD_HEADER_COMPRESSION          0x090D0106
00560 #define OID_WW_CDPD_DATA_COMPRESSION            0x090D0107
00561 #define OID_WW_CDPD_CHANNEL_SELECT              0x090D0108
00562 #define OID_WW_CDPD_CHANNEL_STATE               0x090D0109
00563 #define OID_WW_CDPD_NEI                         0x090D010A
00564 #define OID_WW_CDPD_NEI_STATE                   0x090D010B
00565 #define OID_WW_CDPD_SERVICE_PROVIDER_IDENTIFIER 0x090D010C
00566 #define OID_WW_CDPD_SLEEP_MODE                  0x090D010D
00567 #define OID_WW_CDPD_CIRCUIT_SWITCHED            0x090D010E
00568 #define OID_WW_CDPD_TEI                         0x090D010F
00569 #define OID_WW_CDPD_RSSI                        0x090D0110
00570
00571 //
00572 // Network Dependent - Ardis:
00573 //
00574 #define OID_WW_ARD_SNDCP                        0x09110101
00575 #define OID_WW_ARD_TMLY_MSG                     0x09110102
00576 #define OID_WW_ARD_DATAGRAM                     0x09110103
00577
00578 //
00579 // Network Dependent - DataTac:
00580 //
00581 #define OID_WW_TAC_COMPRESSION                  0x09150101
00582 #define OID_WW_TAC_SET_CONFIG                   0x09150102
00583 #define OID_WW_TAC_GET_STATUS                   0x09150103
00584 #define OID_WW_TAC_USER_HEADER                  0x09150104
00585
00586 //
00587 // Network Dependent - Metricom:
00588 //
00589 #define OID_WW_MET_FUNCTION                     0x09190101
00590
00591 //
00592 // IRDA objects
00593 //
00594 #define OID_IRDA_RECEIVING                      0x0A010100
00595 #define OID_IRDA_TURNAROUND_TIME                0x0A010101
00596 #define OID_IRDA_SUPPORTED_SPEEDS               0x0A010102
00597 #define OID_IRDA_LINK_SPEED                     0x0A010103
00598 #define OID_IRDA_MEDIA_BUSY                     0x0A010104
00599 #define OID_IRDA_EXTRA_RCV_BOFS                 0x0A010200
00600 #define OID_IRDA_RATE_SNIFF                     0x0A010201
00601 #define OID_IRDA_UNICAST_LIST                   0x0A010202
00602 #define OID_IRDA_MAX_UNICAST_LIST_SIZE          0x0A010203
00603 #define OID_IRDA_MAX_RECEIVE_WINDOW_SIZE        0x0A010204
00604 #define OID_IRDA_MAX_SEND_WINDOW_SIZE           0x0A010205
00605
00606 //
00607 // Medium the Ndis Driver is running on (OID_GEN_MEDIA_SUPPORTED/
00608 // OID_GEN_MEDIA_IN_USE).
00609 //
00610 typedef enum _NDIS_MEDIUM {
00611   NdisMedium802_3,
00612   NdisMedium802_5,
00613   NdisMediumFddi,
00614   NdisMediumWan,
00615   NdisMediumLocalTalk,
00616   NdisMediumDix,                // defined for convenience, not a real medium
00617   NdisMediumArcnetRaw,
00618   NdisMediumArcnet878_2,
00619   NdisMediumAtm,
00620   NdisMediumWirelessWan,
00621   NdisMediumIrda,
00622   NdisMediumMax                 // Not a real medium, defined as an upper-bound
00623 } NDIS_MEDIUM, *PNDIS_MEDIUM;
00624
00625 //
00626 // Hardware status codes (OID_GEN_HARDWARE_STATUS).
00627 //
00628 typedef enum _NDIS_HARDWARE_STATUS {
00629   NdisHardwareStatusReady,
00630   NdisHardwareStatusInitializing,
00631   NdisHardwareStatusReset,
00632   NdisHardwareStatusClosing,
00633   NdisHardwareStatusNotReady
00634 } NDIS_HARDWARE_STATUS, *PNDIS_HARDWARE_STATUS;
00635
00636 //
00637 // this is the type passed in the OID_GEN_GET_TIME_CAPS request
00638 //
00639 typedef struct _GEN_GET_TIME_CAPS {
00640   ULONG  Flags;                  // Bits defined below
00641   ULONG  ClockPrecision;
00642 } GEN_GET_TIME_CAPS, *PGEN_GET_TIME_CAPS;
00643
00644 #define READABLE_LOCAL_CLOCK                    0x000000001
00645 #define CLOCK_NETWORK_DERIVED                   0x000000002
00646 #define CLOCK_PRECISION                         0x000000004
00647 #define RECEIVE_TIME_INDICATION_CAPABLE         0x000000008
00648 #define TIMED_SEND_CAPABLE                      0x000000010
00649 #define TIME_STAMP_CAPABLE                      0x000000020
00650
00651 //
00652 // this is the type passed in the OID_GEN_GET_NETCARD_TIME request
00653 //
00654 typedef struct _GEN_GET_NETCARD_TIME {
00655   ULONG ReadTime;
00656 } GEN_GET_NETCARD_TIME, *PGEN_GET_NETCARD_TIME;
00657
00658 //
00659 // Defines the attachment types for FDDI (OID_FDDI_ATTACHMENT_TYPE).
00660 //
00661 typedef enum _NDIS_FDDI_ATTACHMENT_TYPE {
00662   NdisFddiTypeIsolated = 1,
00663   NdisFddiTypeLocalA,
00664   NdisFddiTypeLocalB,
00665   NdisFddiTypeLocalAB,
00666   NdisFddiTypeLocalS,
00667   NdisFddiTypeWrapA,
00668   NdisFddiTypeWrapB,
00669   NdisFddiTypeWrapAB,
00670   NdisFddiTypeWrapS,
00671   NdisFddiTypeCWrapA,
00672   NdisFddiTypeCWrapB,
00673   NdisFddiTypeCWrapS,
00674   NdisFddiTypeThrough
00675 } NDIS_FDDI_ATTACHMENT_TYPE, *PNDIS_FDDI_ATTACHMENT_TYPE;
00676
00677 //
00678 // Defines the ring management states for FDDI (OID_FDDI_RING_MGT_STATE).
00679 //
00680 typedef enum _NDIS_FDDI_RING_MGT_STATE {
00681   NdisFddiRingIsolated = 1,
00682   NdisFddiRingNonOperational,
00683   NdisFddiRingOperational,
00684   NdisFddiRingDetect,
00685   NdisFddiRingNonOperationalDup,
00686   NdisFddiRingOperationalDup,
00687   NdisFddiRingDirected,
00688   NdisFddiRingTrace
00689 } NDIS_FDDI_RING_MGT_STATE, *PNDIS_FDDI_RING_MGT_STATE;
00690
00691 //
00692 // Defines the Lconnection state for FDDI (OID_FDDI_LCONNECTION_STATE).
00693 //
00694 typedef enum _NDIS_FDDI_LCONNECTION_STATE {
00695   NdisFddiStateOff = 1,
00696   NdisFddiStateBreak,
00697   NdisFddiStateTrace,
00698   NdisFddiStateConnect,
00699   NdisFddiStateNext,
00700   NdisFddiStateSignal,
00701   NdisFddiStateJoin,
00702   NdisFddiStateVerify,
00703   NdisFddiStateActive,
00704   NdisFddiStateMaintenance
00705 } NDIS_FDDI_LCONNECTION_STATE, *PNDIS_FDDI_LCONNECTION_STATE;
00706
00707 //
00708 // Defines the medium subtypes for WAN medium (OID_WAN_MEDIUM_SUBTYPE).
00709 //
00710 typedef enum _NDIS_WAN_MEDIUM_SUBTYPE {
00711   NdisWanMediumHub,
00712   NdisWanMediumX_25,
00713   NdisWanMediumIsdn,
00714   NdisWanMediumSerial,
00715   NdisWanMediumFrameRelay,
00716   NdisWanMediumAtm,
00717   NdisWanMediumSonet,
00718   NdisWanMediumSW56K
00719 } NDIS_WAN_MEDIUM_SUBTYPE, *PNDIS_WAN_MEDIUM_SUBTYPE;
00720
00721 //
00722 // Defines the header format for WAN medium (OID_WAN_HEADER_FORMAT).
00723 //
00724 typedef enum _NDIS_WAN_HEADER_FORMAT {
00725   NdisWanHeaderNative,          // src/dest based on subtype, followed by NLPID
00726   NdisWanHeaderEthernet         // emulation of ethernet header
00727 } NDIS_WAN_HEADER_FORMAT, *PNDIS_WAN_HEADER_FORMAT;
00728
00729 //
00730 // Defines the line quality on a WAN line (OID_WAN_QUALITY_OF_SERVICE).
00731 //
00732 typedef enum _NDIS_WAN_QUALITY {
00733   NdisWanRaw,
00734   NdisWanErrorControl,
00735   NdisWanReliable
00736 } NDIS_WAN_QUALITY, *PNDIS_WAN_QUALITY;
00737
00738 //
00739 // Defines the state of a token-ring adapter (OID_802_5_CURRENT_RING_STATE).
00740 //
00741 typedef enum _NDIS_802_5_RING_STATE {
00742   NdisRingStateOpened = 1,
00743   NdisRingStateClosed,
00744   NdisRingStateOpening,
00745   NdisRingStateClosing,
00746   NdisRingStateOpenFailure,
00747   NdisRingStateRingFailure
00748 } NDIS_802_5_RING_STATE, *PNDIS_802_5_RING_STATE;
00749
00750 //
00751 // Defines the state of the LAN media
00752 //
00753 typedef enum _NDIS_MEDIA_STATE {
00754   NdisMediaStateConnected,
00755   NdisMediaStateDisconnected
00756 } NDIS_MEDIA_STATE, *PNDIS_MEDIA_STATE;
00757
00758 //
00759 // The following is set on a per-packet basis as OOB data with NdisClass802_3Priority
00760 //
00761 typedef ULONG Priority_802_3;   // 0-7 priority levels
00762
00763 //
00764 // The following structure is used to query OID_GEN_CO_LINK_SPEED and
00765 // OID_GEN_CO_MINIMUM_LINK_SPEED.  The first OID will return the current
00766 // link speed of the adapter.  The second will return the minimum link speed
00767 // the adapter is capable of.
00768 //
00769 typedef struct _NDIS_CO_LINK_SPEED {
00770   ULONG  Outbound;
00771   ULONG  Inbound;
00772 } NDIS_CO_LINK_SPEED, *PNDIS_CO_LINK_SPEED;
00773
00774 //
00775 // Ndis Packet Filter Bits (OID_GEN_CURRENT_PACKET_FILTER).
00776 //
00777 #define NDIS_PACKET_TYPE_DIRECTED               0x0001
00778 #define NDIS_PACKET_TYPE_MULTICAST              0x0002
00779 #define NDIS_PACKET_TYPE_ALL_MULTICAST          0x0004
00780 #define NDIS_PACKET_TYPE_BROADCAST              0x0008
00781 #define NDIS_PACKET_TYPE_SOURCE_ROUTING         0x0010
00782 #define NDIS_PACKET_TYPE_PROMISCUOUS            0x0020
00783 #define NDIS_PACKET_TYPE_SMT                    0x0040
00784 #define NDIS_PACKET_TYPE_ALL_LOCAL              0x0080
00785 #define NDIS_PACKET_TYPE_MAC_FRAME              0x8000
00786 #define NDIS_PACKET_TYPE_FUNCTIONAL             0x4000
00787 #define NDIS_PACKET_TYPE_ALL_FUNCTIONAL         0x2000
00788 #define NDIS_PACKET_TYPE_GROUP                  0x1000
00789
00790 //
00791 // Ndis Token-Ring Ring Status Codes (OID_802_5_CURRENT_RING_STATUS).
00792 //
00793 #define NDIS_RING_SIGNAL_LOSS                   0x00008000
00794 #define NDIS_RING_HARD_ERROR                    0x00004000
00795 #define NDIS_RING_SOFT_ERROR                    0x00002000
00796 #define NDIS_RING_TRANSMIT_BEACON               0x00001000
00797 #define NDIS_RING_LOBE_WIRE_FAULT               0x00000800
00798 #define NDIS_RING_AUTO_REMOVAL_ERROR            0x00000400
00799 #define NDIS_RING_REMOVE_RECEIVED               0x00000200
00800 #define NDIS_RING_COUNTER_OVERFLOW              0x00000100
00801 #define NDIS_RING_SINGLE_STATION                0x00000080
00802 #define NDIS_RING_RING_RECOVERY                 0x00000040
00803
00804 //
00805 // Ndis protocol option bits (OID_GEN_PROTOCOL_OPTIONS).
00806 //
00807 #define NDIS_PROT_OPTION_ESTIMATED_LENGTH       0x00000001
00808 #define NDIS_PROT_OPTION_NO_LOOPBACK            0x00000002
00809 #define NDIS_PROT_OPTION_NO_RSVD_ON_RCVPKT      0x00000004
00810
00811 //
00812 // Ndis MAC option bits (OID_GEN_MAC_OPTIONS).
00813 //
00814 #define NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA     0x00000001
00815 #define NDIS_MAC_OPTION_RECEIVE_SERIALIZED      0x00000002
00816 #define NDIS_MAC_OPTION_TRANSFERS_NOT_PEND      0x00000004
00817 #define NDIS_MAC_OPTION_NO_LOOPBACK             0x00000008
00818 #define NDIS_MAC_OPTION_FULL_DUPLEX             0x00000010
00819 #define NDIS_MAC_OPTION_EOTX_INDICATION         0x00000020
00820 #define NDIS_MAC_OPTION_RESERVED                0x80000000
00821
00822 //
00823 //      NDIS MAC option bits for OID_GEN_CO_MAC_OPTIONS.
00824 //
00825 #define NDIS_CO_MAC_OPTION_DYNAMIC_LINK_SPEED   0x00000001
00826
00827 //
00828 // The following is set on a per-packet basis as OOB data with NdisClassIrdaPacketInfo
00829 // This is the per-packet info specified on a per-packet basis
00830 //
00831 typedef struct _NDIS_IRDA_PACKET_INFO {
00832   UINT  ExtraBOFs;
00833   UINT  MinTurnAroundTime;
00834 } NDIS_IRDA_PACKET_INFO, *PNDIS_IRDA_PACKET_INFO;
00835
00836 #endif  /* _w32_NTDDNDIS_H */
00837
Generated on Wed Jan 25 15:42:35 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/OLDSTUFF.C Source File

SRC/OLDSTUFF.C

Go to the documentation of this file.
00001
00006 #include <stdio.h>
00007 #include <stdlib.h>
00008 #include <time.h>
00009
00010 #include "copyrigh.h"
00011 #include "wattcp.h"
00012 #include "pctcp.h"
00013 #include "netaddr.h"
00014 #include "strings.h"
00015 #include "chksum.h"
00016 #include "misc.h"
00017 #include "timer.h"
00018 #include "udp_dom.h"
00019
00024 #undef tcp_cbrk
00025 int tcp_cbrk (int mode)
00026 {
00027   return tcp_cbreak (mode);
00028 }
00029
00034 unsigned long set_ttimeout (unsigned ticks)
00035 {
00036   int   tmp = has_8254;
00037   DWORD now;
00038
00039   has_8254 = 0;
00040   now = set_timeout (0);
00041   has_8254 = tmp;
00042   return (ticks + now);
00043 }
00044
00045 /*
00046  * Not needed in Watt-32. Print remote tcp address and port.
00047  */
00048 #define psocket NAMESPACE (psocket)
00049 void psocket (const sock_type *s)
00050 {
00051   char buf[20];
00052
00053   (*_outch) ('[');
00054   outs (_inet_ntoa(buf, s->tcp.hisaddr));
00055   (*_outch) (':');
00056   itoa (s->tcp.hisport, buf, 10);
00057   outs (buf);
00058   (*_outch) (']');
00059 }
00060
00065 void sock_sturdy (sock_type *s, int level)
00066 {
00067   s->tcp.rigid = level;
00068   if (s->tcp.rigid < s->tcp.stress)
00069      sock_abort (s);
00070 }
00071
00075 int resolve_ip (DWORD ip, char *name, size_t len)
00076 {
00077   return reverse_resolve_ip4 (ip, name, len);
00078 }
00079
00080 #undef time
00081
00082 /*
00083  * Some time/date conversion function only(?) found in Borland libs.
00084  * Only(?) djgpp/DMC besides Borland have "struct time" etc.
00085  */
00086 #if defined(__DJGPP__) || defined(__DMC__)
00087 time_t dostounix (struct date *d, struct time *t)
00088 {
00089   struct tm tm;
00090
00091   if (!d || !t)
00092      return (0);
00093
00094   tm.tm_year  = d->da_year - 1900;
00095   tm.tm_mon   = d->da_mon - 1;
00096   tm.tm_mday  = d->da_day;
00097   tm.tm_isdst = 0;
00098   tm.tm_hour  = t->ti_hour;
00099   tm.tm_min   = t->ti_min;
00100   tm.tm_sec   = t->ti_sec;
00101   return mktime (&tm);
00102 }
00103
00104 void unixtodos (time_t time, struct date *d, struct time *t)
00105 {
00106   struct tm *tm = localtime (&time);
00107
00108   if (d && tm)
00109   {
00110     d->da_year = tm->tm_year;
00111     d->da_mon  = tm->tm_mon;
00112     d->da_day  = tm->tm_mday;
00113   }
00114   if (t && tm)
00115   {
00116     t->ti_hour = tm->tm_hour;
00117     t->ti_min  = tm->tm_min;
00118     t->ti_sec  = tm->tm_sec;
00119     t->ti_hund = 0;
00120   }
00121 }
00122 #endif
00123
00124
00125 WORD inchksum (const void *ptr, int len)
00126 {
00127 #ifdef HAVE_IN_CHECKSUM_FAST
00128   return _w32_in_checksum_fast (ptr, len);
00129 #else
00130   return _w32_in_checksum (ptr, len);
00131 #endif
00132 }
00133
00134 WORD _w32_inchksum (const void *ptr, int len)
00135 {
00136 #ifdef HAVE_IN_CHECKSUM_FAST
00137   return _w32_in_checksum_fast (ptr, len);
00138 #else
00139   return _w32_in_checksum (ptr, len);
00140 #endif
00141 }
00142
00143
00144 #if !defined(USE_BIGENDIAN) && !defined(WATT_NO_INLINE_INTEL)
00145 /*
00146  * If linking old .o-files with new watt*.lib.
00147  * Or user didn't include <sys/swap.h> (via tcp.h).
00148  */
00149 #undef intel
00150 #undef intel16
00151 #undef htons
00152 #undef htonl
00153 #undef ntohs
00154 #undef ntohl
00155
00156 DWORD intel (DWORD val)
00157 {
00158   return __ntohl (val);
00159 }
00160
00161 WORD intel16 (WORD val)
00162 {
00163   return __ntohs (val);
00164 }
00165 #endif
00166
00167 #if defined(TEST_PROG)
00168
00169 int main (void)
00170 {
00171   struct date d;
00172   struct time t;
00173   time_t now = time (NULL);
00174
00175   getdate (&d);
00176   gettime (&t);
00177   printf ("time now is: %s", ctime(&now));
00178   now = dostounix (&d, &t);
00179   printf ("dostounix(): %s", ctime(&now));
00180   printf ("unixtodos(): %02d/%02d/%04d %02d:%02d:%02d\n",
00181           d.da_day,  d.da_mon, d.da_year,
00182           t.ti_hour, t.ti_min, t.ti_sec);
00183   return (0);
00184 }
00185 #endif
00186
Generated on Wed Jan 25 15:42:35 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/PACKET32.C Source File

SRC/PACKET32.C

00001 /*
00002  * Copyright (c) 1999 - 2003
00003  * Politecnico di Torino.  All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that: (1) source code distributions
00007  * retain the above copyright notice and this paragraph in its entirety, (2)
00008  * distributions including binary code include the above copyright notice and
00009  * this paragraph in its entirety in the documentation or other materials
00010  * provided with the distribution, and (3) all advertising materials mentioning
00011  * features or use of this software display the following acknowledgement:
00012  * ``This product includes software developed by the Politecnico
00013  * di Torino, and its contributors.'' Neither the name of
00014  * the University nor the names of its contributors may be used to endorse
00015  * or promote products derived from this software without specific prior
00016  * written permission.
00017  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
00018  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
00019  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00020  */
00021
00022  /*
00023   * Changes for Watt-32:
00024   *  - Merged Packet32.c and AdInfo.c into one.
00025   *  - Removed all WanPacket and Dag API support.
00026   *  - Rewritten for ASCII function (no Unicode).
00027   *  - Lots of simplifications.
00028   */
00029 #include <stdio.h>
00030 #include <stdarg.h>
00031 #include <io.h>
00032
00033 #if defined(WIN32) || defined(_WIN32)
00034
00035 #define WIN32_LEAN_AND_MEAN
00036
00037 #include <windows.h>
00038 #include <windowsx.h>       /* GlobalAllocPtr() */
00039 #include <winsvc.h>         /* SERVICE_ALL_ACCESS... */
00040 #include <arpa/inet.h>      /* inet_aton() */
00041 #include <sys/socket.h>     /* AF_INET etc. */
00042 #include <process.h>
00043
00044 #include "wattcp.h"
00045 #include "misc.h"
00046 #include "timer.h"
00047 #include "strings.h"
00048 #include "pcconfig.h"
00049 #include "pcdbug.h"
00050 #include "NtddNdis.h"
00051 #include "cpumodel.h"
00052 #include "packet32.h"
00053
00054 #if defined(USE_DYN_PACKET)
00055 struct dyn_table dyn_funcs;
00056 static HINSTANCE packet_mod = NULL;
00057
00058 static BOOL LoadPacketFunctions (void);
00059
00060 #else
00061
00065 static char npf_driver_version[64] = "Unknown npf.sys version";
00066
00070 static const char NPF_service_name[]      = "NPF";
00071 static const char NPF_service_descr[]     = "Netgroup Packet Filter";
00072 static const char NPF_registry_location[] = "SYSTEM\\CurrentControlSet\\Services\\NPF";
00073 static const char NPF_driver_path[]       = "system32\\drivers\\npf.sys";
00074
00079 static ADAPTER_INFO *adapters_list = NULL;
00080
00086 static HANDLE adapters_mutex = INVALID_HANDLE_VALUE;
00087
00088 static BOOL PopulateAdaptersInfoList (void);
00089 static BOOL FreeAdaptersInfoList (void);
00090 static BOOL GetFileVersion (const char *file_name,
00091                             char *version_buf,
00092                             size_t version_buf_len);
00093 #endif
00094
00095 /*
00096  * Lack of a C99 compiler makes this a bit harder to trace.
00097  */
00098 static const char *trace_func;
00099
00100 #if !defined(USE_DEBUG)
00101   #define WINPCAP_TRACE(args)  ((void)0)
00102 #else
00103   #define WINPCAP_TRACE(args) do { \
00104           trace_line = __LINE__;   \
00105           winpcap_trace args ;     \
00106         } while (0)
00107
00108   static FILE *trace_file = NULL;
00109   static UINT  trace_line;
00110   static DWORD start_tick;
00111
00123   static void PacketDumpRegistryKey (const char *key_name, const char *file_name)
00124   {
00125     char command[256];
00126
00127     /* Let regedit do the dirty work for us
00128      */
00129     _snprintf (command, sizeof(command), "regedit /e %s %s", file_name, key_name);
00130     system (command);
00131   }
00132
00133   static void winpcap_trace (const char *fmt, ...)
00134   {
00135     static BOOL init = FALSE;
00136     va_list args;
00137
00138     if (!trace_file)
00139        return;
00140
00141     if (!init)
00142        fputs ("dT [ms] line\n------------------------------------------"
00143               "------------------------------------------\n", trace_file);
00144     init = TRUE;
00145
00146     fprintf (trace_file, "%5lu, %4u %s(): ", GetTickCount() - start_tick,
00147              trace_line, trace_func);
00148     va_start (args, fmt);
00149     vfprintf (trace_file, fmt, args);
00150     fflush (trace_file);
00151     if (ferror(trace_file))
00152     {
00153       TCP_CONSOLE_MSG (1, ("error writing WinPcap dump file; %s\n",
00154                        strerror(errno)));
00155       fclose (trace_file);
00156       trace_file = NULL;
00157     }
00158     va_end (args);
00159   }
00160 #endif
00161
00165 BOOL PacketInitModule (BOOL init, FILE *dump)
00166 {
00167   BOOL rc;
00168
00169   trace_func = "PacketInitModule";
00170
00171   if (!init)
00172   {
00173     WINPCAP_TRACE (("deinit\n"));
00174
00175 #if defined(USE_DYN_PACKET)
00176     if (packet_mod)
00177        FreeLibrary (packet_mod);
00178     packet_mod = NULL;
00179     rc = TRUE;
00180 #else
00181     FreeAdaptersInfoList();
00182     rc = CloseHandle (adapters_mutex);
00183     adapters_mutex = INVALID_HANDLE_VALUE;
00184 #endif
00185     return (rc);
00186   }
00187
00188 #if defined(USE_DEBUG)
00189   trace_file = dump;
00190   start_tick = GetTickCount();
00191   WINPCAP_TRACE (("init\n"));
00192
00193   if (debug_on >= 5 && !_watt_is_win9x)
00194   {
00195     /* dump a bunch of registry keys
00196      */
00197     PacketDumpRegistryKey (
00198       "HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet"
00199       "\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}",
00200       "adapters.reg");
00201     PacketDumpRegistryKey ("HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet"
00202                            "\\Services\\Tcpip", "tcpip.reg");
00203     PacketDumpRegistryKey ("HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet"
00204                            "\\Services\\NPF", "npf.reg");
00205     PacketDumpRegistryKey ("HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet"
00206                            "\\Services", "services.reg");
00207   }
00208 #endif
00209
00210 #if defined(USE_DYN_PACKET)
00211   rc = LoadPacketFunctions();
00212
00213 #else
00214   /* Create the mutex that will protect the adapter information list
00215    */
00216   adapters_mutex = CreateMutex (NULL, FALSE, NULL);
00217
00218   /* Retrieve NPF.sys version information from the file
00219    */
00220   GetFileVersion ("drivers\\npf.sys", npf_driver_version,
00221                   sizeof(npf_driver_version));
00222
00223   /* Populate the 'adapters_list' list.
00224    */
00225   rc = PopulateAdaptersInfoList();
00226
00227 #if defined(USE_DEBUG)
00228   if (trace_file)
00229   {
00230     const struct ADAPTER_INFO *ai;
00231
00232     fputs ("\nKnown adapters:\n", trace_file);
00233     for (ai = adapters_list; ai; ai = ai->Next)
00234         fprintf (trace_file, "  %s, `%s'\n", ai->Name, ai->Description);
00235     fputs ("\n", trace_file);
00236   }
00237 #endif
00238 #endif
00239
00240   return (rc);
00241 }
00242
00243 #if defined(USE_DYN_PACKET)
00244
00245 typedef void (__cdecl *packet_func) (void);
00246
00247 static BOOL GetPacketFunc (packet_func *func, const char *name)
00248 {
00249   *func = (packet_func) GetProcAddress (packet_mod, name);
00250   trace_func = "GetPacketFunc";
00251   WINPCAP_TRACE (("  %s -> 0x%p\n", name, *func));
00252   if (!*func)
00253      return (FALSE);
00254   return (TRUE);
00255 }
00256
00257 static BOOL LoadPacketFunctions (void)
00258 {
00259   packet_mod = LoadLibrary ("packet.dll");
00260   if (!packet_mod)
00261   {
00262     trace_func = "LoadPacketFunctions";
00263     WINPCAP_TRACE (("Cannot load packet.dll; %s\n", win_strerror(GetLastError())));
00264     return (FALSE);
00265   }
00266   if (!GetPacketFunc((packet_func*)&dyn_funcs.PacketOpenAdapter, "PacketOpenAdapter") ||
00267       !GetPacketFunc((packet_func*)&dyn_funcs.PacketCloseAdapter, "PacketCloseAdapter") ||
00268       !GetPacketFunc((packet_func*)&dyn_funcs.PacketRequest, "PacketRequest") ||
00269       !GetPacketFunc((packet_func*)&dyn_funcs.PacketGetDriverVersion, "PacketGetDriverVersion") ||
00270       !GetPacketFunc((packet_func*)&dyn_funcs.PacketSetMode, "PacketSetMode") ||
00271       !GetPacketFunc((packet_func*)&dyn_funcs.PacketSetBuff, "PacketSetBuff") ||
00272       !GetPacketFunc((packet_func*)&dyn_funcs.PacketSetMinToCopy, "PacketSetMinToCopy") ||
00273       !GetPacketFunc((packet_func*)&dyn_funcs.PacketSetReadTimeout, "PacketSetReadTimeout") ||
00274       !GetPacketFunc((packet_func*)&dyn_funcs.PacketGetStatsEx, "PacketGetStatsEx") ||
00275       !GetPacketFunc((packet_func*)&dyn_funcs.PacketReceivePacket, "PacketReceivePacket") ||
00276       !GetPacketFunc((packet_func*)&dyn_funcs.PacketSendPacket, "PacketSendPacket"))
00277      return (FALSE);
00278   return (TRUE);
00279 }
00280
00281 #else    /* rest of file */
00282
00294 static BOOL PacketSetMaxLookaheadsize (const ADAPTER *AdapterObject)
00295 {
00296   struct {
00297     PACKET_OID_DATA oidData;
00298     DWORD           filler;
00299   } oid;
00300   BOOL rc;
00301
00302   trace_func = "PacketSetMaxLookaheadsize";
00303
00304   /* Set the size of the lookahead buffer to the maximum available
00305    * by the the NIC driver.
00306    */
00307   memset (&oid, 0, sizeof(oid));
00308   oid.oidData.Oid    = OID_GEN_MAXIMUM_LOOKAHEAD;
00309   oid.oidData.Length = sizeof(oid.filler);
00310   rc = PacketRequest (AdapterObject, FALSE, &oid.oidData);
00311
00312   trace_func = "PacketSetMaxLookaheadsize";
00313   WINPCAP_TRACE (("lookahead %lu, rc %d; %s\n",
00314                   *(DWORD*)&oid.oidData, rc,
00315                   !rc ? win_strerror(GetLastError()) : "okay"));
00316
00317   memset (&oid, 0, sizeof(oid));
00318   oid.oidData.Oid    = OID_GEN_CURRENT_LOOKAHEAD;
00319   oid.oidData.Length = sizeof(oid.filler);
00320   rc = PacketRequest (AdapterObject, TRUE, &oid.oidData);
00321
00322   trace_func = "PacketSetMaxLookaheadsize";
00323   WINPCAP_TRACE (("rc %d; %s\n",
00324                   rc, !rc ? win_strerror(GetLastError()) : "okay"));
00325   return (rc);
00326 }
00327
00339 static BOOL PacketSetReadEvt (ADAPTER *AdapterObject)
00340 {
00341   DWORD BytesReturned;
00342   char  EventName[40];
00343   WCHAR EventNameU[20];
00344
00345   trace_func = "PacketSetReadEvt";
00346
00347   /* this tells the terminal service to retrieve the event from the global
00348    * namespace
00349    */
00350   strcpy (EventName, "Global\\");
00351
00352   /* retrieve the Unicode name of the shared event from the driver
00353    */
00354   memset (&EventName, 0, sizeof(EventName));
00355   if (!DeviceIoControl(AdapterObject->hFile, pBIOCEVNAME, NULL, 0,
00356                        EventNameU, sizeof(EventNameU), &BytesReturned, NULL))
00357   {
00358     WINPCAP_TRACE (("error retrieving the event-name from the kernel\n"));
00359     return (FALSE);
00360   }
00361
00362   _snprintf (EventName, sizeof(EventName), "Global\\%.13S", EventNameU);
00363   WINPCAP_TRACE (("  event-name %s\n", EventName));
00364
00365   /* open the shared event
00366    */
00367   AdapterObject->ReadEvent = CreateEvent (NULL, TRUE, FALSE, EventName);
00368
00369   /* On Win-NT4 "Global\" is not automatically ignored: try to use
00370    * simply the event name.
00371    */
00372   if (GetLastError() != ERROR_ALREADY_EXISTS)
00373   {
00374     if (AdapterObject->ReadEvent != INVALID_HANDLE_VALUE)
00375        CloseHandle (AdapterObject->ReadEvent);
00376
00377     /* open the shared event */
00378     AdapterObject->ReadEvent = CreateEvent (NULL, TRUE, FALSE, EventName + 7);
00379   }
00380
00381   if (AdapterObject->ReadEvent == INVALID_HANDLE_VALUE ||
00382       GetLastError() != ERROR_ALREADY_EXISTS)
00383   {
00384     WINPCAP_TRACE (("error retrieving the event from the kernel\n"));
00385     return (FALSE);
00386   }
00387
00388   AdapterObject->ReadTimeOut = 0;  /* block until something received */
00389   return (TRUE);
00390 }
00391
00403 BOOL PacketInstallDriver (SC_HANDLE ascmHandle, SC_HANDLE *srvHandle)
00404 {
00405   BOOL  result = FALSE;
00406   DWORD error  = 0UL;
00407
00408   trace_func = "PacketInstallDriver";
00409   WINPCAP_TRACE (("\n"));
00410
00411   *srvHandle = CreateService (ascmHandle,
00412                               NPF_service_name,
00413                               NPF_service_descr,
00414                               SERVICE_ALL_ACCESS,
00415                               SERVICE_KERNEL_DRIVER,
00416                               SERVICE_DEMAND_START,
00417                               SERVICE_ERROR_NORMAL,
00418                               NPF_driver_path, NULL, NULL,
00419                               NULL, NULL, NULL);
00420   if (!*srvHandle)
00421   {
00422     if (GetLastError() == ERROR_SERVICE_EXISTS)
00423     {
00424       /* npf.sys already exists */
00425       result = TRUE;
00426     }
00427   }
00428   else
00429   {
00430     /* Created service for npf.sys */
00431     result = TRUE;
00432   }
00433
00434   if (result == TRUE && *srvHandle)
00435      CloseServiceHandle (*srvHandle);
00436
00437   if (result == FALSE)
00438   {
00439     error = GetLastError();
00440     if (error != ERROR_FILE_NOT_FOUND)
00441        WINPCAP_TRACE (("failed; %s\n", win_strerror(error)));
00442   }
00443
00444   SetLastError (error);
00445   return (result);
00446 }
00447
00451 static BOOL GetFileVersion (const char *file_name,
00452                             char       *version_buf,
00453                             size_t      version_buf_len)
00454 {
00455   DWORD     ver_info_size;         /* Size of version information block */
00456   DWORD     err, ver_hnd = 0;      /* An 'ignored' parameter, always '0' */
00457   UINT      bytes_read;
00458   char      sub_block[64];
00459   void     *res_buf, *vff_info = NULL;
00460   HINSTANCE mod;
00461   BOOL      rc = FALSE;
00462
00463   DWORD (WINAPI *_GetFileVersionInfoSize) (char *, DWORD*);
00464   BOOL  (WINAPI *_GetFileVersionInfo) (char *, DWORD, DWORD, void *);
00465   BOOL  (WINAPI *_VerQueryValue) (const void **, char *, void **, UINT *);
00466
00467   const struct LANG_AND_CODEPAGE {
00468                WORD language;
00469                WORD code_page;
00470             } *lang_info;
00471   void *lang_info_ptr;
00472
00473   trace_func = "GetFileVersion";
00474
00475   mod = LoadLibrary ("version.dll");
00476   if (!mod)
00477   {
00478     WINPCAP_TRACE (("Didn't find version.dll\n"));
00479     return (FALSE);
00480   }
00481
00482   _GetFileVersionInfoSize = (DWORD (WINAPI*)(char*,DWORD*))
00483                               GetProcAddress (mod, "GetFileVersionInfoSizeA");
00484   _GetFileVersionInfo = (BOOL (WINAPI*)(char*,DWORD,DWORD,void*))
00485                           GetProcAddress (mod, "GetFileVersionInfoA");
00486   _VerQueryValue = (BOOL (WINAPI*)(const void**, char*,void**,UINT*))
00487                      GetProcAddress (mod, "VerQueryValueA");
00488
00489   if (!_GetFileVersionInfoSize || !_GetFileVersionInfo || !_VerQueryValue)
00490   {
00491     WINPCAP_TRACE (("failed to load functons from version.dll\n"));
00492     goto quit;
00493   }
00494
00495   /* Pull out the version information
00496    */
00497   ver_info_size = (*_GetFileVersionInfoSize) ((char*)file_name, &ver_hnd);
00498   WINPCAP_TRACE (("file %s, ver-size %lu\n", file_name, ver_info_size));
00499
00500   if (!ver_info_size)
00501   {
00502     err = GetLastError();
00503     WINPCAP_TRACE (("failed to call GetFileVersionInfoSize; %s\n",
00504                     win_strerror(err)));
00505     goto quit;
00506   }
00507
00508   vff_info = malloc (ver_info_size);
00509   if (!vff_info)
00510   {
00511     WINPCAP_TRACE (("failed to allocate memory\n"));
00512     goto quit;
00513   }
00514
00515   if (!(*_GetFileVersionInfo) ((char*)file_name, ver_hnd,
00516                                ver_info_size, vff_info))
00517   {
00518     WINPCAP_TRACE (("failed to call GetFileVersionInfo\n"));
00519     goto quit;
00520   }
00521
00522   /* Read the list of languages and code pages.
00523    */
00524   if (!(*_VerQueryValue) (vff_info, "\\VarFileInfo\\Translation",
00525                           &lang_info_ptr, &bytes_read) ||
00526       bytes_read < sizeof(*lang_info))
00527   {
00528     WINPCAP_TRACE (("failed to call VerQueryValue\n"));
00529     goto quit;
00530   }
00531   lang_info = (const struct LANG_AND_CODEPAGE*) lang_info_ptr;
00532
00533   /* Create the file version string for the first (i.e. the only
00534    * one) language.
00535    */
00536   sprintf (sub_block, "\\StringFileInfo\\%04x%04x\\FileVersion",
00537            lang_info->language, lang_info->code_page);
00538
00539   /* Retrieve the file version string for the language. 'res_buf' will
00540    * point into 'vff_info'. Hence it doesn't have to b freed.
00541    */
00542   if (!(*_VerQueryValue) (vff_info, sub_block, &res_buf, &bytes_read))
00543   {
00544     WINPCAP_TRACE (("failed to call VerQueryValue\n"));
00545     goto quit;
00546   }
00547
00548   WINPCAP_TRACE (("sub-block '%s' -> '%.*s'\n",
00549                   sub_block, bytes_read, (const char*)res_buf));
00550
00551   if (strlen(res_buf) >= version_buf_len)
00552   {
00553     WINPCAP_TRACE (("input buffer too small\n"));
00554     goto quit;
00555   }
00556   rc = TRUE;
00557   strcpy (version_buf, res_buf);
00558
00559 quit:
00560   if (vff_info)
00561      free (vff_info);
00562   FreeLibrary (mod);
00563   return (rc);
00564 }
00565
00576 static ADAPTER *PacketOpenAdapterNPF (const char *AdapterName)
00577 {
00578   ADAPTER  *lpAdapter;
00579   BOOL      QuerySStat, Result;
00580   DWORD     error, KeyRes;
00581   SC_HANDLE svcHandle = NULL;
00582   HKEY      PathKey;
00583   char      SymbolicLink[128], *npf;
00584   SERVICE_STATUS SStat;
00585   SC_HANDLE      scmHandle;
00586   SC_HANDLE      srvHandle;
00587
00588   trace_func = "PacketOpenAdapterNPF";
00589
00590   WINPCAP_TRACE (("\n"));
00591
00592   scmHandle = OpenSCManager (NULL, NULL, GENERIC_READ);
00593   if (!scmHandle)
00594   {
00595     error = GetLastError();
00596     WINPCAP_TRACE (("OpenSCManager failed; %s\n", win_strerror(error)));
00597   }
00598   else
00599   {
00600     /* Check if the NPF registry key is already present.
00601      * This means that the driver is already installed and that
00602      * we don't need to call PacketInstallDriver
00603      */
00604     KeyRes = RegOpenKeyEx (HKEY_LOCAL_MACHINE, NPF_registry_location,
00605                            0, KEY_READ, &PathKey);
00606     if (KeyRes != ERROR_SUCCESS)
00607     {
00608       Result = PacketInstallDriver (scmHandle, &svcHandle);
00609     }
00610     else
00611     {
00612       Result = TRUE;
00613       RegCloseKey (PathKey);
00614     }
00615
00616     trace_func = "PacketOpenAdapterNPF";
00617
00618     if (Result)
00619     {
00620       srvHandle = OpenService (scmHandle, NPF_service_name,
00621                                SERVICE_START | SERVICE_QUERY_STATUS);
00622       if (srvHandle)
00623       {
00624         QuerySStat = QueryServiceStatus (srvHandle, &SStat);
00625
00626         switch (SStat.dwCurrentState)
00627         {
00628           case SERVICE_CONTINUE_PENDING:
00629                WINPCAP_TRACE (("SERVICE_CONTINUE_PENDING\n"));
00630                break;
00631           case SERVICE_PAUSE_PENDING:
00632                WINPCAP_TRACE (("SERVICE_PAUSE_PENDING\n"));
00633                break;
00634           case SERVICE_PAUSED:
00635                WINPCAP_TRACE (("SERVICE_PAUSED\n"));
00636                break;
00637           case SERVICE_RUNNING:
00638                WINPCAP_TRACE (("SERVICE_RUNNING\n"));
00639                break;
00640           case SERVICE_START_PENDING:
00641                WINPCAP_TRACE (("SERVICE_START_PENDING\n"));
00642                break;
00643           case SERVICE_STOP_PENDING:
00644                WINPCAP_TRACE (("SERVICE_STOP_PENDING\n"));
00645                break;
00646           case SERVICE_STOPPED:
00647                WINPCAP_TRACE (("SERVICE_STOPPED\n"));
00648                break;
00649           default:
00650                WINPCAP_TRACE (("state unknown %98lX\n",
00651                                 SStat.dwCurrentState));
00652                break;
00653         }
00654
00655         if (!QuerySStat || SStat.dwCurrentState != SERVICE_RUNNING)
00656         {
00657           WINPCAP_TRACE (("Calling startservice\n"));
00658           if (!StartService (srvHandle, 0, NULL))
00659           {
00660             error = GetLastError();
00661             if (error != ERROR_SERVICE_ALREADY_RUNNING &&
00662                 error != ERROR_ALREADY_EXISTS)
00663             {
00664               error = GetLastError();
00665               if (scmHandle)
00666                  CloseServiceHandle (scmHandle);
00667               scmHandle = NULL;
00668               WINPCAP_TRACE (("StartService failed; %s\n",
00669                               win_strerror(error)));
00670               SetLastError (error);
00671               return (NULL);
00672             }
00673           }
00674         }
00675         CloseServiceHandle (srvHandle);
00676         srvHandle = NULL;
00677       }
00678       else
00679       {
00680         error = GetLastError();
00681         WINPCAP_TRACE (("OpenService failed; %s\n", win_strerror(error)));
00682         SetLastError (error);
00683       }
00684     }
00685     else
00686     {
00687       if (KeyRes != ERROR_SUCCESS)
00688            Result = PacketInstallDriver (scmHandle, &svcHandle);
00689       else Result = TRUE;
00690
00691       trace_func = "PacketOpenAdapterNPF";
00692
00693       if (Result)
00694       {
00695         srvHandle = OpenService (scmHandle, NPF_service_name, SERVICE_START);
00696         if (srvHandle)
00697         {
00698           QuerySStat = QueryServiceStatus (srvHandle, &SStat);
00699
00700           switch (SStat.dwCurrentState)
00701           {
00702             case SERVICE_CONTINUE_PENDING:
00703                  WINPCAP_TRACE (("SERVICE_CONTINUE_PENDING\n"));
00704                  break;
00705             case SERVICE_PAUSE_PENDING:
00706                  WINPCAP_TRACE (("SERVICE_PAUSE_PENDING\n"));
00707                  break;
00708             case SERVICE_PAUSED:
00709                  WINPCAP_TRACE (("SERVICE_PAUSED\n"));
00710                  break;
00711             case SERVICE_RUNNING:
00712                  WINPCAP_TRACE (("SERVICE_RUNNING\n"));
00713                  break;
00714             case SERVICE_START_PENDING:
00715                  WINPCAP_TRACE (("SERVICE_START_PENDING\n"));
00716                  break;
00717             case SERVICE_STOP_PENDING:
00718                  WINPCAP_TRACE (("SERVICE_STOP_PENDING\n"));
00719                  break;
00720             case SERVICE_STOPPED:
00721                  WINPCAP_TRACE (("SERVICE_STOPPED\n"));
00722                  break;
00723             default:
00724                  WINPCAP_TRACE (("state unknown 0x%08lX\n",
00725                                  SStat.dwCurrentState));
00726                  break;
00727           }
00728
00729           if (!QuerySStat || SStat.dwCurrentState != SERVICE_RUNNING)
00730           {
00731             WINPCAP_TRACE (("Calling startservice\n"));
00732
00733             if (StartService (srvHandle, 0, NULL) == 0)
00734             {
00735               error = GetLastError();
00736               if (error != ERROR_SERVICE_ALREADY_RUNNING &&
00737                   error != ERROR_ALREADY_EXISTS)
00738               {
00739                 if (scmHandle)
00740                    CloseServiceHandle (scmHandle);
00741                 WINPCAP_TRACE (("StartService failed; %s\n",
00742                                 win_strerror(error)));
00743                 SetLastError (error);
00744                 return (NULL);
00745               }
00746             }
00747           }
00748           CloseServiceHandle (srvHandle);
00749         }
00750         else
00751         {
00752           error = GetLastError();
00753           WINPCAP_TRACE (("OpenService failed; %s", win_strerror(error)));
00754           SetLastError (error);
00755         }
00756       }
00757     }
00758   }
00759
00760   if (scmHandle)
00761      CloseServiceHandle (scmHandle);
00762
00763   lpAdapter = GlobalAllocPtr (GMEM_MOVEABLE | GMEM_ZEROINIT,
00764                               sizeof(*lpAdapter));
00765   if (!lpAdapter)
00766   {
00767     WINPCAP_TRACE (("Failed to allocate the adapter structure\n"));
00768     return (NULL);
00769   }
00770
00771   /* skip "\Device" and create a symlink name
00772    */
00773   npf = strstr (AdapterName, "\\NPF_");
00774   _snprintf (SymbolicLink, sizeof(SymbolicLink), "\\\\.\\%s", npf);
00775
00776   /* try if it is possible to open the adapter immediately
00777    */
00778   lpAdapter->hFile = CreateFile (SymbolicLink, GENERIC_WRITE | GENERIC_READ,
00779                                  0, NULL, OPEN_EXISTING, 0, 0);
00780
00781   if (lpAdapter->hFile != INVALID_HANDLE_VALUE)
00782   {
00783     if (!PacketSetReadEvt(lpAdapter))
00784     {
00785       error = GetLastError();
00786       GlobalFreePtr (lpAdapter);
00787       WINPCAP_TRACE (("failed; %s\n", win_strerror(error)));
00788       SetLastError (error);
00789       return (NULL);
00790     }
00791
00792     PacketSetMaxLookaheadsize (lpAdapter);
00793     trace_func = "PacketOpenAdapterNPF";
00794     StrLcpy (lpAdapter->Name, AdapterName, sizeof(lpAdapter->Name));
00795     return (lpAdapter);
00796   }
00797
00798   error = GetLastError();
00799   GlobalFreePtr (lpAdapter);
00800   WINPCAP_TRACE (("CreateFile failed; %s\n", win_strerror(error)));
00801   SetLastError (error);
00802   return (NULL);
00803 }
00804
00808 const char *PacketGetDriverVersion (void)
00809 {
00810   return (npf_driver_version);
00811 }
00812
00813 #ifdef NOT_NEEDED
00814
00825 BOOL PacketStopDriver (void)
00826 {
00827   SC_HANDLE scmHandle;
00828   SC_HANDLE schService;
00829   BOOL      rc = FALSE;
00830
00831   trace_func = "PacketStopDriver";
00832
00833   scmHandle = OpenSCManager (NULL, NULL, SC_MANAGER_ALL_ACCESS);
00834   if (scmHandle)
00835   {
00836     schService = OpenService (scmHandle, NPF_service_name, SERVICE_ALL_ACCESS);
00837     if (schService)
00838     {
00839       SERVICE_STATUS status;
00840
00841       rc = ControlService (schService, SERVICE_CONTROL_STOP, &status);
00842       CloseServiceHandle (schService);
00843       CloseServiceHandle (scmHandle);
00844     }
00845   }
00846
00847   WINPCAP_TRACE (("rc %d\n", rc));
00848   return (rc);
00849 }
00850 #endif
00851
00860 const ADAPTER *PacketOpenAdapter (const char *AdapterName)
00861 {
00862   trace_func = "PacketOpenAdapter";
00863   WINPCAP_TRACE (("trying to open the adapter %s\n", AdapterName));
00864
00865   return PacketOpenAdapterNPF (AdapterName);
00866 }
00867
00874 void PacketCloseAdapter (ADAPTER *adapter)
00875 {
00876   BOOL rc;
00877   int  err = 0;
00878
00879   trace_func = "PacketCloseAdapter";
00880
00881   if (!adapter || adapter->hFile == INVALID_HANDLE_VALUE)
00882   {
00883     WINPCAP_TRACE (("adapter already closed\n"));
00884     return;
00885   }
00886   WINPCAP_TRACE (("adapter file 0x%08lX\n", (DWORD)adapter->hFile));
00887
00888   rc = CloseHandle (adapter->hFile);
00889   adapter->hFile = INVALID_HANDLE_VALUE;
00890   if (!rc)
00891      err = GetLastError();
00892
00893   SetEvent (adapter->ReadEvent);   /* might already be set */
00894   CloseHandle (adapter->ReadEvent);
00895   GlobalFreePtr (adapter);
00896
00897   WINPCAP_TRACE (("CloseHandle() rc %d: %s\n",
00898                   rc, !rc ? win_strerror(err) : "okay"));
00899 }
00900
00916 int PacketReceivePacket (const ADAPTER *adapter, PACKET *pkt, BOOL sync)
00917 {
00918   HANDLE handle;
00919   int    rc = 0;
00920
00921   if ((int)adapter->ReadTimeOut != -1)
00922      WaitForSingleObject (adapter->ReadEvent,
00923                           adapter->ReadTimeOut == 0 ?
00924                           INFINITE : adapter->ReadTimeOut);
00925
00926   handle = adapter->hFile;
00927   if (handle == INVALID_HANDLE_VALUE)
00928        SetLastError (ERROR_INVALID_HANDLE);
00929   else rc = ReadFile (handle, pkt->Buffer, pkt->Length, &pkt->ulBytesReceived, NULL);
00930
00931   trace_func = "PacketReceivePacket";
00932   WINPCAP_TRACE (("rc %d; %s\n",
00933                   rc, rc == 0 ? win_strerror(GetLastError()) : "okay"));
00934   ARGSUSED (sync);
00935   return (rc);
00936 }
00937
00941 int PacketSendPacket (const ADAPTER *AdapterObject, PACKET *pkt, BOOL sync)
00942 {
00943   DWORD BytesTransfered = 0UL;
00944   int   rc;
00945
00946   rc = WriteFile (AdapterObject->hFile, pkt->Buffer, pkt->Length, &BytesTransfered, NULL);
00947
00948   trace_func = "PacketSendPacket";
00949   WINPCAP_TRACE (("rc %d; %s\n",
00950                   rc, rc == 0 ? win_strerror(GetLastError()) : "okay"));
00951   ARGSUSED (sync);
00952   return (rc);
00953 }
00954
00976 BOOL PacketSetMinToCopy (const ADAPTER *AdapterObject, int nbytes)
00977 {
00978   DWORD BytesReturned;
00979   BOOL  rc;
00980
00981   rc = DeviceIoControl (AdapterObject->hFile, pBIOCSMINTOCOPY, &nbytes,
00982                         4, NULL, 0, &BytesReturned, NULL);
00983
00984   trace_func = "PacketSetMinToCopy";
00985   WINPCAP_TRACE (("nbytes %d, rc %d; %s\n",
00986                   nbytes, rc, !rc ? win_strerror(GetLastError()) :
00987                   "okay"));
00988   return (rc);
00989 }
00990
01036 BOOL PacketSetMode (const ADAPTER *AdapterObject, DWORD mode)
01037 {
01038   DWORD BytesReturned;
01039   BOOL  rc;
01040
01041   rc = DeviceIoControl (AdapterObject->hFile, pBIOCSMODE, &mode,
01042                         sizeof(mode), NULL, 0, &BytesReturned, NULL);
01043
01044   trace_func = "PacketSetMode";
01045   WINPCAP_TRACE (("mode %lu, rc %d; %s\n",
01046                   mode, rc, !rc ? win_strerror(GetLastError()) : "okay"));
01047   return (rc);
01048 }
01049
01077 HANDLE PacketGetReadEvent (const ADAPTER *AdapterObject)
01078 {
01079   return (AdapterObject->ReadEvent);
01080 }
01081
01099 BOOL PacketSetReadTimeout (ADAPTER *AdapterObject, int timeout)
01100 {
01101   DWORD BytesReturned;
01102   int   driverTimeout = -1;  /* NPF return immediately if a pkt is ready */
01103   BOOL  rc;
01104
01105   AdapterObject->ReadTimeOut = timeout;
01106
01107   rc = DeviceIoControl (AdapterObject->hFile, pBIOCSRTIMEOUT, &driverTimeout,
01108                         sizeof(driverTimeout), NULL, 0, &BytesReturned, NULL);
01109
01110   trace_func = "PacketSetReadTimeout";
01111   WINPCAP_TRACE (("timeout %d, rc %d; %s\n",
01112                   timeout, rc, !rc ? win_strerror(GetLastError()) : "okay"));
01113   return (rc);
01114 }
01115
01135 BOOL PacketSetBuff (const ADAPTER *AdapterObject, DWORD dim)
01136 {
01137   DWORD BytesReturned;
01138   BOOL  rc;
01139
01140   rc = DeviceIoControl (AdapterObject->hFile, pBIOCSETBUFFERSIZE,
01141                         &dim, sizeof(dim), NULL, 0, &BytesReturned, NULL);
01142
01143   trace_func = "PacketSetBuff";
01144   WINPCAP_TRACE (("size %lu, rc %d; %s\n",
01145                   dim, rc, !rc ? win_strerror(GetLastError()) : "okay"));
01146   return (rc);
01147 }
01148
01149 #ifdef NOT_NEEDED
01150
01173 BOOL PacketSetBpf (const ADAPTER *AdapterObject, const struct bpf_program *fp)
01174 {
01175   DWORD BytesReturned;
01176   BOOL  rc;
01177
01178   rc = DeviceIoControl (AdapterObject->hFile, pBIOCSETF, (char*)fp->bf_insns,
01179                         fp->bf_len * sizeof(struct bpf_insn), NULL, 0,
01180                         &BytesReturned, NULL);
01181
01182   trace_func = "PacketSetBpf";
01183   WINPCAP_TRACE (("rc %d; %s\n",
01184                   rc, !rc ? win_strerror(GetLastError()) : "okay"));
01185   return (rc);
01186 }
01187 #endif
01188
01197 BOOL PacketGetStatsEx (const ADAPTER *AdapterObject, struct bpf_stat *s)
01198 {
01199   struct bpf_stat tmp_stat;
01200   DWORD  BytesReturned;
01201   BOOL   rc;
01202
01203   memset (&tmp_stat, 0, sizeof(tmp_stat));
01204   rc = DeviceIoControl (AdapterObject->hFile,
01205                         pBIOCGSTATS, NULL, 0, &tmp_stat, sizeof(tmp_stat),
01206                         &BytesReturned, NULL);
01207
01208   trace_func = "PacketGetStatsEx";
01209   WINPCAP_TRACE (("rc %d; %s\n",
01210                   rc, !rc ? win_strerror(GetLastError()) : "okay"));
01211
01212   s->bs_recv   = tmp_stat.bs_recv;
01213   s->bs_drop   = tmp_stat.bs_drop;
01214   s->ps_ifdrop = tmp_stat.ps_ifdrop;
01215   s->bs_capt   = tmp_stat.bs_capt;
01216   return (rc);
01217 }
01218
01238 BOOL PacketRequest (const ADAPTER *AdapterObject, BOOL set,
01239                     PACKET_OID_DATA *oidData)
01240 {
01241   DWORD  transfered, in_size, out_size;
01242   DWORD  in_len, out_len;
01243   BOOL   rc;
01244   int    error = 0;
01245   char   prof_buf[100] = "";
01246
01247 #if defined(USE_PROFILER) && defined(USE_DEBUG)
01248   uint64 start = U64_SUFFIX (0);
01249
01250   if (profile_enable && trace_file)
01251      start = get_rdtsc();
01252 #endif
01253
01254   transfered = 0;
01255   in_len   = oidData->Length;
01256   in_size  = sizeof(*oidData) - 1 + oidData->Length;
01257   out_size = in_size;
01258   rc = DeviceIoControl (AdapterObject->hFile,
01259                         set ? pBIOCSETOID : pBIOCQUERYOID,
01260                         oidData, in_size,
01261                         oidData, out_size,
01262                         &transfered, NULL);
01263   out_len = rc ? oidData->Length : 0;
01264
01265   if (!rc)
01266      error = GetLastError();
01267   trace_func = "PacketRequest";
01268
01269 #if defined(USE_PROFILER) && defined(USE_DEBUG)
01270   if (profile_enable && trace_file)
01271   {
01272     int64  clocks = (int64) (get_rdtsc() - start);
01273     double msec   = (double)clocks / ((double)clocks_per_usec * 1000.0);
01274     _snprintf (prof_buf, sizeof(prof_buf), " (%.3f ms)", msec);
01275   }
01276 #endif
01277
01278   WINPCAP_TRACE (("OID 0x%08lX, len %lu/%lu, xfered %lu,%s set %d, rc %d; %s\n",
01279                   oidData->Oid, in_len, out_len, transfered, prof_buf, set,
01280                   rc, !rc ? win_strerror(error) : "okay"));
01281   if (!rc)
01282      SetLastError (error);
01283   return (rc);
01284 }
01285
01286 /*
01287  * Formerly in AdInfo.c:
01288  *
01289  * This file contains the support functions used by packet.dll to retrieve
01290  * information about installed adapters, like
01291  *
01292  * - the adapter list
01293  * - the device associated to any adapter and the description of the adapter
01294  */
01295
01312 static BOOL GetAddressesFromRegistry (const char  *AdapterName,
01313                                       npf_if_addr *buffer,
01314                                       int         *NEntries)
01315 {
01316   struct sockaddr_in *TmpAddr, *TmpBroad;
01317   const char *guid;
01318   HKEY  TcpIpKey = NULL, UnderTcpKey = NULL;
01319   char  String [1024+1];
01320   DWORD RegType, BufLen, StringPos, DHCPEnabled, ZeroBroadcast;
01321   LONG  status;
01322   DWORD line = 0;
01323   int   naddrs, nmasks;
01324
01325   *NEntries = 0;
01326
01327   trace_func = "GetAddressesFromRegistry";
01328
01329   guid = strchr (AdapterName, '{');
01330
01331   WINPCAP_TRACE (("guid %s\n", guid));
01332
01333   if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
01334        "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces",
01335        0, KEY_READ, &UnderTcpKey) == ERROR_SUCCESS)
01336   {
01337     status = RegOpenKeyEx (UnderTcpKey, guid, 0, KEY_READ, &TcpIpKey);
01338     line = __LINE__ - 1;
01339     if (status != ERROR_SUCCESS)
01340        goto fail;
01341   }
01342   else
01343   {
01344     HKEY SystemKey, ParametersKey, InterfaceKey;
01345
01346     /* Query the registry key with the interface's addresses
01347      */
01348     status = RegOpenKeyEx (HKEY_LOCAL_MACHINE,
01349                            "SYSTEM\\CurrentControlSet\\Services",
01350                            0, KEY_READ, &SystemKey);
01351     if (status != ERROR_SUCCESS)
01352        goto fail;
01353
01354     status = RegOpenKeyEx (SystemKey, guid, 0, KEY_READ, &InterfaceKey);
01355     line = __LINE__ - 1;
01356     RegCloseKey (SystemKey);
01357     if (status != ERROR_SUCCESS)
01358        goto fail;
01359
01360     status = RegOpenKeyEx (InterfaceKey, "Parameters", 0, KEY_READ,
01361                            &ParametersKey);
01362     line = __LINE__ - 1;
01363     RegCloseKey (InterfaceKey);
01364     if (status != ERROR_SUCCESS)
01365        goto fail;
01366
01367     status = RegOpenKeyEx (ParametersKey, "TcpIp", 0, KEY_READ, &TcpIpKey);
01368     line = __LINE__ - 1;
01369     RegCloseKey (ParametersKey);
01370     if (status != ERROR_SUCCESS)
01371        goto fail;
01372
01373     BufLen = sizeof(String);
01374   }
01375
01376   BufLen = 4;
01377
01378   /* Try to detect if the interface has a zero broadcast addr
01379    */
01380   status = RegQueryValueEx (TcpIpKey, "UseZeroBroadcast", NULL,
01381                             &RegType, (BYTE*)&ZeroBroadcast, &BufLen);
01382   if (status != ERROR_SUCCESS)
01383      ZeroBroadcast = 0;
01384
01385   BufLen = 4;
01386
01387   /* See if DHCP is used by this system
01388    */
01389   status = RegQueryValueEx (TcpIpKey, "EnableDHCP", NULL,
01390                             &RegType, (BYTE*)&DHCPEnabled, &BufLen);
01391   if (status != ERROR_SUCCESS)
01392      DHCPEnabled = 0;
01393
01394   /* Retrieve the addresses
01395    */
01396   if (DHCPEnabled)
01397   {
01398     WINPCAP_TRACE (("  DHCP enabled\n"));
01399
01400     BufLen = sizeof(String);
01401     status = RegQueryValueEx (TcpIpKey, "DhcpIPAddress", NULL,
01402                               &RegType, (BYTE*)String, &BufLen);
01403     line = __LINE__ - 1;
01404     if (status != ERROR_SUCCESS)
01405        goto fail;
01406
01407     /* scan the key to obtain the addresses
01408      */
01409     StringPos = 0;
01410     for (naddrs = 0; naddrs < MAX_NETWORK_ADDRESSES; naddrs++)
01411     {
01412       TmpAddr = (struct sockaddr_in*) &buffer[naddrs].IPAddress;
01413       WINPCAP_TRACE (("  addr %s\n", String+StringPos));
01414
01415       if (inet_aton(String + StringPos, &TmpAddr->sin_addr))
01416       {
01417         TmpAddr->sin_family = AF_INET;
01418         TmpBroad = (struct sockaddr_in*) &buffer[naddrs].Broadcast;
01419         TmpBroad->sin_family = AF_INET;
01420         if (!ZeroBroadcast)
01421              TmpBroad->sin_addr.s_addr = INADDR_BROADCAST;
01422         else TmpBroad->sin_addr.s_addr = INADDR_ANY;
01423
01424         while (*(String+StringPos))
01425              StringPos++;
01426         StringPos++;
01427
01428         if (*(String + StringPos) == '\0' || StringPos >= BufLen)
01429            break;
01430       }
01431       else
01432         break;
01433     }
01434
01435     BufLen = sizeof(String);
01436
01437     /* Open the key with the netmasks
01438      */
01439     status = RegQueryValueEx (TcpIpKey, "DhcpSubnetMask", NULL,
01440                               &RegType, (BYTE*)String, &BufLen);
01441     line = __LINE__ - 1;
01442     if (status != ERROR_SUCCESS)
01443        goto fail;
01444
01445     /* scan the key to obtain the masks
01446      */
01447     StringPos = 0;
01448     for (nmasks = 0; nmasks < MAX_NETWORK_ADDRESSES; nmasks++)
01449     {
01450       TmpAddr = (struct sockaddr_in*) &buffer[nmasks].SubnetMask;
01451       WINPCAP_TRACE (("  addr %s\n", String+StringPos));
01452
01453       if (inet_aton (String + StringPos, &TmpAddr->sin_addr))
01454       {
01455         TmpAddr->sin_family = AF_INET;
01456
01457         while (*(String + StringPos))
01458               StringPos++;
01459         StringPos++;
01460         if (*(String + StringPos) == '\0' || StringPos >= BufLen)
01461            break;
01462       }
01463       else
01464         break;
01465     }
01466
01467     /* The number of masks MUST be equal to the number of addresses
01468      */
01469     if (nmasks != naddrs)
01470        goto fail;
01471   }
01472   else   /* Not DHCP enabled */
01473   {
01474     WINPCAP_TRACE (("  Not DHCP enabled\n"));
01475
01476     BufLen = sizeof(String);
01477
01478     /* Open the key with the addresses
01479      */
01480     status = RegQueryValueEx (TcpIpKey, "IPAddress", NULL,
01481                               &RegType, (BYTE*)String, &BufLen);
01482     line = __LINE__ - 1;
01483     if (status != ERROR_SUCCESS)
01484        goto fail;
01485
01486     /* scan the key to obtain the addresses
01487      */
01488     StringPos = 0;
01489     for (naddrs = 0; naddrs < MAX_NETWORK_ADDRESSES; naddrs++)
01490     {
01491       TmpAddr = (struct sockaddr_in*) &buffer[naddrs].IPAddress;
01492       WINPCAP_TRACE (("  addr %s\n", String+StringPos));
01493
01494       if (inet_aton (String + StringPos, &TmpAddr->sin_addr))
01495       {
01496         TmpAddr->sin_family = AF_INET;
01497
01498         TmpBroad = (struct sockaddr_in*) &buffer[naddrs].Broadcast;
01499         TmpBroad->sin_family = AF_INET;
01500         if (!ZeroBroadcast)
01501              TmpBroad->sin_addr.s_addr = INADDR_BROADCAST;
01502         else TmpBroad->sin_addr.s_addr = INADDR_ANY;
01503
01504         while (*(String + StringPos))
01505               StringPos++;
01506         StringPos++;
01507
01508         if (*(String + StringPos) == '\0' || StringPos >= BufLen)
01509            break;
01510       }
01511       else
01512         break;
01513     }
01514
01515     /* Open the key with the netmasks
01516      */
01517     BufLen = sizeof(String);
01518     status = RegQueryValueEx (TcpIpKey, "SubnetMask", NULL,
01519                               &RegType, (BYTE*)String, &BufLen);
01520     line = __LINE__ - 1;
01521     if (status != ERROR_SUCCESS)
01522        goto fail;
01523
01524     /* scan the key to obtain the masks
01525      */
01526     StringPos = 0;
01527     for (nmasks = 0; nmasks < MAX_NETWORK_ADDRESSES; nmasks++)
01528     {
01529       TmpAddr = (struct sockaddr_in*) &buffer[nmasks].SubnetMask;
01530       WINPCAP_TRACE (("  mask %s\n", String+StringPos));
01531
01532       if (inet_aton (String + StringPos, &TmpAddr->sin_addr))
01533       {
01534         TmpAddr->sin_family = AF_INET;
01535
01536         while (*(String + StringPos) != 0)
01537               StringPos++;
01538         StringPos++;
01539
01540         if (*(String + StringPos) == 0 || StringPos >= BufLen)
01541            break;
01542       }
01543       else
01544         break;
01545     }
01546
01547     /* The number of masks MUST be equal to the number of addresses
01548      */
01549     if (nmasks != naddrs)
01550        goto fail;
01551   }
01552
01553   *NEntries = naddrs + 1;
01554
01555   RegCloseKey (TcpIpKey);
01556   RegCloseKey (UnderTcpKey);
01557
01558   return (status != ERROR_SUCCESS);
01559
01560 fail:
01561   WINPCAP_TRACE (("failed line %u; %s\n", line, win_strerror(GetLastError())));
01562
01563   if (TcpIpKey)
01564      RegCloseKey (TcpIpKey);
01565   if (UnderTcpKey)
01566      RegCloseKey (UnderTcpKey);
01567   *NEntries = 0;
01568   ARGSUSED (line);
01569   return (FALSE);
01570 }
01571
01581 static BOOL AddAdapter (const char *AdName)
01582 {
01583   struct {
01584     PACKET_OID_DATA oidData;
01585     char            descr[512];
01586   } oid;
01587
01588   ADAPTER_INFO *TmpAdInfo = NULL;
01589   ADAPTER      *adapter   = NULL;
01590   char         *descr, *p;
01591   LONG          Status;
01592   BOOL          rc = FALSE;
01593
01594   trace_func = "AddAdapter";
01595
01596   WINPCAP_TRACE (("adapter %s\n", AdName));
01597
01598   WaitForSingleObject (adapters_mutex, INFINITE);
01599
01600   for (TmpAdInfo = adapters_list; TmpAdInfo; TmpAdInfo = TmpAdInfo->Next)
01601   {
01602     if (!strcmp(AdName, TmpAdInfo->Name))
01603     {
01604       WINPCAP_TRACE (("adapter already present in the list\n"));
01605       ReleaseMutex (adapters_mutex);
01606       return (TRUE);
01607     }
01608   }
01609
01610   TmpAdInfo = NULL;
01611
01612   /* Here we could have released the mutex, but what happens if two
01613    * threads try to add the same adapter? The adapter would be duplicated
01614    * on the linked list.
01615    */
01616
01617   /* Try to Open the adapter
01618    */
01619   adapter = PacketOpenAdapterNPF (AdName);
01620   trace_func = "AddAdapter";
01621
01622   if (!adapter)
01623      goto quit;
01624
01625   /* PacketOpenAdapter() was succesful. Consider this a valid adapter
01626    * and allocate an entry for it In the adapter list.
01627    */
01628   TmpAdInfo = GlobalAllocPtr (GMEM_MOVEABLE | GMEM_ZEROINIT,
01629                               sizeof(*TmpAdInfo));
01630   if (!TmpAdInfo)
01631   {
01632     WINPCAP_TRACE (("GlobalAllocPtr Failed\n"));
01633     goto quit;
01634   }
01635
01637 #if 0
01638   adapter->info = TmpAdInfo;
01639 #endif
01640
01641   /* Copy the device name
01642    */
01643   strcpy (TmpAdInfo->Name, AdName);
01644
01645   /* Query the NIC driver for the adapter description
01646    */
01647   memset (&oid, 0, sizeof(oid));
01648   oid.oidData.Oid    = OID_GEN_VENDOR_DESCRIPTION;
01649   oid.oidData.Length = sizeof(oid.descr);
01650
01651   Status = PacketRequest (adapter, FALSE, &oid.oidData);
01652   trace_func = "AddAdapter";
01653
01654   descr = (char*) oid.oidData.Data;
01655
01656   if (!Status || !*descr)
01657      WINPCAP_TRACE (("failed to get adapter description\n"));
01658
01659   /* Strip trailing newlines and right aligned text in description;
01660    * text separated by TABs or >= 2 spaces.
01661    */
01662   p = strrchr (descr, '\r');
01663   if (p)
01664      *p = '\0';
01665   p = strchr (descr, '\t');
01666   if (p)
01667      *p = '\0';
01668   p = strstr (descr, "  ");
01669   if (p)
01670      *p = '\0';
01671
01672   WINPCAP_TRACE (("adapter Description \"%s\"\n", descr));
01673
01674   /* Save the description
01675    */
01676   strncpy (TmpAdInfo->Description, descr, sizeof(TmpAdInfo->Description));
01677
01678   GetAddressesFromRegistry (TmpAdInfo->Name,
01679                             TmpAdInfo->NetworkAddresses,
01680                             &TmpAdInfo->NNetworkAddresses);
01681
01682   /* Update the AdaptersInfo list
01683    */
01684   TmpAdInfo->Next  = adapters_list;
01685   adapters_list = TmpAdInfo;
01686
01687   rc = TRUE;
01688
01689 quit:
01690   /* Close it; we don't need it until user open it again.
01691    */
01692   if (adapter)
01693      PacketCloseAdapter (adapter);
01694   if (!rc && TmpAdInfo)
01695      GlobalFreePtr (TmpAdInfo);
01696   ReleaseMutex (adapters_mutex);
01697   return (rc);
01698 }
01699
01708 static BOOL PacketGetAdapters (void)
01709 {
01710   HKEY  LinkageKey, AdapKey, OneAdapKey;
01711   DWORD RegKeySize = 0;
01712   DWORD dim, RegType;
01713   char  TName[256];
01714   char  TAName[256];
01715   char  AdapName[256];
01716   const char *guid;
01717   LONG  Status;
01718   int   i = 0;
01719
01720   trace_func = "PacketGetAdapters";
01721   WINPCAP_TRACE (("\n"));
01722
01723   Status = RegOpenKeyEx (HKEY_LOCAL_MACHINE,
01724                          "SYSTEM\\CurrentControlSet\\Control\\Class\\"
01725                          "{4D36E972-E325-11CE-BFC1-08002BE10318}",
01726                          0, KEY_READ, &AdapKey);
01727   i = 0;
01728
01729   if (Status != ERROR_SUCCESS)
01730   {
01731     WINPCAP_TRACE (("RegOpenKeyEx ( Class\\{networkclassguid} ) Failed\n"));
01732     goto nt4;
01733   }
01734
01735   WINPCAP_TRACE (("cycling through the adapters:\n"));
01736
01737   /* Cycle through the entries inside the {4D3..} key
01738    * to get the names of the adapters
01739    */
01740   while (RegEnumKey (AdapKey, i, AdapName, sizeof(AdapName)) == ERROR_SUCCESS)
01741   {
01742     WINPCAP_TRACE (("  loop %d: sub-key %s\n", i, AdapName));
01743     i++;
01744
01745     /* Get the adapter name from the registry key
01746      */
01747     Status = RegOpenKeyEx (AdapKey, AdapName, 0, KEY_READ, &OneAdapKey);
01748     if (Status != ERROR_SUCCESS)
01749     {
01750       WINPCAP_TRACE (("  RegOpenKeyEx (OneAdapKey) Failed\n"));
01751       continue;
01752     }
01753
01754     Status = RegOpenKeyEx (OneAdapKey, "Linkage", 0, KEY_READ, &LinkageKey);
01755     if (Status != ERROR_SUCCESS)
01756     {
01757       RegCloseKey (OneAdapKey);
01758       WINPCAP_TRACE (("  RegOpenKeyEx (LinkageKey) Failed\n"));
01759       continue;
01760     }
01761
01762     dim = sizeof(TName);
01763     Status = RegQueryValueEx (LinkageKey, "Export", NULL, NULL,
01764                               (BYTE*)TName, &dim);
01765     RegCloseKey (OneAdapKey);
01766     RegCloseKey (LinkageKey);
01767     if (Status != ERROR_SUCCESS)
01768     {
01769       WINPCAP_TRACE (("  Name = SKIPPED (error reading the key)\n"));
01770       continue;
01771     }
01772     if (!TName[0])
01773     {
01774       WINPCAP_TRACE (("  Name = SKIPPED (empty name)\n"));
01775       continue;
01776     }
01777     guid = strchr (TName, '{');
01778     if (!guid)
01779     {
01780       WINPCAP_TRACE (("  Name = SKIPPED (missing GUID)\n"));
01781       continue;
01782     }
01783
01784     WINPCAP_TRACE (("  key %d: %s\n", i, TName));
01785
01786     /* Put the \Device\NPF_ string at the beginning of the name
01787      */
01788     _snprintf (TAName, sizeof(TAName), "\\Device\\NPF_%s", guid);
01789
01790     /* If the adapter is valid, add it to the list.
01791      */
01792     AddAdapter (TAName);
01793     trace_func = "PacketGetAdapters";
01794   }
01795
01796   RegCloseKey (AdapKey);
01797
01798 nt4:
01799
01800   /*
01801    * No adapters were found under {4D36E972-E325-11CE-BFC1-08002BE10318}.
01802    * This means with great probability that we are under Win-NT 4, so we
01803    * try to look under the tcpip bindings.
01804    */
01805
01806   if (i == 0)
01807        WINPCAP_TRACE (("Adapters not found under SYSTEM\\CurrentControlSet\\"
01808                        "Control\\Class. Using the TCP/IP bindings.\n"));
01809   else WINPCAP_TRACE (("Trying NT4 bindings anyway\n"));
01810
01811   Status = RegOpenKeyEx (HKEY_LOCAL_MACHINE,
01812                          "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Linkage",
01813                          0, KEY_READ, &LinkageKey);
01814   if (Status == ERROR_SUCCESS)
01815   {
01816     BYTE *bpStr;
01817
01818     /* Retrieve the length of the binding key
01819      */
01820     Status = RegQueryValueEx (LinkageKey, "bind", NULL, &RegType,
01821                               NULL, &RegKeySize);
01822
01823     bpStr = calloc (RegKeySize+1, 1);
01824     if (!bpStr)
01825        return (FALSE);
01826
01827     /* Query the key again to get its content
01828      */
01829     Status = RegQueryValueEx (LinkageKey, "bind", NULL, &RegType,
01830                               bpStr, &RegKeySize);
01831     RegCloseKey (LinkageKey);
01832
01833     /* Loop over the space separated "\Device\{.." strings.
01834      */
01835     for (guid = strchr(bpStr,'{'); guid; guid = strchr(guid+1,'{'))
01836     {
01837       _snprintf (TAName, sizeof(TAName), "\\Device\\NPF_%s", guid);
01838       AddAdapter (TAName);
01839       trace_func = "PacketGetAdapters";
01840     }
01841     free (bpStr);
01842   }
01843   else
01844   {
01845     WINPCAP_TRACE (("Cannot find the TCP/IP bindings"));
01846     return (FALSE);
01847   }
01848   return (TRUE);
01849 }
01850
01857 const ADAPTER_INFO *PacketFindAdInfo (const char *AdapterName)
01858 {
01859   const ADAPTER_INFO *ad_info;
01860
01861   trace_func = "PacketFindAdInfo";
01862   WINPCAP_TRACE (("\n"));
01863
01864   for (ad_info = adapters_list; ad_info; ad_info = ad_info->Next)
01865       if (!strcmp(ad_info->Name, AdapterName))
01866          break;
01867   return (ad_info);
01868 }
01869
01873 const ADAPTER_INFO *PacketGetAdInfo (void)
01874 {
01875   trace_func = "PacketGetAdInfo";
01876   WINPCAP_TRACE (("\n"));
01877
01878   return (adapters_list);
01879 }
01880
01887 static BOOL PopulateAdaptersInfoList (void)
01888 {
01889   BOOL rc = TRUE;
01890
01891   trace_func = "PopulateAdaptersInfoList";
01892   WINPCAP_TRACE (("\n"));
01893
01894   WaitForSingleObject (adapters_mutex, INFINITE);
01895
01896   adapters_list = NULL;
01897
01898   /* Fill the list
01899    */
01900   if (!PacketGetAdapters())
01901   {
01902     WINPCAP_TRACE (("registry scan for adapters failed!\n"));
01903     rc = FALSE;
01904   }
01905   ReleaseMutex (adapters_mutex);
01906   return (rc);
01907 }
01908
01912 static BOOL FreeAdaptersInfoList (void)
01913 {
01914   ADAPTER_INFO *next, *ad_info;
01915
01916   trace_func = "FreeAdaptersInfoList";
01917   WINPCAP_TRACE (("\n"));
01918
01919   WaitForSingleObject (adapters_mutex, INFINITE);
01920
01921   for (ad_info = adapters_list; ad_info; ad_info = next)
01922   {
01923     next = ad_info->Next;
01924     GlobalFreePtr (ad_info);
01925   }
01926
01927   adapters_list = NULL;
01928   ReleaseMutex (adapters_mutex);
01929   return (TRUE);
01930 }
01931 #endif   /* USE_DYN_PACKET */
01932 #endif   /* WIN32 || _WIN32 */
Generated on Wed Jan 25 15:42:36 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/Packet32.h Source File

SRC/Packet32.h

00001 /*
00002  * Copyright (c) 1999 - 2003
00003  * NetGroup, Politecnico di Torino (Italy)
00004  * All rights reserved.
00005  *
00006  * Redistribution and use in source and binary forms, with or without
00007  * modification, are permitted provided that the following conditions
00008  * are met:
00009  *
00010  * 1. Redistributions of source code must retain the above copyright
00011  * notice, this list of conditions and the following disclaimer.
00012  * 2. Redistributions in binary form must reproduce the above copyright
00013  * notice, this list of conditions and the following disclaimer in the
00014  * documentation and/or other materials provided with the distribution.
00015  * 3. Neither the name of the Politecnico di Torino nor the names of its
00016  * contributors may be used to endorse or promote products derived from
00017  * this software without specific prior written permission.
00018  *
00019  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00020  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00021  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
00022  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
00023  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00024  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00025  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00026  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00027  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00028  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00029  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00030  */
00031
00032 #ifndef _w32_PACKET32_H
00033 #define _w32_PACKET32_H
00034
00035 /* Never include old-style BPF stuff here; use the WinPcap
00036  * definition copied in below
00037  */
00038 #define __NET_BPF_H
00039
00040 #ifdef __DMC__
00041 #include <win32/wtypes.h>  /* Has <wtypes.h> in include path */
00042 #endif
00043
00044 #include <netinet/in.h>    /* struct sockaddr_storage */
00045
00046 /* Working modes
00047  */
00048 #define PACKET_MODE_CAPT      0x0                    /* Capture mode */
00049 #define PACKET_MODE_STAT      0x1                    /* Statistical mode */
00050 #define PACKET_MODE_MON       0x2                    /* Monitoring mode */
00051 #define PACKET_MODE_DUMP      0x10                   /* Dump mode */
00052 #define PACKET_MODE_STAT_DUMP (MODE_STAT|MODE_DUMP)  /* Statistical dump Mode */
00053
00054 /*
00055  * Macro definition for defining IOCTL and FSCTL function control codes.  Note
00056  * that function codes 0-2047 are reserved for Microsoft Corporation, and
00057  * 2048-4095 are reserved for customers.
00058  */
00059 #define CTL_CODE(DeviceType, Function, Method, Access) ( \
00060         ((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method) )
00061
00062 /* Define the method codes for how buffers are passed for I/O and FS controls
00063  */
00064 #define METHOD_BUFFERED    0
00065 #define METHOD_IN_DIRECT   1
00066 #define METHOD_OUT_DIRECT  2
00067 #define METHOD_NEITHER     3
00068
00069 /*
00070  * Duplicates from <WinIoCtl.h>:
00071  * The FILE_READ_ACCESS and FILE_WRITE_ACCESS constants are also defined in
00072  * ntioapi.h as FILE_READ_DATA and FILE_WRITE_DATA. The values for these
00073  * constants *MUST* always be in sync.
00074  */
00075 #ifndef FILE_ANY_ACCESS
00076 #define FILE_ANY_ACCESS    0
00077 #endif
00078
00079 #ifndef FILE_READ_ACCESS
00080 #define FILE_READ_ACCESS   0x0001    /* file & pipe */
00081 #endif
00082
00083 #ifndef FILE_READ_ACCESS
00084 #define FILE_WRITE_ACCESS  0x0002    /* file & pipe */
00085 #endif
00086
00087 /* ioctls
00088  */
00089 #ifndef FILE_DEVICE_PROTOCOL
00090 #define FILE_DEVICE_PROTOCOL          0x8000
00091 #endif
00092
00093 #ifndef FILE_DEVICE_PHYSICAL_NETCARD
00094 #define FILE_DEVICE_PHYSICAL_NETCARD  0x0017
00095 #endif
00096
00097 #define IOCTL_PROTOCOL_STATISTICS CTL_CODE (FILE_DEVICE_PROTOCOL, 2, METHOD_BUFFERED, FILE_ANY_ACCESS)
00098 #define IOCTL_PROTOCOL_RESET      CTL_CODE (FILE_DEVICE_PROTOCOL, 3, METHOD_BUFFERED, FILE_ANY_ACCESS)
00099 #define IOCTL_PROTOCOL_READ       CTL_CODE (FILE_DEVICE_PROTOCOL, 4, METHOD_BUFFERED, FILE_ANY_ACCESS)
00100 #define IOCTL_PROTOCOL_WRITE      CTL_CODE (FILE_DEVICE_PROTOCOL, 5, METHOD_BUFFERED, FILE_ANY_ACCESS)
00101 #define IOCTL_PROTOCOL_MACNAME    CTL_CODE (FILE_DEVICE_PROTOCOL, 6, METHOD_BUFFERED, FILE_ANY_ACCESS)
00102 #define IOCTL_OPEN                CTL_CODE (FILE_DEVICE_PROTOCOL, 7, METHOD_BUFFERED, FILE_ANY_ACCESS)
00103 #define IOCTL_CLOSE               CTL_CODE (FILE_DEVICE_PROTOCOL, 8, METHOD_BUFFERED, FILE_ANY_ACCESS)
00104
00105 #define pBIOCSETBUFFERSIZE        9592   /* set kernel buffer size */
00106 #define pBIOCSETF                 9030   /* set packet filtering program */
00107 #define pBIOCGSTATS               9031   /* get the capture stats */
00108 #define pBIOCSRTIMEOUT            7416   /* set the read timeout */
00109 #define pBIOCSMODE                7412   /* set working mode */
00110 #define pBIOCSWRITEREP            7413   /* set number of physical repetions of every packet written by the app. */
00111 #define pBIOCSMINTOCOPY           7414   /* set minimum amount of data in the kernel buffer that unlocks a read call */
00112 #define pBIOCSETOID        2147483648U   /* set an OID value */
00113 #define pBIOCQUERYOID      2147483652U   /* get an OID value */
00114 #define pATTACHPROCESS            7117   /* attach a process to the driver. Used in Win9x only */
00115 #define pDETACHPROCESS            7118   /* detach a process from the driver. Used in Win9x only */
00116 #define pBIOCEVNAME               7415   /* get the name of the event that the driver signals when some data is present in the buffer */
00117 #define pBIOCSETDUMPFILENAME      9029   /* set the name of a the file used by kernel dump mode */
00118 #define pBIOCSENDPACKETSNOSYNC    9032   /* send a buffer containing multiple packets to the network, ignoring the timestamps associated with the packets */
00119 #define pBIOCSENDPACKETSSYNC      9033   /* send a buffer containing multiple packets to the network, respecting the timestamps associated with the packets */
00120 #define pBIOCSETDUMPLIMITS        9034   /* set the dump file limits. See the PacketSetDumpLimits() function */
00121
00122 /* Alignment macro. Defines the alignment size.
00123  */
00124 #define Packet_ALIGNMENT sizeof(int)
00125
00126 /* Alignment macro. Rounds up to the next even multiple of Packet_ALIGNMENT.
00127  */
00128 #define Packet_WORDALIGN(x) (((x) + (Packet_ALIGNMENT-1)) & ~(Packet_ALIGNMENT-1))
00129
00130 #define NdisMediumNull      -1   /* Custom linktype: NDIS doesn't provide an equivalent */
00131 #define NdisMediumCHDLC     -2   /* Custom linktype: NDIS doesn't provide an equivalent */
00132 #define NdisMediumPPPSerial -3   /* Custom linktype: NDIS doesn't provide an equivalent */
00133
00140 typedef struct npf_if_addr {
00141         struct sockaddr_storage IPAddress;
00142         struct sockaddr_storage SubnetMask;
00143         struct sockaddr_storage Broadcast;
00144       } npf_if_addr;
00145
00146
00147 #define MAX_LINK_NAME_LENGTH   64       /* Maximum length of the devices symbolic links */
00148 #define ADAPTER_NAME_LENGTH   (256+12)  /* Max length for the name of an adapter */
00149 #define ADAPTER_DESC_LENGTH    128      /* Max length for the description of an adapter */
00150 #define MAX_MAC_ADDR_LENGTH    8        /* Max length for the link layer address */
00151 #define MAX_NETWORK_ADDRESSES  16       /* Max # of network layer addresses */
00152
00159 typedef struct ADAPTER_INFO {
00160         struct ADAPTER_INFO *Next;
00161         char                 Name [ADAPTER_NAME_LENGTH+1];
00162         char                 Description [ADAPTER_DESC_LENGTH+1];
00163         int                  NNetworkAddresses;
00164         struct npf_if_addr   NetworkAddresses [MAX_NETWORK_ADDRESSES];
00165       } ADAPTER_INFO;
00166
00170 typedef struct ADAPTER {
00171         HANDLE hFile;
00172         HANDLE ReadEvent;
00173         UINT   ReadTimeOut;
00174         char   Name [ADAPTER_NAME_LENGTH];
00175      /* struct ADAPTER_INFO *info;  \todo */
00176       } ADAPTER;
00177
00178
00182 typedef struct PACKET {
00183         HANDLE      hEvent;
00184         OVERLAPPED  OverLapped;
00185         void       *Buffer;
00186         UINT        Length;
00187         DWORD       ulBytesReceived;
00188         BOOLEAN     bIoComplete;
00189       } PACKET;
00190
00199 typedef struct PACKET_OID_DATA {
00200         DWORD  Oid;
00201         DWORD  Length;
00202         BYTE   Data[1];
00203       } PACKET_OID_DATA;
00204
00210 struct bpf_hdr {
00211        struct timeval bh_tstamp;  /* The timestamp associated with the captured packet */
00212        DWORD          bh_caplen;  /* Length of captured portion */
00213        DWORD          bh_datalen; /* Original length of packet */
00214        WORD           bh_hdrlen;  /* Length of bpf header (this struct plus alignment padding) */
00215      };
00216
00217 /* Include the BPF structures here since the WinPcap headers messes
00218  * this up big time.
00219  */
00220 struct bpf_stat {
00221        DWORD bs_recv;   /* # of packets that the driver received from the network adapter */
00222        DWORD bs_drop;   /* # of packets that the driver lost from the beginning of a capture */
00223        DWORD ps_ifdrop; /* drops by interface. XXX not yet supported */
00224        DWORD bs_capt;   /* # of packets that pass the filter */
00225      };
00226
00227 /* The instruction data structure.
00228  */
00229 struct bpf_insn {
00230        WORD  code;
00231        BYTE  jt;
00232        BYTE  jf;
00233        DWORD k;
00234     };
00235
00236 /* Structure for BIOCSETF.
00237  */
00238 struct bpf_program {
00239        DWORD            bf_len;
00240        struct bpf_insn *bf_insns;
00241      };
00242
00243 BOOL PacketInitModule (BOOL init, FILE *dump_file);
00244
00245 #if defined(USE_DYN_PACKET)
00246   struct dyn_table {
00247          const ADAPTER *(__cdecl *PacketOpenAdapter) (const char *);
00248          void           (__cdecl *PacketCloseAdapter) (ADAPTER *);
00249          BOOL           (__cdecl *PacketRequest) (const ADAPTER *, BOOL, PACKET_OID_DATA *);
00250          const char    *(__cdecl *PacketGetDriverVersion) (void);
00251          BOOL           (__cdecl *PacketSetMode) (const ADAPTER *, DWORD);
00252          BOOL           (__cdecl *PacketSetBuff) (const ADAPTER *, DWORD);
00253          BOOL           (__cdecl *PacketSetMinToCopy) (const ADAPTER *, int);
00254          BOOL           (__cdecl *PacketSetReadTimeout) (ADAPTER *, int);
00255          BOOL           (__cdecl *PacketGetStatsEx) (const ADAPTER *, struct bpf_stat *);
00256          BOOL           (__cdecl *PacketReceivePacket) (const ADAPTER *, PACKET *, BOOL);
00257          int            (__cdecl *PacketSendPacket) (const ADAPTER *, PACKET *, BOOL);
00258        };
00259
00260   extern struct dyn_table dyn_funcs;
00261
00262   #define PacketOpenAdapter(name)    (*dyn_funcs.PacketOpenAdapter) (name)
00263   #define PacketCloseAdapter(a)      (*dyn_funcs.PacketCloseAdapter) (a)
00264   #define PacketRequest(a,s,p)       (*dyn_funcs.PacketRequest) (a,s,p)
00265   #define PacketGetDriverVersion()   (*dyn_funcs.PacketGetDriverVersion)()
00266   #define PacketSetMode(a,m)         (*dyn_funcs.PacketSetMode) (a,m)
00267   #define PacketSetBuff(a,s)         (*dyn_funcs.PacketSetBuff) (a,s)
00268   #define PacketSetMinToCopy(a,n)    (*dyn_funcs.PacketSetMinToCopy) (a,n)
00269   #define PacketSetReadTimeout(a,t)  (*dyn_funcs.PacketSetReadTimeout) (a,t)
00270   #define PacketGetStatsEx(a,s)      (*dyn_funcs.PacketGetStatsEx) (a,s)
00271   #define PacketReceivePacket(a,p,s) (*dyn_funcs.PacketReceivePacket) (a,p,s)
00272   #define PacketSendPacket(a,p,s)    (*dyn_funcs.PacketSendPacket) (a,p,s)
00273
00274 #else
00275
00276   const ADAPTER      *PacketOpenAdapter (const char *AdapterName);
00277   const ADAPTER_INFO *PacketFindAdInfo (const char *AdapterName);
00278   const ADAPTER_INFO *PacketGetAdInfo (void);
00279   void                PacketCloseAdapter (ADAPTER *AdapterObject);
00280   BOOL                PacketRequest (const ADAPTER *AdapterObject, BOOL Set, PACKET_OID_DATA *OidData);
00281   const char         *PacketGetDriverVersion (void);
00282
00283   BOOL PacketSetMode (const ADAPTER *AdapterObject, DWORD mode);
00284   BOOL PacketSetBuff (const ADAPTER *AdapterObject, DWORD dim);
00285   BOOL PacketSetMinToCopy (const ADAPTER *AdapterObject, int nbytes);
00286   BOOL PacketSetReadTimeout (ADAPTER *AdapterObject, int timeout);
00287   BOOL PacketGetStatsEx (const ADAPTER *AdapterObject, struct bpf_stat *st);
00288   BOOL PacketReceivePacket (const ADAPTER *AdapterObject, PACKET *pkt, BOOL sync);
00289   int  PacketSendPacket (const ADAPTER *AdapterObject, PACKET *pkt, BOOL sync);
00290
00291 #endif  /* USE_DYN_PACKET */
00292 #endif  /* _w32_PACKET32_H */
Generated on Wed Jan 25 15:42:36 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/PC_CBRK.C Source File

SRC/PC_CBRK.C

Go to the documentation of this file.
00001
00005 #include <stdio.h>
00006 #include <stdlib.h>
00007 #include <setjmp.h>
00008 #include <signal.h>
00009
00010 #include "copyrigh.h"
00011 #include "wattcp.h"
00012 #include "sock_ini.h"
00013 #include "wdpmi.h"
00014 #include "x32vm.h"
00015 #include "misc.h"
00016 #include "printk.h"
00017 #include "bsddbug.h"
00018 #include "language.h"
00019 #include "strings.h"
00020
00021 #ifdef __DJGPP__
00022 #include <sys/exceptn.h>
00023 #endif
00024
00025 #if defined(__HIGHC__)
00026   extern UINT _mwstack_limit[2]; /* stack-check limits */
00027   pragma Alias (_mwstack_limit, "_mwstack_limit");
00028   #undef SIGBREAK        /* SIGBREAK == SIGQUIT */
00029
00030 #elif defined(__DMC__)   /* ditto */
00031   #undef SIGBREAK
00032 #endif
00033
00034 #ifdef TEST_PROG
00035   #include <conio.h>
00036   #undef  outsnl
00037   #define outsnl(str)  cputs (str)
00038 #endif
00039
00044 #include "nochkstk.h"
00045
00046 WORD         _watt_handle_cbreak = 0;
00047 volatile int _watt_cbroke        = 0;
00049 static int cbreak_mode;
00050
00051 #if !defined(WIN32)
00052 static jmp_buf sig_jmp;
00053 #endif
00054
00058 void MS_CDECL sig_handler_watt (int sig)
00059 {
00060 #ifdef TEST_PROG
00061   BEEP();
00062 #endif
00063
00064   if (_watt_handle_cbreak) /* inside _arp_resolve(), lookup_domain() etc. */
00065   {
00066     _watt_cbroke++;
00067     if (cbreak_mode & 0x10)
00068        outsnl (_LANG("\nInterrupting"));
00069   }
00070   else if (cbreak_mode & 1)
00071   {
00072     outsnl (_LANG("\nBreaks ignored"));
00073   }
00074   else
00075   {
00076 #if defined(__HIGHC__)
00077     static UINT new_stk [1024];
00078     _mwstack_limit[1] = (UINT)&new_stk;  /* set new Bottom-Of-Stack */
00079 #elif defined(__DJGPP__)
00080     signal (sig, SIG_IGN);               /* ignore until we quit */
00081 #endif
00082
00083     _watt_cbroke++;
00084
00085 #if defined(WIN32)
00086     return;
00087 #else
00088     longjmp (sig_jmp, sig);
00089 #endif
00090   }
00091
00092   signal (sig, sig_handler_watt);        /* rearm our handler */
00093
00094   /* !! Seems the BREAK state of NTVDM gets reenabled when pressing ^C.
00095    * So disable the state again (not reentrant)
00096    */
00097   if (sig == SIGINT && (cbreak_mode & 1))
00098      set_cbreak (0);
00099 }
00100
00101
00110 int set_cbreak (int want_brk)
00111 {
00112 #if defined(WIN32)
00113   ARGSUSED (want_brk);
00114   return (0);
00115 #else
00116   IREGS reg;
00117   WORD  brk;
00118
00119 #if 0
00120  /*
00121   * After much testing (ref .\tests\pc_cbrk.exe), I found the following
00122   * to be most reliable for both DOS and Windows-NT. Using any combination
00123   * of `cbreak_mode' and pressing ^C seems to work in Win-NT, but ^Break still
00124   * have problems...
00125   */
00126   __djgpp_set_ctrl_c (want_brk & 1);
00127
00128  /* don't count ^Breaks; the 0x1B vector isn't always restored
00129   * at program exit
00130   */
00131   _go32_want_ctrl_break (want_brk & 1);
00132 #endif
00133
00134   reg.r_ax = 0x3300;             /* get normal BREAK state */
00135   GEN_INTERRUPT (0x21, &reg);
00136   brk = loBYTE (reg.r_dx);
00137
00138 #if 0
00139   if (want_brk & 0x0100)
00140   {
00141     reg.r_ax = 0x3302;
00142     GEN_INTERRUPT (0x21, &reg);
00143     brk |= loBYTE(reg.r_dx) << 8;
00144   }
00145 #endif
00146
00147   if (want_brk == 0)
00148   {
00149     reg.r_ax = 0x3301;          /* set normal BREAK state off */
00150     reg.r_dx = 0;
00151     GEN_INTERRUPT (0x21, &reg);
00152     reg.r_ax = 0x3302;          /* set extended BREAK state off */
00153     reg.r_dx = 0;
00154     GEN_INTERRUPT (0x21, &reg);
00155   }
00156   else                    /* set normal/extended BREAK state on */
00157   {
00158     reg.r_ax = (want_brk >= 0x0100) ? 0x3302 : 0x3301;
00159     reg.r_dx = 1;
00160     GEN_INTERRUPT (0x21, &reg);
00161   }
00162   return (brk);
00163 #endif  /* WIN32 */
00164 }
00165
00172 int tcp_cbreak (int mode)
00173 {
00174   volatile int rc = 0;
00175
00176   signal (SIGINT, sig_handler_watt);
00177
00178 #if defined(SIGBREAK)
00179   signal (SIGBREAK, sig_handler_watt);
00180 #endif
00181
00182 #if defined(__DJGPP__)
00183   if (win32_dos_box)
00184      rc = set_cbreak (0);  /* ignore DOS BREAK checking */
00185   else
00186 #endif
00187      rc = set_cbreak (!(mode & 1));
00188
00189   cbreak_mode = mode;
00190
00191 #if !defined(WIN32)
00192   {
00193     int sig;
00194
00195     /* Some vendors calls signal-handlers with a very limited stack.
00196      * We longjmp() out of it to restore to a safe stack.
00197      */
00198     sig = setjmp (sig_jmp);
00199     if (sig)
00200        sock_sig_exit ("\nTerminating.", sig);
00201   }
00202 #endif
00203   return (rc);
00204 }
00205
00206 #if defined(TEST_PROG)
00207
00208 void usage (char *argv0)
00209 {
00210   printf ("Usage: %s normal | nobrk | graceful\n", argv0);
00211   exit (-1);
00212 }
00213
00214 int old_brk = -1;
00215
00216 int main (int argc, char **argv)
00217 {
00218   int mode = 0, show_brk = 1;
00219
00220   if (argc != 2)
00221      usage (argv[0]);
00222
00223   if (!stricmp(argv[1],"normal"))
00224   {
00225     mode = 0x10;
00226     _watt_handle_cbreak = 0;
00227   }
00228   else if (!stricmp(argv[1],"nobrk"))
00229   {
00230     mode = 0x01;
00231     _watt_handle_cbreak = 1;
00232     puts ("Press <^BREAK> three times to exit");
00233   }
00234   else if (!stricmp(argv[1],"graceful"))
00235   {
00236     mode = 0x00;
00237     _watt_handle_cbreak = 1;
00238     puts ("Press <^C> or <^BREAK> three times to exit");
00239   }
00240   else
00241     usage (argv[0]);
00242
00243   if (show_brk)
00244      mode |= 0x10;
00245
00246   old_brk = tcp_cbreak (mode);
00247   _watt_cbroke = 0;
00248
00249   while (_watt_cbroke < 3)
00250   {
00251     usleep (200000);
00252
00253     /* PEEKB on djgpp changes the FS register. This is just to
00254      * test if SIGINT handler restores FS/GS registers.
00255      */
00256     (void) PEEKB (0, 0);
00257     kbhit();
00258     putchar ('.');
00259     fflush (stdout);
00260   }
00261   printf ("`_watt_cbroke' set %d times\n", _watt_cbroke);
00262   set_cbreak (old_brk);
00263   return (1);
00264 }
00265 #endif /* TEST_PROG */
Generated on Wed Jan 25 15:42:36 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/PCARP.C Source File

SRC/PCARP.C

Go to the documentation of this file.
00001
00011 #include <stdio.h>
00012 #include <stdlib.h>
00013 #include <string.h>
00014
00015 #include "copyrigh.h"
00016 #include "wattcp.h"
00017 #include "strings.h"
00018 #include "language.h"
00019 #include "netaddr.h"
00020 #include "misc.h"
00021 #include "timer.h"
00022 #include "rs232.h"
00023 #include "ip4_in.h"
00024 #include "ip4_out.h"
00025 #include "sock_ini.h"
00026 #include "chksum.h"
00027 #include "pcdbug.h"
00028 #include "pctcp.h"
00029 #include "pcsed.h"
00030 #include "pcconfig.h"
00031 #include "pcqueue.h"
00032 #include "pcicmp.h"
00033 #include "pcdhcp.h"
00034 #include "pcpkt.h"
00035 #include "pcarp.h"
00036
00037 #ifndef __inline
00038 #define __inline
00039 #endif
00040
00041 #if defined(USE_SECURE_ARP)
00042   /*
00043    * Allocated here so we don't link in OpenSSL libs by default.
00044    * Application must call sarp_init() before sock_init() to enable.
00045    */
00046   int (*_sarp_recv_hook) (const struct sarp_Packet*) = NULL;
00047   int (*_sarp_xmit_hook) (struct sarp_Packet*)       = NULL;
00048 #endif
00049
00050 /* Local parameters.
00051  */
00052 static int  arp_timeout    = 2;      /* 2 seconds ARP timeout    */
00053 static int  arp_alive      = 300;    /* 5 min ARP cache lifespan */
00054 static int  arp_rexmit_to  = 250;    /* 250 milliseconds per try */
00055 static int  arp_num_cache  = 64;     /* # of entries in ARP cache (not yet) */
00056 static BOOL dead_gw_detect = FALSE;  /* Enable Dead Gateway detection */
00057 static BOOL arp_gratiotous = FALSE;
00058
00059 static BOOL LAN_lookup (DWORD ip, eth_address *eth);
00060 static BOOL is_on_LAN  (DWORD ip);
00061 static void arp_daemon (void);
00062
00066 #define DEAD_GW_TIMEOUT    10000   /* 10 sec */
00067 #define gate_top_of_cache  8
00068
00069 static int gate_top = 0;
00070
00071 static struct gate_entry gate_list [gate_top_of_cache];
00072
00073
00074 #if defined(USE_DEBUG)
00075
00080 int _arp_list_gateways (struct gate_entry *gw, int max)
00081 {
00082   int i;
00083
00084   for (i = 0; i < gate_top && i < max; i++, gw++)
00085   {
00086     memset (gw, 0, sizeof(*gw));
00087     gw->gate_ip = gate_list[i].gate_ip;
00088     gw->subnet  = gate_list[i].subnet;
00089     gw->mask    = gate_list[i].mask;
00090 #if defined(USE_DEAD_GWD)
00091     gw->echo_pending = gate_list[i].echo_pending;
00092     gw->is_dead      = gate_list[i].is_dead;
00093 #endif
00094   }
00095   return (i);
00096 }
00097 #endif
00098
00099 #if defined(USE_DEAD_GWD)
00100
00104 static WORD icmp_id  = 0;
00105 static WORD icmp_seq = 0;
00106
00107 static int ping_gateway (DWORD host, void *eth)
00108 {
00109   struct ping_pkt  *pkt;
00110   struct icmp_echo *icmp;
00111   struct in_Header *ip;
00112   int    len;
00113
00114   pkt  = (struct ping_pkt*) _eth_formatpacket (eth, IP4_TYPE);
00115   ip   = &pkt->in;
00116   icmp = &pkt->icmp;
00117   len  = sizeof (*icmp);
00118   icmp_id = (WORD) set_timeout (0);  /* "random" id */
00119
00120   icmp->type       = ICMP_ECHO;
00121   icmp->code       = 0;
00122   icmp->index      = 1;
00123   icmp->identifier = icmp_id;
00124   icmp->sequence   = icmp_seq++;
00125   icmp->checksum   = 0;
00126   icmp->checksum   = ~CHECKSUM (icmp, len);
00127
00128   return IP4_OUTPUT (ip, 0, intel(host), ICMP_PROTO, 1,
00129                      (BYTE)_default_tos, 0, len, NULL);
00130 }
00131
00132 /*
00133  * This functiom is called once each second.
00134  */
00135 static void check_dead_gw (void)
00136 {
00137   char   buf[20];
00138   static int i = 0;
00139
00140   if (i >= gate_top)
00141       i = 0;
00142
00143   for ( ; i < gate_top; i++)
00144   {
00145     struct gate_entry *gw = &gate_list [i];
00146     eth_address        eth;
00147
00148     if (!is_on_LAN(gw->gate_ip))
00149        continue;
00150
00151     if (!LAN_lookup(gw->gate_ip,&eth))
00152        continue;
00153
00154     if (gw->chk_timer == 0UL || !chk_timeout(gw->chk_timer))
00155     {
00156       gw->chk_timer = set_timeout (DEAD_GW_TIMEOUT);
00157       continue;
00158     }
00159
00160     if (gw->echo_pending &&
00161         _chk_ping(gw->gate_ip,NULL) == (DWORD)-1)
00162     {
00163       gw->is_dead      = TRUE;
00164       gw->echo_pending = FALSE;
00165       TCP_CONSOLE_MSG (1, ("Dead default GW %s (%d) detected\n",
00166                        _inet_ntoa(NULL,gw->gate_ip), i));
00167     }
00168
00169     if (ping_gateway (gw->gate_ip, eth))
00170        gw->echo_pending = TRUE;
00171
00172     gw->chk_timer = set_timeout (DEAD_GW_TIMEOUT);
00173     return;  /* only one ping per interval */
00174   }
00175 }
00176 #endif
00177
00178
00188 BOOL _arp_add_gateway (const char *config_string, DWORD ip)
00189 {
00190   struct gate_entry *gw;
00191   DWORD  subnet = 0UL;
00192   DWORD  mask   = 0UL;
00193   int    i;
00194
00195   SIO_TRACE (("_arp_add_gateway"));
00196
00197   if (config_string)
00198   {
00199     const char* subnetp, *maskp;
00200
00201     /* Get gateways IP address from string
00202      */
00203     ip = aton (config_string);
00204     if (ip == 0)
00205        return (FALSE); /* invalid */
00206
00207     /* Check if optional subnet was supplied
00208      */
00209     subnetp = strchr (config_string, ',');
00210     if (subnetp)
00211     {
00212       /* NB: atoi (used in aton) stops conversion when the first non-number
00213        * is hit, so there is no need to manually null-terminate the string.
00214        * i.e. aton ("123.123.123.123,blabla") = 123.123.123.123
00215        */
00216       subnet = aton (++subnetp);
00217
00218       /* Check if optional mask was supplied
00219        */
00220       maskp = strchr (subnetp, ',');
00221       if (maskp)
00222          mask = aton (++maskp);
00223       else /* No mask was supplied, we derive it from the supplied subnet */
00224       {
00225         switch (subnet >> 30)
00226         {
00227           case  0:
00228           case  1:
00229                 mask = 0xFF000000UL;
00230                 break;
00231           case  2:
00232                 mask = 0xFFFFFE00UL;   /* minimal class B */
00233                 break;
00234           case  3:
00235           default:
00236                 mask = 0xFFFFFF00UL;
00237                 break;
00238         }
00239       }
00240     }
00241   }
00242   else /* (config_string == NULL) */
00243   {
00244     if (ip == 0UL)
00245     {
00246       outsnl ("_arp_add_gateway(): Illegal router");
00247       return (FALSE); /* args invalid */
00248     }
00249   }
00250
00251   /* Figure out where to put our new gateway
00252    */
00253   gw = NULL;
00254
00255   /* Check if gateway is already is in list
00256    */
00257   for (i = 0; i < gate_top; i++)
00258       if (gate_list[i].gate_ip == ip)
00259       {
00260         gw = &gate_list[i];
00261         break;
00262       }
00263
00264   /* If a 'new' gateway, we check if we have enough room and simply
00265    * add it to the end of the list.
00266    *
00267    * There is not much point in sorting the list, as the 'whole' list is
00268    * scanned when a gateway is needed. Usually there will only be 1 anyway.
00269    * If we do sort, we would use plain old insert-sort and NOT quicksort,
00270    * as quicksort goes O(n^2) on an already sorted list, plus it has a high
00271    * overhead that especially hurts on a tiny list like this.
00272    */
00273   if (gw == NULL)
00274   {
00275     if (gate_top+1 >= DIM(gate_list))
00276     {
00277       outsnl (_LANG("Gateway table full"));
00278       return (FALSE);  /* no more room */
00279     }
00280     gw = &gate_list [gate_top++];
00281   }
00282
00283   /* Fill in new entry
00284    */
00285   memset (gw, 0, sizeof(*gw));
00286   gw->gate_ip = ip;
00287   gw->mask    = mask;
00288   gw->subnet  = subnet;
00289   return (TRUE);
00290 }
00291
00295 void _arp_kill_gateways (void)
00296 {
00297   SIO_TRACE (("_arp_kill_gateways"));
00298   gate_top = 0;
00299 }
00300
00304 BOOL _arp_have_default_gw (void)
00305 {
00306   int i, num = 0;
00307
00308   SIO_TRACE (("_arp_have_default_gw"));
00309   for (i = 0; i < gate_top; i++)
00310       if (gate_list[i].subnet == 0UL)
00311          num++;
00312   return (num > 0);
00313 }
00314
00315
00320 /* ARP cache table internal structure:
00321  * \verbatim
00322  *
00323  * Index pointers       ARP cache table
00324  * --------------       ---------------
00325  *
00326  * (top_of_cache) ->
00327  *  (= top_pending)   ----------------------
00328  *                    | ...
00329  *                    | PENDING ARP ENTRIES (requested/ing - no reply yet)
00330  * first_pending ->   | ... grow downwards (into free slots)
00331  *  (= top_free)      ----------------------
00332  *                    | ...
00333  *                    | ...
00334  *                    | FREE SLOTS
00335  *                    | ...
00336  * first_free ---->   | ...
00337  *  (= top_dynamic)   ----------------------
00338  *                    | ... grow upwards (into free slots)
00339  *                    | ...
00340  *                    | "DYNAMIC" ARP ENTRIES
00341  * first_dynamic ->   | ...
00342  *  (= top_fixed)     ----------------------
00343  *                    | ... grow upwards (rolling dynamic entries upwards)
00344  *                    | FIXED ARP ENTRIES
00345  *  (first_dynamic=0) | ...
00346  *                    ----------------------
00347  * \endverbatim
00348  *
00349  * \note
00350  *  - "Top" means last entry + 1.
00351  *  - The entries inside each section are not ordered in any way.
00352  *  - The ARP cache only holds entries of hosts that are on our LAN.
00353  *  - Connections to hosts outside of our LAN are done over a gateway, and
00354  *    the IP of the gateway used (per host) is stored in the "route cache"
00355  *    (below).
00356  */
00357
00358 #define arp_top_of_cache    64
00361 #define arp_top_pending     arp_top_of_cache
00362 #define arp_top_free        arp_first_pending
00363 #define arp_top_dynamic     arp_first_free
00364 #define arp_top_fixed       arp_first_dynamic
00365 #define arp_first_fixed     0
00366
00367 static int arp_first_pending = arp_top_pending;
00368 static int arp_first_free    = 0;
00369 static int arp_first_dynamic = 0;
00370
00371 static struct arp_entry arp_list [arp_top_of_cache];
00372
00376 static __inline BOOL arp_send (const arp_Header *arp, unsigned line)
00377 {
00378   WORD len = sizeof(*arp);
00379
00380   SIO_TRACE (("_arp_send"));
00381
00382 #if defined(USE_SECURE_ARP)
00383   if (_sarp_xmit_hook)  /* put the auth header in */
00384      len = (*_sarp_xmit_hook) ((struct sarp_Packet*)arp);
00385 #else
00386   ARGSUSED (arp);
00387 #endif
00388   return _eth_send (len, NULL, __FILE__, line);
00389 }
00390
00391
00395 static BOOL arp_send_request (DWORD ip)
00396 {
00397   arp_Header *arp = (arp_Header*) _eth_formatpacket (&_eth_brdcast[0], ARP_TYPE);
00398
00399   SIO_TRACE (("_arp_send_request"));
00400
00401   arp->hwType       = intel16 (_eth_get_hwtype(NULL,NULL));
00402   arp->protType     = IP4_TYPE;
00403   arp->hwAddrLen    = sizeof (eth_address);
00404   arp->protoAddrLen = sizeof (ip);
00405   arp->opcode       = ARP_REQUEST;
00406   arp->srcIPAddr    = intel (my_ip_addr);
00407   arp->dstIPAddr    = intel (ip);
00408   memcpy (arp->srcEthAddr, _eth_addr, sizeof(arp->srcEthAddr));
00409   memset (arp->dstEthAddr, 0, sizeof(arp->dstEthAddr));
00410   return arp_send (arp, __LINE__);
00411 }
00412
00413
00418 BOOL _arp_reply (const void *mac_dst, DWORD src_ip, DWORD dst_ip)
00419 {
00420   arp_Header *arp;
00421
00422   SIO_TRACE (("_arp_reply"));
00423
00424   if (!mac_dst)
00425      mac_dst = &_eth_brdcast;
00426
00427   arp = (arp_Header*) _eth_formatpacket (mac_dst, ARP_TYPE);
00428   arp->hwType       = intel16 (_eth_get_hwtype(NULL,NULL));
00429   arp->protType     = IP4_TYPE;
00430   arp->hwAddrLen    = sizeof (mac_address);
00431   arp->protoAddrLen = sizeof (dst_ip);
00432   arp->opcode       = ARP_REPLY;
00433   arp->dstIPAddr    = src_ip;
00434   arp->srcIPAddr    = dst_ip;
00435
00436   memcpy (arp->srcEthAddr, _eth_addr,sizeof(mac_address));
00437   memcpy (arp->dstEthAddr, mac_dst,  sizeof(mac_address));
00438   return arp_send (arp, __LINE__);
00439 }
00440
00444 static __inline void arp_move_entry (int to_index, int from_index)
00445 {
00446   memcpy (&arp_list[to_index], &arp_list[from_index], sizeof(struct arp_entry));
00447 }
00448
00455 static BOOL LAN_start_lookup (DWORD ip)
00456 {
00457   struct arp_entry *ae;
00458   int    i;
00459
00460   SIO_TRACE (("LAN_start_lookup"));
00461
00462   /* Ignore if IP is already in any list section (pending, fixed, dynamic)
00463    */
00464   for (i = arp_first_pending; i < arp_top_pending; i++)
00465       if (arp_list[i].ip == ip)
00466           return (TRUE);
00467
00468   for (i = arp_first_dynamic; i < arp_top_dynamic; i++)
00469       if (arp_list[i].ip == ip)
00470          return (TRUE);
00471
00472   for (i = arp_first_fixed; i < arp_top_fixed; i++)
00473       if (arp_list[i].ip == ip)
00474          return (TRUE);
00475
00476   /* Figure out where to put the new guy
00477    */
00478   if (arp_first_free < arp_top_free) /* Do we have any free slots? */
00479   {
00480     /* yes, ok! */
00481   }
00482   else if (arp_first_dynamic < arp_top_dynamic) /* any dynamic entries? */
00483   {
00484     /* This new request is probably more important than an existing
00485      * dynamic entry, so we sacrifice the top dynamic entry. It might be
00486      * neater to kill the oldest entry, but all this shouldn't happen anyway.
00487      * NB: Table size reallocation would go here.
00488      */
00489     --arp_top_dynamic; /* nuke top entry */
00490     outsnl (_LANG("ARP table overflow"));
00491   }
00492   else /* No more room - table is full with pending + fixed entries. */
00493   {
00494     outsnl (_LANG("ARP table full"));
00495     return (FALSE);       /* failed, nothing we can do right now. */
00496   }
00497
00498   /* Fill new slot, send out ARP request
00499    */
00500   ae = &arp_list [--arp_first_pending];
00501   ae->ip     = ip;
00502   ae->expiry = set_timeout (1000UL * arp_timeout);
00503   ae->flags  = (ARP_INUSE | ARP_PENDING);
00504
00505   /* If request fails, we try again a little sooner
00506    */
00507   if (!arp_send_request(ip))
00508        ae->retransmit_to = set_timeout (arp_rexmit_to / 4);
00509   else ae->retransmit_to = set_timeout (arp_rexmit_to);
00510
00511   return (TRUE);      /* ok, new request logged */
00512 }
00513
00517 static BOOL LAN_lookup (DWORD ip, eth_address *eth)
00518 {
00519   int i;
00520
00521   SIO_TRACE (("LAN_lookup"));
00522
00523   /* Check in dynamic + fixed list section
00524    */
00525   for (i = arp_first_fixed; i < arp_top_dynamic; i++)
00526   {
00527     if (arp_list[i].ip != ip)
00528        continue;
00529     if (eth)
00530        memcpy (eth, arp_list[i].hardware, sizeof(*eth));
00531     return (TRUE);
00532   }
00533   return (FALSE);
00534 }
00535
00539 static BOOL LAN_lookup_pending (DWORD ip)
00540 {
00541   int i;
00542
00543   SIO_TRACE (("LAN_lookup_pending"));
00544
00545   /* Scan pending list section
00546    */
00547   for (i = arp_first_pending; i < arp_top_pending; i++)
00548       if (arp_list[i].ip == ip)
00549          return (TRUE);
00550   return (FALSE);
00551 }
00552
00560 static void arp_check_timeouts (BOOL check_dynamic_entries)
00561 {
00562   struct arp_entry *ae;
00563   int    i;
00564
00565   SIO_TRACE (("arp_check_timeouts"));
00566
00567   /* Check pending entries for retansmit & expiry
00568    */
00569   for (i = arp_first_pending; i < arp_top_pending; i++)
00570   {
00571     ae = &arp_list[i];
00572
00573     /* If entry has expired (without being resolved): kill it
00574      */
00575     if (chk_timeout(ae->expiry))
00576     {
00577       if (i > arp_first_pending)
00578       {
00579         ae->flags &= ~ARP_INUSE;
00580         arp_move_entry (i--, arp_first_pending++); /* fill hole */
00581         continue; /* backed 'i' up a step, now re-check 'new' current entry */
00582       }
00583       ++arp_first_pending;
00584     }
00585     /* If time for a retransmission: do it & restart timeout
00586      */
00587     else if (chk_timeout(ae->retransmit_to))
00588     {
00589       /* If request fails, we try again a little sooner
00590        */
00591       ae->retransmit_to = set_timeout (arp_send_request(ae->ip) ?
00592                                        arp_rexmit_to : arp_rexmit_to / 4);
00593     }
00594   }
00595
00596   /* Check dynamic entries for expiry
00597    */
00598   if (!check_dynamic_entries)
00599      return;
00600
00601   for (i = arp_first_dynamic; i < arp_top_dynamic; i++)
00602   {
00603     ae = &arp_list[i];
00604
00605     if (chk_timeout(ae->expiry))  /* entry has expired: kill it */
00606     {
00607       if (i < --arp_top_dynamic)
00608       {
00609         ae->flags &= ~ARP_INUSE;
00610         arp_move_entry (i--, arp_top_dynamic); /* fill hole */
00611         /* backed 'i' up a step, now re-check 'new' current entry */
00612       }
00613     }
00614   }
00615 }
00616
00617
00622 /* Route table internal structure:
00623  * \verbatim
00624  *
00625  * Index pointers       Route cache table
00626  * --------------       -----------------
00627  *
00628  * (top_of_cache) ->
00629  *  (= top_pending)   ----------------------
00630  *                    | ...
00631  *                    | PENDING ROUTE ENTRIES (ARPing gateway - no reply yet)
00632  * first_pending ->   | ... grow downwards (into free slots)
00633  *  (= top_free)      ----------------------
00634  *                    | ...
00635  *                    | ...
00636  *                    | FREE SLOTS
00637  *                    | ...
00638  * first_free ---->   | ...
00639  *  (= top_dynamic)   ----------------------
00640  *                    | ... grow upwards (into free slots)
00641  *                    | ...
00642  *                    | "DYNAMIC" ROUTE ENTRIES
00643  * first_dynamic ->   | ...
00644  *                    ----------------------
00645  * \endverbatim
00646  *
00647  * \note
00648  *  - "Top" means last entry + 1.
00649  *  - The entries inside each section are not ordered in any way.
00650  *  - The route cache only holds entries of hosts that are OUTSIDE of our LAN.
00651  *  - The entries time out when the gateways ARP cache entry times out.
00652  */
00653
00657 struct route_entry  {
00658        DWORD  host_ip; /* when connection to this host ... */
00659        DWORD  gate_ip; /* ... we use this gateway */
00660      };
00661
00662 #define route_top_of_cache    32
00663 #define route_top_pending     route_top_of_cache
00664 #define route_top_free        route_first_pending
00665 #define route_top_dynamic     route_first_free
00666 #define route_first_dynamic   0
00667
00668 static int route_first_pending = route_top_pending;
00669 static int route_first_free    = 0;
00670
00671 static struct route_entry route_list [route_top_of_cache];
00672
00673 static __inline void route_move_entry (int to_index, int from_index)
00674 {
00675   memcpy (&route_list[to_index], &route_list[from_index],
00676           sizeof(struct route_entry));
00677 }
00678
00679 static BOOL route_makeNewSlot (DWORD host_ip, DWORD gate_ip)
00680 {
00681   struct route_entry *re;
00682
00683   /* We assume IP was already checked for, otherwise we would add it twice.
00684    * Check where we have room.
00685    */
00686   if (route_first_free < route_top_free)
00687   {
00688     /* Ok, free slots available */
00689   }
00690   else if (route_first_dynamic < route_top_dynamic)
00691   {
00692     /* Slaughter first dynamic entry, as new entry probably is more important
00693      */
00694     if (route_first_dynamic < --route_top_dynamic)
00695        route_move_entry (route_first_dynamic, route_top_dynamic);
00696     outsnl (_LANG("Route table overflow"));
00697   }
00698   else
00699   {
00700     outsnl (_LANG("Route table full"));
00701     return (FALSE); /* Nothing we can do - list is full of pending entries */
00702   }
00703
00704   /* Put the new entry in
00705    */
00706   re = &route_list [--route_first_pending];
00707   re->host_ip = host_ip; /* when connection to this host ... */
00708   re->gate_ip = gate_ip; /* ... use this gateway */
00709   return (TRUE);
00710 }
00711
00715 static BOOL is_on_LAN (DWORD ip)
00716 {
00717   return (((ip ^ my_ip_addr) & sin_mask) == 0);
00718 }
00719
00727 BOOL _arp_register (DWORD use_this_gateway_ip, DWORD for_this_host_ip)
00728 {
00729   int i;
00730
00731   SIO_TRACE (("_arp_register"));
00732
00733   /* Only makes sense if ("old") host is outside of our LAN,
00734    * and ("new") gateway is on LAN.
00735    */
00736   if (!is_on_LAN (use_this_gateway_ip) || is_on_LAN (for_this_host_ip))
00737      return (FALSE);
00738
00739   /* See if this guy is in our dynamic table
00740    */
00741   for (i = route_first_dynamic; i < route_top_dynamic; i++)
00742   {
00743     struct route_entry *re = &route_list[i];
00744
00745     if (re->host_ip != for_this_host_ip)
00746        continue;
00747
00748     if (re->gate_ip == use_this_gateway_ip)
00749        return (TRUE); /* Already done */
00750
00751     if (LAN_lookup (use_this_gateway_ip, NULL))
00752     {
00753       re->gate_ip = use_this_gateway_ip;
00754       return (TRUE);  /* New gateway is already in ARP cache, done */
00755     }
00756
00757     if (!LAN_start_lookup (use_this_gateway_ip))
00758     {
00759       outsnl (_LANG ("Unable to add redirect to ARP cache"));
00760       return (FALSE); /* ARP table full */
00761     }
00762
00763     /* Kill 'old' dynamic entry, fill hole
00764      */
00765     if (i < --route_top_dynamic)
00766        route_move_entry (i, route_top_dynamic);
00767
00768     /* Add new request, the new dynamic slot will be created when the
00769      * gateway ARP reply comes
00770      */
00771     return route_makeNewSlot (use_this_gateway_ip, for_this_host_ip);
00772   }
00773
00774   /* Note: We do not check the pending section, as the gateway sending
00775    * the redirect could not really know the best route to a host that
00776    * we have not yet even started to connect to. Redirects referring
00777    * to a pending entry could be some sort of redirect attack.
00778    */
00779   return (FALSE);
00780 }
00781
00785 static BOOL route_lookup (DWORD host_ip, eth_address *eth)
00786 {
00787   int i;
00788
00789   SIO_TRACE (("route_lookup"));
00790
00791   /* 1st, we need to find the gateway entry for the specified host
00792    * in our route table
00793    */
00794   for (i = route_first_dynamic; i < route_top_dynamic; i++)
00795   {
00796     if (route_list[i].host_ip != host_ip)
00797        continue;
00798
00799     /* 2nd, the gateway needs to be in the ARP table
00800      */
00801     return LAN_lookup (route_list[i].gate_ip, eth);
00802   }
00803   return (FALSE); /* host not here */
00804 }
00805
00810 static BOOL route_lookup_pending (DWORD host_ip)
00811 {
00812   int i;
00813
00814   SIO_TRACE (("route_lookup_pending"));
00815
00816   /* Scan our pending list for the supplied host ip
00817    */
00818   for (i = route_first_pending; i < route_top_pending; i++)
00819   {
00820     if (route_list [i].host_ip == host_ip)
00821        return (TRUE);
00822   }
00823   return (FALSE); /* host not here */
00824 }
00825
00829 static BOOL route_start_lookup (DWORD host_ip)
00830 {
00831   DWORD first_gate_ip;
00832   int   i;
00833
00834   SIO_TRACE (("route_start_lookup"));
00835
00836   /* Check if we already have an entry anywhere for this host
00837    */
00838   for (i = route_first_pending; i < route_top_pending; i++)
00839       if (route_list [i].host_ip == host_ip)
00840          return (TRUE);   /* Already here */
00841
00842   for (i = route_first_dynamic; i < route_top_dynamic; i++)
00843       if (route_list [i].host_ip == host_ip)
00844          return (TRUE);   /* Already here */
00845
00846   /* Abort if we don't have any gateways
00847    */
00848   if (gate_top <= 0)
00849   {
00850     outsnl (_LANG ("No gateways defined."));
00851     return (FALSE);
00852   }
00853
00854   /* Find the first 'fitting' gateway
00855    */
00856   first_gate_ip = 0; /* we remember the first gateway IP that fits */
00857
00858   for (i = 0; i < gate_top; i++)
00859   {
00860     struct gate_entry *gw = &gate_list [i];
00861
00862     if (/* !! sin_mask != 0xFFFFFFFFUL && */ !is_on_LAN(gw->gate_ip))
00863        continue;
00864
00865     if ((gw->mask & host_ip) != gw->subnet)
00866        continue;
00867
00868     if (gw->is_dead)
00869        continue;
00870
00871     if (!LAN_start_lookup (gw->gate_ip))
00872     {
00873       outsnl (_LANG ("Unable to add gateway to ARP cache"));
00874       return (FALSE); /* ARP table full, no point in going on right now */
00875     }
00876     first_gate_ip = gw->gate_ip; /* We start with this guy */
00877     break;
00878   }
00879
00880   /* Abort if we didn't find anybody at all to ARP, or all ARPs failed
00881    */
00882   if (first_gate_ip == 0)
00883   {
00884     outsnl (_LANG ("No matching gateway"));
00885     return (FALSE);
00886   }
00887
00888   /* Create a new route cache slot with our guy
00889    */
00890   route_makeNewSlot (host_ip, first_gate_ip);
00891   return (TRUE);
00892 }
00893
00894
00902 static void route_check_timeouts (BOOL check_dynamic_entries)
00903 {
00904   int i, j;
00905
00906   /* Check our pending entries
00907    */
00908   for (i = route_first_pending; i < route_top_pending; i++)
00909   {
00910     struct route_entry *re = &route_list [i];
00911
00912     /* Was the ARP lookup able to resolve the gateway IP?
00913      */
00914     if (LAN_lookup (re->gate_ip, NULL))
00915     {
00916       /* Success - move route entry from pending to dynamic list
00917        */
00918       struct route_entry temp = *re; /* Make a copy so we can safely delete
00919                                       * the pending entry
00920                                       */
00921       if (i > route_first_pending)
00922          route_move_entry (i--, route_first_pending);    /* fill hole */
00923          /* (i-- to "re"check new current entry) */
00924
00925       ++route_first_pending;              /* remove from pending list */
00926       route_list [route_top_dynamic++] = temp; /* add to dynamic list */
00927     }
00928     /* Is the ARP lookup still pending? -> Keep waiting
00929      */
00930     else if (LAN_lookup_pending (re->gate_ip))
00931     {
00932       /* Do nothing */
00933     }
00934     /* The ARP lookup failed, we try the next possible gateway
00935      */
00936     else
00937     {
00938       /* Find the gateway that was tried last (the one that just timed out)
00939        */
00940       BOOL foundLastGateway = FALSE;
00941       BOOL foundNextGateway = FALSE;
00942
00943       for (j = 0; j < gate_top; j++)
00944       {
00945         if (gate_list[j].gate_ip != re->gate_ip)
00946            continue;
00947         foundLastGateway = TRUE;
00948         break;
00949       }
00950
00951       if (!foundLastGateway)
00952          j = -1; /* If search failed, we try the first gateway "again". */
00953
00954       /* Now we look for the next gateway that could be used
00955        */
00956       while (++j < gate_top)
00957       {
00958         struct gate_entry *gw = &gate_list [j];
00959
00960         if (/* !! sin_mask != 0xFFFFFFFFUL && */ !is_on_LAN(gw->gate_ip))
00961            continue;
00962
00963         if ((gw->mask & re->host_ip) != gw->subnet)
00964            continue;
00965
00966         if (!LAN_start_lookup (gw->gate_ip))
00967            break;                  /* No room in ARP table, fail */
00968
00969         re->gate_ip = gw->gate_ip; /* Ok, now we try this gateway */
00970         foundNextGateway = TRUE;
00971         break;
00972       }
00973
00974       /* No more gateways to try, hence lookup failed, kill entry
00975        */
00976       if (!foundNextGateway)
00977       {
00978         if (i > route_first_pending)
00979            route_move_entry (i--, route_first_pending); /* fill hole */
00980         ++route_first_pending;
00981       }
00982     }
00983   }
00984
00985   /* Check our dynamic list for expired entries
00986    */
00987   if (check_dynamic_entries)
00988   {
00989     for (i = route_first_dynamic; i < route_top_dynamic; i++)
00990     {
00991       if (LAN_lookup (route_list [i].gate_ip, NULL))
00992          continue; /* Still in ARP cache - ok */
00993
00994       /* This guy has expired, kill from list
00995        */
00996       if (i < --route_top_dynamic)
00997       {
00998         route_move_entry (i--, route_top_dynamic); /* fill hole */
00999         /* (i backed up a step so 'new' slot is rechecked) */
01000       }
01001     }
01002   }
01003 }
01004
01005
01015 #if !defined(USE_UDP_ONLY)
01016
01021 BOOL arp_start_lookup (DWORD ip)
01022 {
01023   SIO_TRACE (("arp_start_lookup"));
01024
01025   if (_pktserial)     /* Skip if using serial driver */
01026      return (TRUE);
01027
01028   if (is_on_LAN(ip))
01029      return LAN_start_lookup (ip);
01030   return route_start_lookup (ip);
01031 }
01032
01033
01038 BOOL arp_lookup (DWORD ip, eth_address *eth)
01039 {
01040   SIO_TRACE (("arp_lookup"));
01041
01042   /* Check if serial driver, return null MAC
01043    */
01044   if (_pktserial)
01045   {
01046     if (eth)
01047        memset (eth, 0, sizeof(*eth));
01048     return (TRUE);
01049   }
01050
01051   if (_ip4_is_local_addr(ip))
01052   {
01053     if (eth)
01054        memcpy (eth, _eth_addr, sizeof(*eth));
01055     return (TRUE);
01056   }
01057
01058   if (is_on_LAN(ip))
01059      return LAN_lookup (ip, eth);
01060   return route_lookup (ip, eth);
01061 }
01062
01063
01070 BOOL arp_lookup_pending (DWORD ip)
01071 {
01072   SIO_TRACE (("arp_lookup_pending"));
01073
01074   if (is_on_LAN(ip))
01075      return LAN_lookup_pending (ip);
01076   return route_lookup_pending (ip);
01077 }
01078
01083 BOOL arp_lookup_fixed (DWORD ip, eth_address *eth)
01084 {
01085   int i;
01086
01087   SIO_TRACE (("arp_lookup_fixed"));
01088
01089   if (_pktserial)
01090   {
01091     if (eth)
01092        memset (eth, 0, sizeof(*eth));
01093     return (TRUE);
01094   }
01095
01096   if (!is_on_LAN(ip))  /* We only have/need a LAN version */
01097      return (FALSE);
01098
01099   /* Scan fixed table section
01100    */
01101   for (i = arp_first_fixed; i < arp_top_fixed; i++)
01102   {
01103     if (arp_list[i].ip != ip)
01104        continue;
01105     if (eth)
01106        memcpy (eth, arp_list[i].hardware, sizeof(*eth));
01107     return (TRUE);
01108   }
01109   return (FALSE);
01110 }
01111 #endif  /* USE_UDP_ONLY */
01112
01113
01117 BOOL _arp_resolve (DWORD ip, eth_address *eth)
01118 {
01119   WORD   brk_mode;
01120   BOOL (*lookup) (DWORD, eth_address*);
01121   BOOL (*start_lookup) (DWORD);
01122   BOOL (*pending_lookup) (DWORD);
01123   BOOL   rc = FALSE;
01124
01125   SIO_TRACE (("_arp_resolve"));
01126
01127   /* Check if serial driver, return null MAC
01128    */
01129   if (_pktserial)
01130   {
01131     if (eth)
01132        memset (eth, 0, sizeof(*eth));
01133     return (TRUE);
01134   }
01135
01136   /* Check if ip is local address, return own MAC address
01137    */
01138   if (_ip4_is_local_addr(ip))
01139   {
01140     if (eth)
01141        memcpy (eth, _eth_addr, sizeof(*eth));
01142     return (TRUE);
01143   }
01144
01145   /* Quick-check if we have this guy in our cache.
01146    */
01147   if (is_on_LAN(ip))
01148   {
01149     lookup         = LAN_lookup;
01150     start_lookup   = LAN_start_lookup;
01151     pending_lookup = LAN_lookup_pending;
01152   }
01153   else
01154   {
01155     lookup         = route_lookup;
01156     start_lookup   = route_start_lookup;
01157     pending_lookup = route_lookup_pending;
01158   }
01159
01160   if ((*lookup)(ip, eth))
01161      return (TRUE);         /* Ok, done */
01162
01163   /* Put out the request for the MAC
01164    */
01165   if (!(*start_lookup)(ip))
01166   {
01167     TCP_CONSOLE_MSG (2, ("%s (%d): %s() failed\n",
01168                      __FILE__, __LINE__, (start_lookup == LAN_start_lookup) ?
01169                      "LAN_start_lookup" : "route_start_lookup"));
01170     return (FALSE);  /* Request failed, resolve doomed */
01171   }
01172
01173   NEW_BREAK_MODE (brk_mode, 1);
01174
01175   /* Now busy-wait until reply is here or timeout (or Ctrl-C)
01176    */
01177   do
01178   {
01179     tcp_tick (NULL);   /* will call our daemon to timeout/retran */
01180     arp_daemon();      /* added for faster lookup */
01181
01182     if ((*lookup)(ip, eth))
01183     {
01184       rc = TRUE;
01185       break;
01186     }
01187     WATT_YIELD();
01188
01189     if (_watt_cbroke)
01190     {
01191       _watt_cbroke = 0;
01192       break;
01193     }
01194   }
01195   while ((*pending_lookup)(ip));
01196
01197   OLD_BREAK_MODE (brk_mode);
01198   return (rc);
01199 }
01200
01201
01206 BOOL _arp_add_cache (DWORD ip, const void *eth, BOOL expires)
01207 {
01208   struct arp_entry *ae;
01209
01210   SIO_TRACE (("_arp_add_cache"));
01211
01212   if (!my_ip_addr && !expires)
01213   {
01214    /* If called from e.g. pcconfig, my_ip_addr may be 0 when using
01215     * DHCP. Allow adding fixed entries.
01216     */
01217   }
01218   else if (!is_on_LAN (ip))  /* Only makes sense if on our LAN. */
01219      return (FALSE);
01220
01221   _arp_delete_cache (ip);   /* Kill it if already here somewhere */
01222
01223   /* Now add to correct list
01224    */
01225   if (expires) /* dynamic list */
01226   {
01227     if (arp_first_free >= arp_top_free)  /* No free dynamic slots */
01228        return (FALSE);
01229
01230     /* Fill new slot data
01231      */
01232     ae = &arp_list [arp_top_dynamic++];
01233     ae->ip = ip;
01234     memcpy (&ae->hardware, eth, sizeof(ae->hardware));
01235     ae->expiry = set_timeout (1000UL * arp_alive);
01236     ae->flags  = (ARP_INUSE | ARP_DYNAMIC);
01237   }
01238   else   /* fixed list */
01239   {
01240     /* Check if we have any free slots; make room if possible
01241      */
01242     if (arp_first_free >= arp_top_free) /* No more fixed slots? */
01243     {
01244       if (arp_first_dynamic >= arp_top_dynamic)
01245          return (FALSE);   /* No free AND no dynamic slots! */
01246       --arp_top_dynamic;   /* Kill the top dynamic slot to make room */
01247     }
01248
01249     /* Roll dynamic entires up one slot to make room for the new fixed entry
01250      */
01251     if (arp_first_dynamic < arp_top_dynamic)
01252        arp_move_entry (arp_top_dynamic, arp_first_dynamic);
01253     ++arp_top_dynamic;
01254
01255     /* Fill new slot data
01256      */
01257     ae = &arp_list [arp_top_fixed++]; /* implies ++arp_first_dynamic! */
01258     ae->ip    = ip;
01259     ae->flags = (ARP_INUSE | ARP_FIXED);
01260     memcpy (&ae->hardware, eth, sizeof(ae->hardware));
01261   }
01262   return (TRUE);
01263 }
01264
01265
01270 BOOL _arp_delete_cache (DWORD ip)
01271 {
01272   int i;
01273
01274   SIO_TRACE (("_arp_delete_cache"));
01275
01276   /* Remove from dynamic list if present
01277    */
01278   for (i = arp_first_dynamic; i < arp_top_dynamic; i++)
01279   {
01280     if (arp_list[i].ip != ip)
01281        continue;
01282
01283     if (i < --arp_top_dynamic)
01284        arp_move_entry (i, arp_top_dynamic); /* fill hole */
01285     arp_list[i].flags &= ~ARP_INUSE;
01286     return (TRUE);
01287   }
01288
01289   /* Remove from fixed list if present
01290    */
01291   for (i = arp_first_fixed; i < arp_top_fixed; i++)
01292   {
01293     if (arp_list[i].ip != ip)
01294        continue;
01295
01296     if (i < --arp_top_fixed)
01297        arp_move_entry (i, arp_top_fixed); /* fill hole */
01298
01299     /* Do we have any dynamic entries we need to roll down one slot?
01300      * arp_first_dynamic same as arp_top_fixed, already implicity
01301      * decremented above!
01302      */
01303     if (arp_first_dynamic < --arp_top_dynamic)
01304        arp_move_entry (arp_first_dynamic, arp_top_dynamic);
01305     arp_list[i].flags &= ~ARP_INUSE;
01306     return (TRUE);
01307   }
01308
01309   /* Remove from pending list if present
01310    */
01311   for (i = arp_first_pending; i < arp_top_pending; i++)
01312   {
01313     if (arp_list[i].ip != ip)
01314        continue;
01315
01316     if (i > arp_first_pending)
01317        arp_move_entry (i, arp_first_pending); /* fill hole */
01318     ++arp_first_pending;
01319     arp_list[i].flags &= ~ARP_INUSE;
01320     return (TRUE);
01321   }
01322   return (FALSE); /* Didn't have it in cache */
01323 }
01324
01332 static void arp_daemon (void)
01333 {
01334   static BOOL  check_dynamic       = TRUE;
01335   static DWORD check_dynamic_timer = 0UL;
01336
01337   arp_check_timeouts   (check_dynamic);
01338   route_check_timeouts (check_dynamic);
01339
01340   if (check_dynamic)
01341   {
01342 #if defined(USE_DEAD_GWD) /* check dead gateways if we have >1 default GW */
01343     if (dead_gw_detect)
01344     {
01345       if (_arp_have_default_gw() <= 1)
01346            dead_gw_detect = FALSE;
01347       else check_dead_gw();
01348     }
01349 #endif
01350
01351     /* Preset check_dynamic for next call
01352      */
01353     check_dynamic_timer = set_timeout (1000UL);
01354     check_dynamic = FALSE;
01355   }
01356   else if (chk_timeout(check_dynamic_timer))
01357   {
01358     check_dynamic = TRUE;
01359   }
01360 }
01361
01365 static void (*prev_cfg_hook) (const char*, const char*);
01366
01367 static void arp_parse (const char *name, const char *value)
01368 {
01369   static const struct config_table arp_cfg[] = {
01370          { "TIMEOUT",       ARG_ATOI, (void*)&arp_timeout    },
01371          { "RETRANS_TO",    ARG_ATOI, (void*)&arp_rexmit_to  },
01372          { "ALIVE",         ARG_ATOI, (void*)&arp_alive      },
01373          { "NUM_CACHE",     ARG_ATOI, (void*)&arp_num_cache  },
01374          { "DEAD_GW_DETECT",ARG_ATOI, (void*)&dead_gw_detect },
01375          { "GRATIOTOUS",    ARG_ATOI, (void*)&arp_gratiotous },
01376          { NULL,            0,        NULL                   }
01377        };
01378   if (!parse_config_table(&arp_cfg[0], "ARP.", name, value) && prev_cfg_hook)
01379      (*prev_cfg_hook) (name, value);
01380 }
01381
01382 #ifdef NOT_YET
01383 static void (*prev_post_hook) (void);
01384
01385 static void arp_alloc (void)
01386 {
01387   if (arp_num_cache < 10)
01388       arp_num_cache = 10;
01389   arp_list = calloc (sizeof(struct arp_entry), arp_num_cache);
01390   if (!arp_list)
01391   {
01392     outsnl (_LANG("Fatal: failed to allocate ARP-cache"));
01393     exit (-1);
01394   }
01395   if (prev_post_hook)
01396     (*prev_post_hook)();
01397 }
01398 #endif
01399
01403 void _arp_init (void)
01404 {
01405   SIO_TRACE (("_arp_init"));
01406   addwattcpd (arp_daemon);
01407
01408 #ifdef NOT_YET
01409   prev_post_hook  = _watt_post_hook;
01410   _watt_post_hook = arp_alloc;
01411 #endif
01412   prev_cfg_hook   = usr_init;
01413   usr_init        = arp_parse;
01414 }
01415
01416
01421 BOOL _arp_handler (const arp_Header *ah, BOOL brdcast)
01422 {
01423   const eth_address *eth;
01424   WORD  hw_needed = intel16 (_eth_get_hwtype(NULL,NULL));
01425   DWORD src, dst;
01426   BOOL  do_reply = FALSE;
01427   int   i;
01428
01429   SIO_TRACE (("_arp_handler"));
01430
01431   DEBUG_RX (NULL, ah);
01432
01433   if (ah->hwType   != hw_needed ||  /* wrong hardware type, */
01434       ah->protType != IP4_TYPE)     /* or not IPv4-protocol */
01435      return (FALSE);
01436
01437 #if 0
01438   if (ah->hwAddrLen    != sizeof(mac_address) ||
01439       ah->protoAddrLen != sizeof(ip))
01440      return (FALSE);
01441 #endif
01442
01443 #if defined(USE_SECURE_ARP)
01444   if (_sarp_recv_hook)
01445      return (*_sarp_recv_hook) ((const struct sarp_Packet*)ah);
01446 #endif
01447
01448   /* Does someone else want our Ethernet address?
01449    */
01450   if (ah->opcode == ARP_REQUEST)
01451   {
01452     src = intel (ah->srcIPAddr);
01453     dst = intel (ah->dstIPAddr);
01454
01455     if (_ip4_is_local_addr(dst) &&
01456         !_ip4_is_multicast(dst) &&
01457         !_ip4_is_loopback_addr(dst))
01458        do_reply = TRUE;
01459
01460     if (src == my_ip_addr && _pkt_rxmode <= RXMODE_BROADCAST &&
01461         memcmp(&_eth_addr,&ah->srcEthAddr,_eth_mac_len))
01462     {
01463       TCP_CONSOLE_MSG (1, ("Address conflict from %s (%s)\n)",
01464                        _inet_ntoa(NULL,src),
01465                        MAC_address(&ah->srcEthAddr)));
01466     }
01467
01468     /* Prevent anti-sniffers detecting us if we're not in normal rx-mode
01469      */
01470     if (_pkt_rxmode > RXMODE_BROADCAST &&
01471         memcmp(MAC_DST(ah),_eth_brdcast,sizeof(_eth_brdcast))) /* not bcast */
01472        do_reply = FALSE;
01473
01474     if (do_reply)
01475        _arp_reply (&ah->srcEthAddr, ah->srcIPAddr, ah->dstIPAddr);
01476   }
01477
01478   /* See if the senders IP & MAC is anything we can use
01479    */
01480   src = intel (ah->srcIPAddr);
01481   eth = &ah->srcEthAddr;
01482
01483   /* Is this the awaited reply to a pending entry?
01484    */
01485   for (i = arp_first_pending; i < arp_top_pending; i++)
01486   {
01487     struct arp_entry *ae;
01488
01489     if (ah->opcode != ARP_REPLY || arp_list[i].ip != src)
01490        continue;
01491
01492     /* Remove from pending list
01493      */
01494     if (i > arp_first_pending)
01495        arp_move_entry (i, arp_first_pending); /* fill 'hole' */
01496     ++arp_first_pending;
01497     arp_list[i].flags &= ~ARP_PENDING;
01498     arp_list[i].flags &= ~ARP_INUSE;
01499
01500     /* fill new dynamic entry
01501      * (at least one slot is free because we just freed a pending slot)
01502      */
01503     ae = &arp_list [arp_top_dynamic++];
01504     ae->ip    = src;
01505     ae->flags = (ARP_INUSE | ARP_DYNAMIC);
01506
01507     memcpy (&ae->hardware, eth, sizeof(*eth));
01508     ae->expiry = set_timeout (1000UL * arp_alive);
01509     return (TRUE);          /* ARP reply was useful */
01510   }
01511
01512   /* Or is this a 'refresher' of a dynamic entry?
01513    * We'll use both ARP_REQUEST and ARP_REPLY to refresh.
01514    */
01515   for (i = arp_first_dynamic; i < arp_top_dynamic; i++)
01516   {
01517     BOOL  equal;
01518     DWORD timeout;
01519
01520     if (arp_list[i].ip != src)
01521        continue;
01522
01523     /* This could also be an 'ARP poisoning attack', where an attacker is
01524      * trying to slip us a fake MAC address.
01525      * Knowing that, we check if the MAC address has changed, and if so
01526      * prematurely expire the entry. We will re-request it when we need it.
01527      * If the MAC address is 'still' the same, we just restart the timeout.
01528      */
01529     equal = (memcmp(&arp_list[i].hardware, eth, sizeof(*eth)) == 0);
01530
01531     /* if poisoned, we give the 'real guy' 500 ms grace to reclaim his MAC ;)
01532      */
01533     timeout = (equal ? (1000UL * arp_alive) : 500UL);
01534     arp_list[i].expiry = set_timeout (timeout);
01535     return (TRUE);    /* ARP reply was useful */
01536   }
01537
01538   /* Add to cache if we replied.
01539    */
01540   if (do_reply)
01541   {
01542     _arp_add_cache (src, &ah->srcEthAddr, TRUE);
01543     return (TRUE);
01544   }
01545
01546   /* Most TCP stacks add any 'sniffed' ARP replies to their cache in case
01547    * they're needed later. But what are the odds? :)
01548    * Anyway, this could quickly fill the table with 'junk' entries on
01549    * heavily populated LANs; plus it makes us vulnerable to ARP-flooding
01550    * attacks ... so it's probably wiser to just ignore them.
01551    */
01552   ARGSUSED (brdcast);
01553   return (FALSE);  /* i.e. not handled */
01554 }
01555
01556
01557 #if defined(USE_DHCP)
01558
01564 BOOL _arp_check_own_ip (eth_address *other_guy)
01565 {
01566   DWORD save = my_ip_addr;
01567   BOOL  rc;
01568
01569   SIO_TRACE (("_arp_check_own_ip"));
01570
01571   my_ip_addr = 0;
01572   memset (other_guy, 0, sizeof(*other_guy));
01573   rc = _arp_resolve (save, other_guy);
01574   my_ip_addr = save;
01575
01576   if (rc && memcmp(other_guy,(const void*)"\0\0\0\0\0\0",sizeof(*other_guy)))
01577      return (FALSE);
01578   return (TRUE);
01579 }
01580 #endif
01581
01582
01583 #if defined(USE_DEBUG)
01584
01590 int _arp_list_cache (struct arp_entry *arp, int max)
01591 {
01592   int i, num;
01593
01594   for (i = num = 0; i < DIM(arp_list) && i < max; i++)
01595   {
01596     if (!(arp_list[i].flags & ARP_INUSE))
01597        continue;
01598
01599     arp->ip     = arp_list[i].ip;
01600     arp->expiry = arp_list[i].expiry;
01601     arp->flags  = arp_list[i].flags;
01602     memcpy (arp->hardware, arp_list[i].hardware, sizeof(eth_address));
01603     arp++;
01604     num++;
01605   }
01606   return (num);
01607 }
01608
01614 BOOL _arp_check_gateways (void)
01615 {
01616   int i, num = 0;
01617
01618   SIO_TRACE (("_arp_check_gateways"));
01619
01620   /* Send a gratiotous ARP. Don't if already done DHCP_arp_check().
01621    */
01622 #if defined(USE_DHCP)
01623   if (dhcp_did_gratuitous_arp)
01624      arp_gratiotous = FALSE;
01625 #endif
01626
01627   if (arp_gratiotous)
01628      _arp_reply (NULL, intel(IP_BCAST_ADDR), intel(my_ip_addr));
01629
01630   for (i = 0; i < gate_top; i++)
01631       if (gate_list[i].subnet == 0UL)
01632          num++;
01633   return (num == 1);
01634 }
01635
01641 void _arp_debug_dump (void)
01642 {
01643   DWORD now = set_timeout (0UL);
01644   int   i;
01645
01646   /* Gateways
01647    */
01648   if (!dbug_printf ("Gateway list:\n"))
01649      return;
01650
01651   if (gate_top == 0)
01652   {
01653     dbug_printf ("  --none--\n");
01654   }
01655   else for (i = 0; i < gate_top; i++)
01656   {
01657     const struct gate_entry *gw = &gate_list[i];
01658     DWORD mask = gw->mask ? gw->mask : sin_mask;
01659
01660     dbug_printf ("  #%03d: %-15s ", i, _inet_ntoa(NULL, gw->gate_ip));
01661     dbug_printf ("(network: %-15s ", _inet_ntoa(NULL, gw->subnet));
01662     dbug_printf ("mask: %s)\n"   , _inet_ntoa(NULL, mask));
01663   }
01664
01665   /* Route table
01666    */
01667   dbug_printf ("\nRouting cache:\n"
01668                "------- top of cache -----------------------------------------------\n"
01669                "  (%03d) top of pending slots ---------------------------------------\n",
01670                route_top_pending);
01671
01672   if (route_first_pending == route_top_pending)
01673   {
01674     dbug_printf ("        --none--\n");
01675   }
01676   else if (route_first_pending > route_top_pending)
01677   {
01678     dbug_printf ("  INDEX ERROR!\n");
01679   }
01680   else for (i = route_top_pending-1; i >= route_first_pending; i--)
01681   {
01682     const struct route_entry *re = &route_list [i];
01683
01684     dbug_printf ("  #%03d: IP: %-15s -> gateway IP %-15s\n",
01685                  i, _inet_ntoa(NULL,re->host_ip),
01686                  _inet_ntoa(NULL,re->gate_ip));
01687   }
01688
01689   dbug_printf ("- (%03d) top of free slots ------------------------------------------\n",
01690                route_top_free);
01691
01692   if (route_first_free == route_top_free)
01693   {
01694     dbug_printf ("  --none--\n");
01695   }
01696   else if (route_first_free > route_top_free)
01697   {
01698     dbug_printf ("  INDEX ERROR!\n");
01699   }
01700   else if (route_top_free - route_first_free <= 3)
01701   {
01702     for (i = route_top_free-1; i >= route_first_free; i--)
01703         dbug_printf ("  #%03d: (free)\n", i);
01704   }
01705   else
01706   {
01707     dbug_printf ("  #%03d: (free)\n", route_top_free-1);
01708     dbug_printf ("   ...  (free)\n");
01709     dbug_printf ("  #%03d: (free)\n", route_first_free);
01710   }
01711
01712   dbug_printf ("- (%03d) top of dynamic slots ---------------------------------------\n",
01713                route_top_dynamic);
01714   if (route_first_dynamic == route_top_dynamic)
01715   {
01716     dbug_printf ("        --none--\n");
01717   }
01718   else if (route_first_dynamic > route_top_dynamic)
01719   {
01720     dbug_printf ("  INDEX ERROR!\n");
01721   }
01722   else for (i = route_top_dynamic-1; i >= route_first_dynamic; i--)
01723   {
01724     const struct route_entry *re = &route_list [i];
01725
01726     dbug_printf ("  #%03d: IP: %-15s -> gateway IP %-15s\n",
01727                  i, _inet_ntoa(NULL,re->host_ip),
01728                  _inet_ntoa(NULL,re->gate_ip));
01729   }
01730   dbug_printf ("------- bottom of cache --------------------------------------------\n");
01731
01732   /* ARP table
01733    */
01734   dbug_printf ("\nARP cache:\n"
01735                "------- top of cache -----------------------------------------------\n"
01736                "  (%03d) top of pending slots ---------------------------------------\n",
01737                arp_top_pending);
01738
01739   if (arp_first_pending == arp_top_pending)
01740   {
01741     dbug_printf ("        --none--\n");
01742   }
01743   else if (arp_first_pending > arp_top_pending)
01744   {
01745     dbug_printf ("  INDEX ERROR!\n");
01746   }
01747   else for (i = arp_top_pending-1; i >= arp_first_pending; i--)
01748   {
01749     const struct arp_entry *ae = &arp_list [i];
01750
01751     dbug_printf ("  #%03d: IP: %-15s -> ??:??:??:??:??:??  expires in %ss\n",
01752                  i, _inet_ntoa(NULL, ae->ip), time_str(ae->expiry - now));
01753   }
01754
01755   dbug_printf ("- (%03d) top of free slots ------------------------------------------\n",
01756                arp_top_free);
01757   if (arp_first_free == arp_top_free)
01758   {
01759     dbug_printf ("  --none--\n");
01760   }
01761   else if (arp_first_free > arp_top_free)
01762   {
01763     dbug_printf ("  INDEX ERROR!\n");
01764   }
01765   else if (arp_top_free - arp_first_free <= 3)
01766   {
01767     for (i = arp_top_free-1; i >= arp_first_free; i--)
01768         dbug_printf ("  #%03d: (free)\n", i);
01769   }
01770   else
01771   {
01772     dbug_printf ("  #%03d: (free)\n", arp_top_free-1);
01773     dbug_printf ("   ...  (free)\n");
01774     dbug_printf ("  #%03d: (free)\n", arp_first_free);
01775   }
01776
01777   dbug_printf ("- (%03d) top of dynamic slots ---------------------------------------\n",
01778                arp_top_dynamic);
01779   if (arp_first_dynamic == arp_top_dynamic)
01780   {
01781     dbug_printf ("        --none--\n");
01782   }
01783   else if (arp_first_dynamic > arp_top_dynamic)
01784   {
01785     dbug_printf ("  INDEX ERROR!\n");
01786   }
01787   else for (i = arp_top_dynamic-1; i >= arp_first_dynamic; i--)
01788   {
01789     const struct arp_entry *ae = &arp_list [i];
01790
01791     dbug_printf ("  #%03d: IP: %-15s -> %s  expires in %ss\n",
01792                  i, _inet_ntoa(NULL,ae->ip), MAC_address(&ae->hardware),
01793                  time_str(ae->expiry - now));
01794   }
01795
01796   dbug_printf ("- (%03d) top of fixed slots -----------------------------------------\n",
01797                arp_top_fixed);
01798   if (arp_first_fixed == arp_top_fixed)
01799   {
01800     dbug_printf ("        --none--\n");
01801   }
01802   else if (arp_first_fixed > arp_top_fixed)
01803   {
01804     dbug_printf ("  INDEX ERROR!\n");
01805   }
01806   else for (i = arp_top_fixed-1; i >= arp_first_fixed; i--)
01807   {
01808     const struct arp_entry *ae = &arp_list [i];
01809
01810     dbug_printf ("  #%03d: IP: %-15s -> %s\n",
01811                  i, _inet_ntoa(NULL,ae->ip), MAC_address(&ae->hardware));
01812   }
01813   dbug_printf ("------- bottom of cache --------------------------------------------\n");
01814 }
01815 #endif  /* USE_DEBUG */
Generated on Wed Jan 25 15:42:36 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/PCARP.H Source File

SRC/PCARP.H

Go to the documentation of this file.
00001
00004 #ifndef _w32_PCARP_H
00005 #define _w32_PCARP_H
00006
00007
00011 struct gate_entry {
00012        DWORD  gate_ip;
00013        DWORD  subnet;
00014        DWORD  mask;
00015        BOOL   is_dead;       /* Dead Gate detection: */
00016        BOOL   echo_pending;  /*   echo-rply pending */
00017        DWORD  chk_timer;     /*   check interval timer */
00018      };
00019
00023 struct arp_entry {
00024        DWORD       ip;
00025        eth_address hardware;
00026        DWORD       expiry;
00027        DWORD       retransmit_to;
00028        WORD        flags;
00029      };
00030
00033 #define ARP_INUSE   0x01
00034 #define ARP_FIXED   0x02
00035 #define ARP_DYNAMIC 0x04
00036 #define ARP_PENDING 0x08
00040 W32_FUNC int  _arp_list_gateways (struct gate_entry *gw, int max);
00041 extern   BOOL _arp_add_gateway  (const char* config_string, DWORD ip);
00042 extern   BOOL _arp_check_gateways (void);
00043 extern   BOOL _arp_have_default_gw (void);
00044 extern   void _arp_kill_gateways (void); /* GvB, replaces global variable */
00045
00050 W32_FUNC BOOL _arp_resolve      (DWORD ina, eth_address *eth);
00051 W32_FUNC BOOL _arp_check_own_ip (eth_address *eth);
00052
00055 extern BOOL  arp_start_lookup   (DWORD ip);
00056 extern BOOL  arp_lookup         (DWORD ip, eth_address *eth);
00057 extern BOOL  arp_lookup_fixed   (DWORD ip, eth_address *eth);
00058 extern BOOL  arp_lookup_pending (DWORD ip);
00059
00062 extern   BOOL _arp_add_cache (DWORD ip, const void *eth, BOOL expire);
00063 extern   BOOL _arp_delete_cache (DWORD ip);
00064 W32_FUNC int  _arp_list_cache (struct arp_entry *arp, int max);
00065
00068 extern void _arp_init (void);
00069 extern BOOL _arp_reply  (const void *mac_dst, DWORD src_ip, DWORD dst_ip);
00070 extern BOOL _arp_handler (const arp_Header *arp, BOOL brdcast);
00071
00074 extern BOOL _arp_register (DWORD use_this_gateway_ip, DWORD for_this_host_ip);
00075
00076 #if defined(USE_DEBUG)
00077   W32_FUNC void _arp_debug_dump (void);
00078 #endif
00079
00080 #if defined(USE_SECURE_ARP)
00081   #include "pcsarp.h"
00082
00083   W32_DATA BOOL (*_sarp_recv_hook) (const struct sarp_Packet *sarp);
00084   W32_DATA BOOL (*_sarp_xmit_hook) (struct sarp_Packet *sarp);
00085 #endif
00086
00087 #endif
Generated on Wed Jan 25 15:42:36 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/PCBOOTP.C Source File

SRC/PCBOOTP.C

Go to the documentation of this file.
00001
00013 #include <stdio.h>
00014 #include <stdlib.h>
00015
00016 #include "copyrigh.h"
00017 #include "wattcp.h"
00018 #include "strings.h"
00019 #include "language.h"
00020 #include "udp_dom.h"
00021 #include "syslog2.h"
00022 #include "misc.h"
00023 #include "timer.h"
00024 #include "netaddr.h"
00025 #include "pctcp.h"
00026 #include "pcsed.h"
00027 #include "pcarp.h"
00028 #include "pcconfig.h"
00029 #include "pcqueue.h"
00030 #include "pcpkt.h"
00031 #include "pcbootp.h"
00032
00033 DWORD _bootp_host = IP_BCAST_ADDR;
00034
00035 #if defined(USE_DHCP)
00036   int _bootp_timeout = 15;  /* give DHCP a chance also (sock_delay=30) */
00037 #else
00038   int _bootp_timeout = 30;
00039 #endif
00040
00041 #if defined(USE_BOOTP)
00042
00043 static sock_type *boot_sock;
00044
00045 static int  bootp_xmit  (struct bootp *bootp_out);
00046 static BOOL bootp_recv  (struct bootp *bootp_out, struct bootp *bootp_in);
00047 static void bootp_parse (const struct bootp *bootp_in, int len);
00048
00058 int BOOTP_do_boot (void)
00059 {
00060   struct bootp       bootp_out, bootp_in;
00061   struct _udp_Socket sock;
00062   DWORD  save_ip = my_ip_addr;
00063   int    rc = 0;
00064
00065   boot_sock = (sock_type*) &sock;
00066
00067   outs (_LANG("Configuring through BOOTP.."));
00068
00069   my_ip_addr = 0UL;   /* We must use IP address 0.0.0.0 for sending */
00070
00071   if (!udp_open(&sock,IPPORT_BOOTPC,_bootp_host,IPPORT_BOOTPS,NULL))
00072   {
00073     outsnl (boot_sock->udp.err_msg);
00074     my_ip_addr = save_ip;
00075   }
00076   else
00077   {
00078     bootp_xmit (&bootp_out);
00079     if (bootp_recv(&bootp_out, &bootp_in))
00080     {
00081       my_ip_addr = intel (bootp_in.bp_yiaddr);
00082       rc = 1;
00083     }
00084   }
00085   sock_close (boot_sock);
00086   boot_sock = NULL;
00087   outsnl (rc ? "okay" : "failed");
00088   return (rc);
00089 }
00090
00091 static int bootp_xmit (struct bootp *bootp_out)
00092 {
00093   DWORD xid = set_timeout (0);  /* "random" exchange ID */
00094
00095   memset (bootp_out, 0, sizeof(*bootp_out));
00096   _eth_get_hwtype (&bootp_out->bp_htype, &bootp_out->bp_hlen);
00097
00098   bootp_out->bp_op   = BOOTP_REQUEST;
00099   bootp_out->bp_xid  = xid;
00100   bootp_out->bp_secs = intel16 (((WORD)xid & 7) + 7);
00101   *(DWORD*) &bootp_out->bp_vend = intel (VM_RFC1048);  /* Magic Number */
00102
00103   memcpy (&bootp_out->bp_chaddr, _eth_addr, sizeof(eth_address));
00104   return sock_fastwrite (boot_sock, (BYTE*)bootp_out, sizeof(*bootp_out));
00105 }
00106
00107 static BOOL bootp_recv (struct bootp *bootp_out, struct bootp *bootp_in)
00108 {
00109   DWORD exchange_id = bootp_out->bp_xid;
00110   DWORD boot_timer  = set_timeout (1000 * _bootp_timeout);
00111
00112   while (1)
00113   {
00114     DWORD vendor;
00115     int   len;
00116
00117     WATT_YIELD();
00118
00119     if (chk_timeout(boot_timer) || !tcp_tick(boot_sock))
00120        return (FALSE);
00121
00122     if (sock_dataready(boot_sock) < sizeof(*bootp_in))
00123        continue;
00124
00125     /* got a response, lets consider it
00126      */
00127     memset (bootp_in, 0, sizeof(*bootp_in));
00128     len = sock_fastread (boot_sock, (BYTE*)bootp_in, sizeof(*bootp_in));
00129     if (len < BOOTP_MIN_SIZE ||
00130         bootp_in->bp_op != BOOTP_REPLY)
00131        continue;
00132
00133     /* Check if transaction ID and MAC-address matches
00134      */
00135     if (bootp_in->bp_xid != exchange_id ||
00136         memcmp(&bootp_in->bp_chaddr, _eth_addr, sizeof(eth_address)))
00137        continue;
00138
00139     vendor = intel (*(DWORD*)&bootp_in->bp_vend);
00140     if (vendor == VM_RFC1048)
00141        bootp_parse (bootp_in, len);
00142     return (TRUE);
00143   }
00144 }
00145
00146 /*
00147  * Parse RFC1048 compliant BOOTP vendor field.
00148  * Based heavily on NCSA Telnet BOOTP
00149  */
00150 static void bootp_parse (const struct bootp *bootp_in, int max)
00151 {
00152   const BYTE *p   = &bootp_in->bp_vend[4]; /* Point after magic value */
00153   const BYTE *end = max + (const BYTE*)bootp_in;
00154   BOOL  got_end = FALSE;
00155
00156   while (!got_end && p < end)
00157   {
00158     DWORD ip;
00159     int   i, len;
00160
00161     switch (*p)
00162     {
00163       case BOOTP_OPT_PAD:
00164            p++;
00165            continue;
00166
00167       case BOOTP_OPT_SUBNET_MASK:
00168            sin_mask = intel (*(DWORD*)(p+2));
00169            break;
00170
00171       case BOOTP_OPT_ROUTERS_ON_SNET:
00172            /* only add first */
00173            ip = intel (*(DWORD*)(p+2));
00174            _arp_add_gateway (NULL, ip);
00175            break;
00176
00177       case BOOTP_OPT_DNS_SRV:
00178            for (i = 0; i < *(p+1); i += sizeof(ip))
00179            {
00180              ip = intel (*(DWORD*)(p+2+i));
00181              _add_server (&last_nameserver, MAX_NAMESERVERS,
00182                           def_nameservers, ip);
00183            }
00184            break;
00185
00186       case BOOTP_OPT_COOKIE_SRV:
00187            for (i = 0; i < *(p+1) ; i += sizeof(ip))
00188            {
00189              ip = intel (*(DWORD*)(p+2+i));
00190              _add_server (&last_cookie, MAX_COOKIES, cookies, ip);
00191            }
00192            break;
00193
00194 #if defined(USE_BSD_API)
00195       case BOOTP_OPT_LOG_SRV:
00196            ip = intel (*(DWORD*)(p+2));  /* select 1st host */
00197            if (!syslog_hostName[0] &&    /* not in config-file */
00198                p[1] % 4 == 0)            /* length = n * 4 */
00199              StrLcpy (syslog_hostName, _inet_ntoa(NULL,ip),
00200                       sizeof(syslog_hostName));
00201            break;
00202 #endif
00203
00204       case BOOTP_OPT_HOST_NAME:
00205            len = min (p[1], sizeof(hostname));
00206            memcpy (&hostname[0], p+2, len);
00207            hostname[len] = '\0';
00208            break;
00209
00210       case BOOTP_OPT_NAME_SRV:    /* IEN-116 name server */
00211       case BOOTP_OPT_LPR_SRV:
00212       case BOOTP_OPT_IMPRESS_SRV:
00213       case BOOTP_OPT_RES_LOCATION_SRV:
00214       case BOOTP_OPT_TIME_SRV:
00215       case BOOTP_OPT_TIME_OFFSET:
00216            break;
00217
00218       case BOOTP_OPT_END:
00219            got_end = TRUE;
00220            break;
00221
00222       default:
00223            break;
00224     }
00225     p += *(p+1) + 2;
00226   }
00227 }
00228 #endif /* USE_BOOTP */
00229
Generated on Wed Jan 25 15:42:36 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/PCBOOTP.H Source File

SRC/PCBOOTP.H

Go to the documentation of this file.
00001
00007 #ifndef _w32_PCBOOTP_H
00008 #define _w32_PCBOOTP_H
00009
00010 W32_DATA DWORD _bootp_host;
00011 W32_DATA int   _bootp_timeout;
00012
00013 extern int BOOTP_do_boot (void);
00014
00015 #define BOOTP_REQUEST  1
00016 #define BOOTP_REPLY    2
00017
00018 /*
00019  * BOOTP options and values.
00020  */
00021 enum BOOTP_Options {
00022      BOOTP_OPT_PAD                      =  0,
00023      BOOTP_OPT_SUBNET_MASK              =  1,
00024      BOOTP_OPT_TIME_OFFSET              =  2,
00025      BOOTP_OPT_ROUTERS_ON_SNET          =  3,
00026      BOOTP_OPT_TIME_SRV                 =  4,
00027      BOOTP_OPT_NAME_SRV                 =  5,
00028      BOOTP_OPT_DNS_SRV                  =  6,
00029      BOOTP_OPT_LOG_SRV                  =  7,
00030      BOOTP_OPT_COOKIE_SRV               =  8,
00031      BOOTP_OPT_LPR_SRV                  =  9,
00032      BOOTP_OPT_IMPRESS_SRV              = 10,
00033      BOOTP_OPT_RES_LOCATION_SRV         = 11,
00034      BOOTP_OPT_HOST_NAME                = 12,
00035      BOOTP_OPT_BOOT_FSIZE               = 13,
00036      BOOTP_OPT_DOMAIN_NAME              = 15,
00037      BOOTP_OPT_NON_LOCAL_SRC_ROUTE      = 20,
00038      BOOTP_OPT_POLICY_FILTER            = 21,
00039      BOOTP_OPT_MAX_DGRAM_REASM_SIZE     = 22,
00040      BOOTP_OPT_IP_DEFAULT_TTL           = 23,
00041      BOOTP_OPT_PATH_MTU_AGING_TIMEOUT   = 24,
00042      BOOTP_OPT_PATH_MTU_PLATEAU_TABLE   = 25,
00043      BOOTP_OPT_IF_MTU                   = 26,
00044      BOOTP_OPT_ALL_SUBNETS_LOCAL        = 27,
00045      BOOTP_OPT_BROADCAST_ADDR           = 28,
00046      BOOTP_OPT_PERFORM_MASK_DISCOVERY   = 29,
00047      BOOTP_OPT_MASK_SUPPLIER            = 30,
00048      BOOTP_OPT_PERFORM_ROUTER_DISCOVERY = 31,
00049      BOOTP_OPT_ROUTER_SOLICITATION_ADDR = 32,
00050      BOOTP_OPT_STATIC_ROUTE             = 33,
00051      BOOTP_OPT_TRAILER_ENCAPSULATION    = 34,
00052      BOOTP_OPT_ARP_CACHE_TIMEOUT        = 35,
00053      BOOTP_OPT_ETHERNET_ENCAPSULATION   = 36,
00054      BOOTP_OPT_END                      = 255,
00055    };
00056
00057 #include <sys/packon.h>
00058
00063 struct bootp {
00064        BYTE   bp_op;         /* packet op code / message type.            */
00065        BYTE   bp_htype;      /* hardware address type, 1 = 10 mb ethernet */
00066        BYTE   bp_hlen;       /* hardware address len, eg '6' for 10mb eth */
00067        BYTE   bp_hops;       /* client sets to zero, optionally used by   */
00068                              /* gateways in cross-gateway booting.        */
00069        DWORD  bp_xid;        /* transaction ID, a random number           */
00070        WORD   bp_secs;       /* filled in by client, seconds elapsed      */
00071                              /* since client started trying to boot.      */
00072        WORD   bp_spare;
00073        DWORD  bp_ciaddr;     /* client IP address filled by client if known */
00074        DWORD  bp_yiaddr;     /* 'your' (client) IP address                */
00075                              /* filled by server if client doesn't know   */
00076        DWORD  bp_siaddr;     /* server IP address returned in bootreply   */
00077        DWORD  bp_giaddr;     /* gateway IP address,                       */
00078                              /* used in optional cross-gateway booting.   */
00079        BYTE   bp_chaddr[16]; /* client hardware address, filled by client */
00080        BYTE   bp_sname[64];  /* optional server host name, null terminated*/
00081
00082        BYTE   bp_file[128];  /* boot file name, null terminated string    */
00083                              /* 'generic' name or null in bootrequest,    */
00084                              /* fully qualified directory-path            */
00085                              /* name in bootreply.                        */
00086        BYTE   bp_vend[64];   /* optional vendor-specific area             */
00087      };
00088
00089 #define BOOTP_MIN_SIZE  44
00090
00091 /*
00092  * UDP port numbers, server and client.
00093  */
00094 #define IPPORT_BOOTPS   67
00095 #define IPPORT_BOOTPC   68
00096
00097
00098 /******** the following is stolen from NCSA which came from CUTCP *********/
00099 /* I have not implemented these, but someone may wish to in the future so */
00100 /* I kept them around.                                                    */
00101 /**************************************************************************/
00102
00107 struct bootp_vend {
00108        BYTE  v_magic[4];    /* magic number */
00109        DWORD v_flags;       /* flags/opcodes, etc. */
00110        BYTE  v_unused[56];  /* currently unused */
00111      };
00112
00113 #include <sys/packoff.h>
00114
00115
00116 #define VM_STANFORD  0x5354414EUL  /* v_magic for Stanford ("STAN") */
00117 #define VM_RFC1048   0x63825363UL  /* v_magic for RFC client/servers */
00118
00119 /*
00120  * 'v_flags' values.
00121  */
00122 #define VF_PCBOOT          1   /* an IBMPC or Mac wants environment info */
00123 #define VF_HELP            2   /* help me, I'm not registered */
00124 #define TAG_BOOTFILE_SIZE  13  /* tag used by bootp_vend fields, RFC 1048 */
00125
00126 #endif
Generated on Wed Jan 25 15:42:36 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/PCBUF.C Source File

SRC/PCBUF.C

Go to the documentation of this file.
00001
00005 #include <stdio.h>
00006 #include <stdlib.h>
00007 #include <string.h>
00008 #include <limits.h>
00009
00010 #include "copyrigh.h"
00011 #include "wattcp.h"
00012 #include "language.h"
00013 #include "misc.h"
00014 #include "strings.h"
00015 #include "pctcp.h"
00016 #include "pcdbug.h"
00017 #include "pcbuf.h"
00018
00019 #if defined(USE_BSD_API)
00020 static int num_free_raw (const _raw_Socket *raw)
00021 {
00022   int num;
00023
00024   for (num = 0; raw; raw = raw->next)
00025       if (!raw->used)
00026          num++;
00027   return (num);
00028 }
00029 #endif
00030
00031 #if defined(USE_IPV6)
00032 static int num_free_raw6 (const _raw6_Socket *raw)
00033 {
00034   int num;
00035
00036   for (num = 0; raw; raw = raw->next)
00037       if (!raw->used)
00038          num++;
00039   return (num);
00040 }
00041 #endif
00042
00043
00044 size_t sock_rbsize (const sock_type *s)
00045 {
00046   switch (_chk_socket(s))
00047   {
00048     case VALID_IP4:
00049          return (sizeof(s->raw.ip) + sizeof(s->raw.rx_data));
00050 #if defined(USE_IPV6)
00051     case VALID_IP6:
00052          return (sizeof(s->raw6.ip6) + sizeof(s->raw6.rx_data));
00053 #endif
00054     case VALID_UDP:
00055          return (s->udp.max_rx_data);
00056     case VALID_TCP:
00057          return (s->tcp.max_rx_data);
00058   }
00059   return (0);
00060 }
00061
00062 size_t sock_rbused (const sock_type *s)
00063 {
00064   switch (_chk_socket(s))
00065   {
00066 #if defined(USE_BSD_API)
00067     case VALID_IP4:
00068          {
00069            const _raw_Socket *raw = find_oldest_raw (&s->raw);
00070            return (raw ? intel16 (raw->ip.length) : 0);
00071          }
00072 #if defined(USE_IPV6)
00073     case VALID_IP6:
00074          {
00075            const _raw6_Socket *raw = find_oldest_raw6 (&s->raw6);
00076            return (raw ? intel16 (raw->ip6.len) : 0);
00077          }
00078 #endif
00079 #endif
00080     case VALID_UDP:
00081          return (s->udp.rx_datalen);
00082     case VALID_TCP:
00083          return (s->tcp.rx_datalen);
00084   }
00085   return (0);
00086 }
00087
00088 size_t sock_rbleft (const sock_type *s)
00089 {
00090   switch (_chk_socket(s))
00091   {
00092 #if defined(USE_BSD_API)
00093     case VALID_IP4:
00094          return num_free_raw (&s->raw) *
00095                   (sizeof(s->raw.ip) + sizeof(s->raw.rx_data));
00096 #if defined(USE_IPV6)
00097     case VALID_IP6:
00098          return num_free_raw6 (&s->raw6) *
00099                   (sizeof(s->raw6.ip6) + sizeof(s->raw6.rx_data));
00100 #endif
00101 #endif
00102     case VALID_UDP:
00103          return (s->tcp.max_rx_data - s->udp.rx_datalen);
00104     case VALID_TCP:
00105          return (s->tcp.max_rx_data - s->tcp.rx_datalen);
00106   }
00107   return (0);
00108 }
00109
00110 size_t sock_tbsize (const sock_type *s)
00111 {
00112   switch (_chk_socket(s))
00113   {
00114     case VALID_IP4:
00115     case VALID_IP6:
00116          return (_mtu);
00117     case VALID_TCP:
00118          return (s->tcp.max_tx_data);
00119     case VALID_UDP:
00120          return (_mtu - UDP_OVERHEAD);
00121   }
00122   return (0);
00123 }
00124
00125 size_t sock_tbleft (const sock_type *s)
00126 {
00127   switch (_chk_socket(s))
00128   {
00129     case VALID_IP4:
00130     case VALID_IP6:
00131          return (_mtu);
00132     case VALID_TCP:
00133          return (s->tcp.max_tx_data - s->tcp.tx_datalen - 1);
00134     case VALID_UDP:
00135          return (_mtu - UDP_OVERHEAD);
00136   }
00137   return (0);
00138 }
00139
00140 size_t sock_tbused (const sock_type *s)
00141 {
00142   if (_chk_socket(s) == VALID_TCP)
00143      return (s->tcp.tx_datalen);
00144   return (0);
00145 }
00146
00147 /*
00148  * Sets new buffer for Rx-data (for udp/tcp).
00149  * Set debug-marker in front and at end of buffer.
00150  * \note does not copy the old content over to new buffer.
00151  */
00152 size_t sock_setbuf (sock_type *s, BYTE *rx_buf, size_t rx_len)
00153 {
00154   int type = _chk_socket (s);
00155
00156   /* Raw-sockets use fixed buffer
00157    */
00158   if (!type || type == VALID_IP4 || type == VALID_IP6)
00159      return (0);
00160
00161   if (rx_len < 8 || !rx_buf)
00162   {
00163     s->tcp.rx_data     = &s->tcp.rx_buf[0];
00164     s->tcp.max_rx_data = sizeof(s->tcp.rx_buf) - 1;
00165   }
00166   else
00167   {
00168     size_t len = min (rx_len, USHRT_MAX-1) - 8;
00169
00170     *(DWORD*)rx_buf         = SAFETY_TCP;
00171     *(DWORD*)(rx_buf+4+len) = SAFETY_TCP;
00172     s->tcp.rx_data     = rx_buf + 4;
00173     s->tcp.max_rx_data = len - 1;
00174   }
00175   return (s->tcp.max_rx_data);
00176 }
00177
00178 #if defined(USE_DEBUG)
00179 /*
00180  * Check the Rx-buffer marker signatures of Rx/Tx-buffers.
00181  * Rx-buffer may have been allocated in above sock_setbuf().
00182  * Tx-buffer may have been allocated in tcp_SetWindow().
00183  * Only usable for TCP sockets.
00184  */
00185 void _sock_check_tcp_buffers (const _tcp_Socket *tcp)
00186 {
00187   const BYTE *rx, *tx;
00188
00189   if (tcp->ip_type != TCP_PROTO)  /* should already be true */
00190      return;
00191
00192   rx = tcp->rx_data;
00193   tx = tcp->tx_data;
00194
00195   WATT_ASSERT (tcp->safetysig == SAFETY_TCP);
00196   WATT_ASSERT (tcp->safetytcp == SAFETY_TCP);
00197
00198 #if (DOSX)
00199   WATT_ASSERT (valid_addr((DWORD)rx, tcp->max_rx_data));
00200   WATT_ASSERT (valid_addr((DWORD)tx, tcp->max_tx_data));
00201 #endif
00202
00203   if (rx != &tcp->rx_buf[0])
00204   {
00205     WATT_ASSERT (*(DWORD*)(rx-4) == SAFETY_TCP);
00206     WATT_ASSERT (*(DWORD*)(rx+1+tcp->max_rx_data) == SAFETY_TCP);
00207   }
00208   if (tx != &tcp->tx_buf[0])
00209   {
00210     WATT_ASSERT (*(DWORD*)(tx-4) == SAFETY_TCP);
00211     WATT_ASSERT (*(DWORD*)(tx+1+tcp->max_tx_data) == SAFETY_TCP);
00212   }
00213 }
00214
00215 void _sock_check_udp_buffers (const _udp_Socket *udp)
00216 {
00217   ARGSUSED (udp);   /* \todo */
00218 }
00219 #endif
00220
00221
00222 size_t sock_preread (const sock_type *s, BYTE *buf, size_t len)
00223 {
00224   size_t count;
00225   int    type = _chk_socket (s);
00226
00227   /* Raw-sockets use fixed buffer
00228    */
00229   if (!type || type == VALID_IP4 || type == VALID_IP6)
00230      return (0);
00231
00232   count = (size_t) s->tcp.rx_datalen;
00233   if (count < 1)
00234      return (count);
00235
00236   if (count > len)
00237       count = len;
00238   if (buf)
00239      memcpy (buf, s->tcp.rx_data, count);
00240   return (count);
00241 }
00242
00243 /*
00244  * chk_socket - determine whether a real socket or not
00245  */
00246 int _chk_socket (const sock_type *s)
00247 {
00248   if (!s)
00249      return (0);
00250
00251   if (s->tcp.ip_type == TCP_PROTO && s->tcp.state <= tcp_StateCLOSED)
00252      return (VALID_TCP);
00253
00254   if (s->udp.ip_type == UDP_PROTO)
00255      return (VALID_UDP);
00256
00257   if (s->raw.ip_type == IP4_TYPE)
00258      return (VALID_IP4);
00259
00260   if (s->raw6.ip_type == IP6_TYPE)
00261      return (VALID_IP6);
00262
00263   return (0);
00264 }
00265
00266 const char *sockerr (const sock_type *s)
00267 {
00268   if (s && s->tcp.err_msg)
00269      return (s->tcp.err_msg);
00270   return (NULL);
00271 }
00272
00273 void sockerr_clear (sock_type *s)
00274 {
00275   if (s)
00276   {
00277     s->tcp.err_msg = NULL;
00278     s->tcp.err_buf[0] = '\0';
00279   }
00280 }
00281
00282 const char *sockstate (const sock_type *s)
00283 {
00284   switch (_chk_socket(s))
00285   {
00286     case VALID_IP4:
00287          return (_LANG("Raw IPv4 Socket"));
00288
00289     case VALID_IP6:
00290          return (_LANG("Raw IPv6 Socket"));
00291
00292     case VALID_UDP:
00293          return (_LANG("UDP Socket"));
00294
00295     case VALID_TCP:
00296          return (_LANG(tcpStateName(s->tcp.state)));
00297
00298     default:
00299          return (_LANG("Not an active socket"));
00300   }
00301 }
00302
00303 #if defined(USE_BSD_API)
00304 const _raw_Socket *find_oldest_raw (const _raw_Socket *raw)
00305 {
00306   const _raw_Socket *s;
00307
00308   for (s = raw; raw; raw = raw->next)
00309   {
00310     if (raw->used && raw->seq_num < s->seq_num)
00311        s = raw;
00312   }
00313   return (s->used ? s : NULL);
00314 }
00315
00316 #if defined(USE_IPV6)
00317 const _raw6_Socket *find_oldest_raw6 (const _raw6_Socket *raw)
00318 {
00319   const _raw6_Socket *s;
00320
00321   for (s = raw; raw; raw = raw->next)
00322   {
00323     if (raw->used && raw->seq_num < s->seq_num)
00324        s = raw;
00325   }
00326   return (s->used ? s : NULL);
00327 }
00328 #endif
00329 #endif
00330
Generated on Wed Jan 25 15:42:36 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/PCBUF.H Source File

SRC/PCBUF.H

Go to the documentation of this file.
00001
00003 #ifndef _w32_PCBUF_H
00004 #define _w32_PCBUF_H
00005
00006 #define VALID_UDP  1
00007 #define VALID_TCP  2
00008 #define VALID_IP4  3
00009 #define VALID_IP6  4
00010
00011 /* public API
00012  */
00013 W32_FUNC size_t sock_rbsize  (const sock_type *s);
00014 W32_FUNC size_t sock_rbused  (const sock_type *s);
00015 W32_FUNC size_t sock_rbleft  (const sock_type *s);
00016 W32_FUNC size_t sock_tbsize  (const sock_type *s);
00017 W32_FUNC size_t sock_tbused  (const sock_type *s);
00018 W32_FUNC size_t sock_tbleft  (const sock_type *s);
00019
00020 W32_FUNC size_t sock_setbuf  (sock_type *s, BYTE *buf, size_t len);
00021 W32_FUNC size_t sock_preread (const sock_type *s, BYTE *buf, size_t len);
00022
00023 W32_FUNC const char *sockerr      (const sock_type *s);
00024 W32_FUNC void        sockerr_clear(sock_type *s);        /* GvB */
00025
00026 W32_FUNC const char *sockstate     (const sock_type *s);
00027 W32_FUNC int        _chk_socket    (const sock_type *s);
00028 W32_FUNC void       sock_debugdump (const sock_type *s);
00029
00030
00031 /* Reduce internal states to "user-easy" states, GvB 2002-09
00032  */
00033 enum TCP_SIMPLE_STATE {
00034      TCP_CLOSED,
00035      TCP_LISTENING,
00036      TCP_OPENING,
00037      TCP_OPEN,
00038      TCP_CLOSING
00039    };
00040
00041 W32_FUNC enum TCP_SIMPLE_STATE tcp_simple_state (const _tcp_Socket *s);
00042
00043 /* privates
00044  */
00045 extern void _sock_check_tcp_buffers (const _tcp_Socket *tcp);
00046 extern void _sock_check_udp_buffers (const _udp_Socket *udp);
00047
00048 const _raw_Socket  *find_oldest_raw  (const _raw_Socket *raw);
00049 const _raw6_Socket *find_oldest_raw6 (const _raw6_Socket *raw);
00050
00051 #endif
00052
Generated on Wed Jan 25 15:42:36 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/PCCONFIG.C Source File

SRC/PCCONFIG.C

Go to the documentation of this file.
00001
00006 #include <stdio.h>
00007 #include <stdlib.h>
00008 #include <io.h>
00009 #include <ctype.h>
00010 #include <string.h>
00011 #include <limits.h>
00012 #include <fcntl.h>
00013 #include <arpa/inet.h>
00014
00015 #include "copyrigh.h"
00016 #include "wattcp.h"
00017 #include "strings.h"
00018 #include "misc.h"
00019 #include "timer.h"
00020 #include "language.h"
00021 #include "udp_dom.h"
00022 #include "netaddr.h"
00023 #include "bsdname.h"
00024 #include "pcqueue.h"
00025 #include "pcdbug.h"
00026 #include "pcsed.h"
00027 #include "pcpkt.h"
00028 #include "pctcp.h"
00029 #include "pcarp.h"
00030 #include "pcrarp.h"
00031 #include "pcdhcp.h"
00032 #include "pcbootp.h"
00033 #include "pcicmp.h"
00034 #include "sock_ini.h"
00035 #include "ip4_frag.h"
00036 #include "ip4_out.h"
00037 #include "ip6_out.h"
00038 #include "loopback.h"
00039 #include "get_xby.h"
00040 #include "printk.h"
00041 #include "pcconfig.h"
00042
00043 #if defined(USE_IPV6)
00044 #include "pcicmp6.h"
00045 #include "teredo64.h"
00046 #endif
00047
00048 #if (DOSX & PHARLAP)
00049   #include <hw386.h>
00050 #endif
00051
00052 #if defined(__BORLANDC__)
00053   #pragma warn -pro
00054 #endif
00055
00056
00057 int  debug_on          = 0;    /* general debug level */
00058 int  ctrace_on         = 0;    /* tracing; on/off (High-C only) */
00059 int  sock_delay        = 30;
00060 int  sock_inactive     = 0;    /* defaults to forever */
00061 int  sock_data_timeout = 0;    /* timeout sending no data (forever) */
00062 WORD multihomes        = 0;    /* We have more than 1 IP-addresses */
00063 BOOL dynamic_host      = 0;    /* reverse resolve assigned IP to true FQDN */
00064
00065 DWORD cookies [MAX_COOKIES];
00066 WORD  last_cookie = 0;
00067
00068 static void deprecated_key    (const char *old_key, const char *new_key);
00069 static void keyword_not_found (const char *key, const char *value);
00070
00071 void (*print_hook) (const char*) = NULL;
00072 void (*usr_init)   (const char*, const char*) = keyword_not_found;
00073
00076 void (*usr_post_init) (void) = NULL;
00077
00078 static char *config_name  = "WATTCP.CFG";  /* name of config file */
00079 static char *current_file = NULL;
00080 static UINT  current_line = 0;
00081 static BOOL  got_eol      = FALSE;  /* got end-of-line in current_line */
00082
00083 static const char *environ_names[] = {
00084                   "WATTCP.CFG",    /* pointer to config-file */
00085                   "WATTCP_CFG"     /* ditto, for bash */
00086                 };
00087
00088 enum ParseMode {
00089      ModeKeyword = 0,
00090      ModeValue,
00091      ModeComment
00092    };
00093
00094 #if defined(USE_DEBUG)
00095   #define CONFIG_DBG_MSG(lvl, args) \
00096           do { \
00097             if (debug_on >= lvl) { \
00098                UINT line = got_eol ? current_line : current_line+1; \
00099                if (current_file) \
00100                     (*_printf) ("%s (%u): ", current_file, line); \
00101                else (*_printf) ("CONFIG: "); \
00102                (*_printf) args; \
00103                fflush (stdout); \
00104             } \
00105           } while (0)
00106
00107   #define RANGE_CHECK(val,low,high) \
00108           do { \
00109             if (((val) < (low)) || ((val) > (high))) \
00110                CONFIG_DBG_MSG (0, ("Value %ld exceedes range [%d - %d]\n", \
00111                                val, low, high)); \
00112           } while (0)
00113 #else
00114   #define CONFIG_DBG_MSG(lvl, args)  ((void)0)
00115   #define RANGE_CHECK(val,low,high)  ((void)0)
00116 #endif
00117
00118
00119 /*
00120  * Set 'debug_on' if not already set before tcp_config() called.
00121  */
00122 static void set_debug_on (const char *value)
00123 {
00124   if (debug_on == 0)
00125      debug_on = ATOI (value);
00126 }
00127
00132 static void set_ethip (const char *value)
00133 {
00134   eth_address eth;
00135   const char *trailer = _inet_atoeth (value, &eth);
00136   DWORD       ip4;
00137
00138   if (!trailer)
00139      return;
00140
00141   ip4 = _inet_addr (trailer);
00142
00143   /* Don't add our MAC/IP-address
00144    */
00145   if (!memcmp (&eth, _eth_real_addr, sizeof(eth)))
00146      return;
00147
00148   if (!ip4)
00149   {
00150 #if defined(USE_IPV6)
00151     const void *ip6 = _inet6_addr (trailer);
00152     if (ip6)
00153        icmp6_ncache_insert_fix (ip6, &eth);
00154 #endif
00155     return;
00156   }
00157
00158   /* Add IPv4-addr to ARP-cache.
00159    */
00160   _arp_add_cache (ip4, (const eth_address*)&eth, FALSE);
00161 }
00162
00163 void _add_server (WORD *counter, WORD max, DWORD *array, DWORD value)
00164 {
00165   int i, duplicate = 0;
00166
00167   if (value && *counter < max)
00168   {
00169     for (i = 0; i < *counter; i++)
00170         if (array[i] == value)
00171            duplicate = 1;
00172
00173     if (!duplicate)
00174        array [(*counter)++] = value;
00175   }
00176 }
00177
00187 const char *ExpandVarStr (const char *str)
00188 {
00189   static char buf [MAX_PATHLEN+MAX_VALUELEN+1];
00190   char   env [30];
00191   const  char *e, *p  = strstr (str, "$(");
00192   const  char *dollar = p;
00193   size_t i;
00194
00195   if (!p || strlen(p) < 4 || !strchr(p+3,')'))  /* minimum "$(x)" */
00196      return (str);
00197
00198   for (i = 0, p += 2; i < sizeof(env)-1; i++)
00199   {
00200     if (*p == ')')
00201        break;
00202     env[i] = *p++;
00203   }
00204   env[i] = '\0';
00205   strupr (env);
00206   e = getenv (env);
00207   if (!e)
00208   {
00209     e = env;
00210     env[0] = '\0';
00211   }
00212
00213   i = dollar - str;
00214   strncpy (buf, str, i);
00215   buf[i] = '\0';
00216   strncat (buf, e, sizeof(buf)-1-i);
00217   return strcat (buf, p+1);
00218 }
00219
00224 static void keyword_not_found (const char *key, const char *value)
00225 {
00226   CONFIG_DBG_MSG (2, ("unhandled key/value: \"%s = %s\"\n", key, value));
00227   ARGSUSED (key);
00228   ARGSUSED (value);
00229 }
00230
00236 static BOOL set_value (BOOL is_hex, const char *value, void *arg, int size)
00237 {
00238   long  val = 0;
00239   BOOL  ok = FALSE;
00240   const char *s = value;
00241
00242 #if (DOSX)
00243   if (is_hex)
00244      ok = (sscanf(s,"0x%lX",&val) == 1 || sscanf(s,"x%lX",&val) == 1);
00245   if (!ok)
00246      ok = (sscanf(s,"%ld",&val) == 1);
00247 #else
00248   if (is_hex)
00249   {
00250     int ch, len = 0;
00251
00252     if (s[0] == '0' && s[1] == 'x' && strlen(s) >= 4)
00253     {
00254       len += 2;
00255       s += 2;
00256     }
00257     else if (s[0] == 'x' && strlen(s) >= 3)
00258     {
00259       len++;
00260       s++;
00261     }
00262
00263     ch = toupper (*s);
00264     if (len > 0 && strchr(hex_chars_upper,ch))
00265     {
00266       val = atox (s-2);
00267       if (strlen(s) >= 4)
00268          val = (val << 8) + atox (s);
00269       if (strlen(s) >= 6)
00270          val = (val << 8) + atox (s+2);
00271       if (strlen(s) >= 8)
00272          val = (val << 8) + atox (s+4);
00273       ok = TRUE;
00274     }
00275   }
00276   if (!ok)
00277   {
00278     val = ATOI (value);
00279     ok = TRUE;  /* could be unconvertable */
00280   }
00281 #endif
00282
00283   if (!ok)
00284   {
00285     CONFIG_DBG_MSG (0, ("failed to match `%s' as %sdecimal.\n",
00286                     s, is_hex ? "hex or " : ""));
00287     return (FALSE);
00288   }
00289
00290   CONFIG_DBG_MSG (4, ("got value %ld/%#lx from `%s'\n",
00291                   val, val, value));
00292   switch (size)
00293   {
00294     case 1:
00295          RANGE_CHECK (val, 0, UCHAR_MAX);
00296          *(BYTE*)arg = (BYTE) min (val, UCHAR_MAX);
00297          break;
00298     case 2:
00299 #if (DOSX == 0)
00300          RANGE_CHECK (val, INT_MIN, INT_MAX);
00301          *(int*)arg = (int) min (max(val,INT_MIN), INT_MAX);
00302 #else
00303          RANGE_CHECK (val, 0, USHRT_MAX);
00304          *(WORD*)arg = (WORD) min (val, USHRT_MAX);
00305 #endif
00306          break;
00307     case 4:
00308          *(DWORD*)arg = (DWORD)val;
00309          break;
00310
00311     default:
00312 #if (DOSX)
00313         if (!valid_addr((DWORD)arg,sizeof(int)))
00314         {
00315           CONFIG_DBG_MSG (0, ("Illegal 'arg' addr %08lX\n", (DWORD)arg));
00316           return (FALSE);
00317         }
00318 #endif
00319          *(int*)arg = val;
00320          break;
00321   }
00322   return (TRUE);
00323 }
00324
00330 int parse_config_table (const struct config_table *tab,
00331                         const char *section,
00332                         const char *name,
00333                         const char *value)
00334 {
00335   for ( ; tab && tab->keyword; tab++)
00336   {
00337     char  keyword [MAX_NAMELEN], *p;
00338     DWORD host;
00339     void *arg;
00340
00341     if (section)
00342     {
00343       if (strlen(section) + strlen(tab->keyword) >= sizeof(keyword))
00344          continue;
00345       strcpy (keyword, section);
00346       strcat (keyword, tab->keyword);   /* "SECTION.KEYWORD" */
00347     }
00348     else
00349       StrLcpy (keyword, tab->keyword, sizeof(keyword));
00350
00351     if (strcmp(name,keyword))
00352        continue;
00353
00354     arg = tab->arg_func;   /* storage or function to call */
00355     if (!arg)
00356     {
00357       CONFIG_DBG_MSG (2, ("No storage for \"%s\", type %d\n",
00358                       keyword, tab->type));
00359       return (1);
00360     }
00361
00362     switch (tab->type)
00363     {
00364       case ARG_ATOI:
00365            set_value (FALSE, value, arg, sizeof(int));
00366            break;
00367
00368       case ARG_ATOB:
00369            set_value (FALSE, value, arg, sizeof(BYTE));
00370            break;
00371
00372       case ARG_ATOX_B:
00373            set_value (TRUE, value, arg, sizeof(BYTE));
00374            break;
00375
00376       case ARG_ATOW:
00377            set_value (FALSE, value, arg, sizeof(WORD));
00378            break;
00379
00380       case ARG_ATOX_W:
00381            set_value (TRUE, value, arg, sizeof(WORD));
00382            break;
00383
00384       case ARG_ATOX_D:
00385            set_value (TRUE, value, arg, sizeof(DWORD));
00386            break;
00387
00388       case ARG_ATOIP:
00389            *(DWORD*)arg = aton (value);
00390            break;
00391
00392       case ARG_FUNC:
00393            (*(void(*)(const char*, int))arg) (value, strlen(value));
00394            break;
00395
00396       case ARG_RESOLVE:
00397            host = resolve (value);
00398            if (!host && !isaddr(value))
00399            {
00400              outs (name);
00401              outs (_LANG(": Cannot resolve \""));
00402              outs (value);
00403              outsnl ("\"");
00404            }
00405            else
00406              *(DWORD*)arg = host;
00407            break;
00408
00409       case ARG_STRDUP:
00410            p = strdup (value);
00411            if (!p)
00412            {
00413              outs (_LANG("No memory for \""));
00414              outs (name);
00415              outsnl ("\"");
00416            }
00417            else
00418              *(char**)arg = p;
00419            break;
00420
00421       case ARG_STRCPY:
00422            StrLcpy ((char*)arg, value, MAX_VALUELEN);
00423            break;
00424
00425       default:
00426 #if defined(USE_DEBUG)
00427            fprintf (stderr, "Something wrong in parse_config_table().\n"
00428                     "Section %s; `%s' = `%s'\n", section, name, value);
00429            exit (-1);
00430 #endif
00431            break;
00432     }
00433
00434     TCP_CONSOLE_MSG (3,
00435        ("ARG_%s, matched `%s' = `%s'\n",
00436         tab->type == ARG_ATOI    ? "ATOI   " :
00437         tab->type == ARG_ATOB    ? "ATOB   " :
00438         tab->type == ARG_ATOW    ? "ATOW   " :
00439         tab->type == ARG_ATOIP   ? "ATOIP  " :
00440         tab->type == ARG_ATOX_B  ? "ATOX_B " :
00441         tab->type == ARG_ATOX_W  ? "ATOX_W " :
00442         tab->type == ARG_FUNC    ? "FUNC   " :
00443         tab->type == ARG_RESOLVE ? "RESOLVE" :
00444         tab->type == ARG_STRDUP  ? "STRDUP " :
00445         tab->type == ARG_STRCPY  ? "STRCPY " : "??",
00446         keyword, value));
00447
00448     return (1);
00449   }
00450   return (0);
00451 }
00452
00453 static void set_my_ip (const char *value)
00454 {
00455   if (!stricmp(value,"bootp"))
00456        _bootp_on = 1;
00457   else if (!stricmp(value,"dhcp"))
00458        _dhcp_on = 1;
00459   else if (!stricmp(value,"rarp"))
00460        _rarp_on = 1;
00461   else my_ip_addr = resolve (value);
00462 }
00463
00464 static void set_hostname (const char *value)
00465 {
00466   StrLcpy (hostname, value, sizeof(hostname));
00467 }
00468
00469 static void set_gateway (const char *value)
00470 {
00471   _arp_add_gateway (value, 0L);  /* accept gateip[,subnet[,mask]] */
00472 }
00473
00474 static void set_nameserv (const char *value)
00475 {
00476   _add_server (&last_nameserver, MAX_NAMESERVERS,
00477                def_nameservers, resolve(value));
00478 }
00479
00480 static void set_cookie (const char *value)
00481 {
00482   _add_server (&last_cookie, MAX_COOKIES, cookies, resolve(value));
00483 }
00484
00488 static void set_eaddr (const char *value)
00489 {
00490   eth_address eth;
00491
00492   if (!_inet_atoeth (value, &eth))
00493      return;
00494
00495   if (memcmp (&eth, _eth_real_addr, sizeof(eth)))
00496   {
00497     if (!_eth_set_addr(&eth))
00498        outsnl (_LANG("Cannot set Ether-addr"));
00499 #if defined(USE_RARP)
00500     else
00501     {
00502       WORD  save_to = _rarptimeout;
00503       DWORD save_ip = my_ip_addr;
00504
00505       /* We need to debug the RARP messages. It doesn't hurt to
00506        * call dbug_open() again in sock_ini.c
00507        */
00508 #if defined(USE_DEBUG)
00509      if (_dbugxmit)
00510         dbug_open();
00511 #endif
00512       _rarptimeout = 2;     /* use only 2 sec timeout */
00513       my_ip_addr   = 0;
00514       if (_dorarp() && my_ip_addr == save_ip)
00515          outsnl (_LANG("Warning: MAC-addr already in use"));
00516       my_ip_addr   = save_ip;
00517       _rarptimeout = save_to;
00518     }
00519 #endif
00520   }
00521
00522 }
00523
00524 static void set_domain (const char *value)
00525 {
00526   setdomainname (value, sizeof(defaultdomain)-1);
00527 }
00528
00529 static void depr_set_domain1 (const char *value)
00530 {
00531   deprecated_key ("DOMAINSLIST", "DOMAIN.SUFFIX");
00532   setdomainname (value, sizeof(defaultdomain)-1);
00533 }
00534
00535 static void depr_set_domain2 (const char *value)
00536 {
00537   deprecated_key ("DOMAIN_LIST", "DOMAIN.SUFFIX");
00538   setdomainname (value, sizeof(defaultdomain)-1);
00539 }
00540
00541 static void do_print (const char *str)
00542 {
00543   if (print_hook)
00544        (*print_hook) (str);
00545   else outsnl (str);
00546 }
00547
00548 static void depr_dns_timeout1 (const char *value)
00549 {
00550   deprecated_key ("DOMAINTO", "DOMAIN.TIMEOUT");
00551   dns_timeout = ATOI (value);
00552 }
00553
00554 static void depr_dns_timeout2 (const char *value)
00555 {
00556   deprecated_key ("DOMAIN_TO", "DOMAIN.TIMEOUT");
00557   dns_timeout = ATOI (value);
00558 }
00559
00560 static void depr_dns_recurse (const char *value)
00561 {
00562   deprecated_key ("DOMAIN_RECURSE", "DOMAIN.RECURSE");
00563   dns_recurse = ATOI (value);
00564 }
00565
00571 static long do_include_file (const char *value, int len)
00572 {
00573   const char *p = value;
00574   long  rc = 0;
00575
00576   if (*p == '?' && len > 1)
00577      ++p;
00578
00579   /* If this is pass 1 of the parsing (ref. pcpkt.c), then return
00580    */
00581   if (usr_init == NULL)
00582   {
00583     CONFIG_DBG_MSG (2, ("Skipping include file `%s'\n", p));
00584     return (0);
00585   }
00586
00587   if (access(p, 0) == 0)
00588   {
00589     /* Recursion, but we're reentrant.
00590      * !!Fix-me: recursion depth should be limited.
00591      */
00592     UINT  tmp_line = current_line;
00593     char *tmp_file = current_file;
00594
00595     rc = tcp_config (p);
00596
00597     current_line = tmp_line;
00598     current_file = tmp_file;
00599   }
00600   else if (*value != '?')
00601   {
00602     outs (_LANG("\nUnable to open \""));
00603     outs (p);
00604     outsnl ("\"");
00605     rc = 0;
00606   }
00607   return (rc);
00608 }
00609
00610 static void deprecated_key (const char *old_key, const char *new_key)
00611 {
00612 #if defined(USE_DEBUG)
00613   if (current_file && current_line > 0)
00614      printf ("%s (%u): ", current_file, current_line);
00615   printf ("Keyword \"%s\" is deprecated. Use \"%s\" instead.\n",
00616           old_key, new_key);
00617 #endif
00618
00619   ARGSUSED (old_key);
00620   ARGSUSED (new_key);
00621 }
00622
00626 const char *get_argv0 (void)
00627 {
00628   const char *ret;
00629
00630 #if defined(WIN32)
00631   static char buf [MAX_PATH];
00632
00633   if (GetModuleFileNameA(NULL, buf, sizeof(buf)))
00634        ret = buf;
00635   else ret = NULL;
00636
00637 #elif (DOSX & PHARLAP)
00638   static     char buf[MAX_PATHLEN];
00639   CONFIG_INF cnf;
00640   UINT       limit;
00641   CD_DES     descr;
00642   FARPTR     fp;
00643   char      *env, *start;
00644
00645   _dx_config_inf (&cnf, (UCHAR*)&cnf);
00646
00647   if (_dx_ldt_rd(cnf.c_env_sel,(UCHAR*)&descr))
00648      return (NULL);
00649
00650   limit = descr.limit0_15 + ((descr.limit16_19 & 15) << 16);
00651   env   = malloc (limit);
00652   if (!env)
00653      return (NULL);
00654
00655   start = env;
00656   FP_SET (fp, 0, cnf.c_env_sel);
00657   ReadFarMem ((void*)env, fp, limit);
00658
00659   /* The environment is organised like this:
00660    * 'PATH=c:\dos;c:\util',0
00661    *  ..
00662    * 'COMSPEC=c:\dos\command.com',0,0,0
00663    * 'program.exe',0
00664    *
00665    */
00666   while (*(env+1))
00667         env += 1 + strlen (env);
00668   env += 2;
00669   StrLcpy (buf, env, sizeof(buf));
00670   free (start);
00671   ret = buf;
00672
00673 #elif defined(__DMC__)
00674   ret = __argv[0];
00675
00676 #elif defined (__DJGPP__)
00677   #if !defined(WATT32_DOS_DLL)
00678   extern char **__crt0_argv;
00679   #endif
00680   ret = __crt0_argv[0];
00681
00682 #elif defined(_MSC_VER)
00683   extern char **__argv;
00684   ret = __argv[0];
00685
00686 #else
00687   extern char **_argv;   /* Borland, Watcom */
00688   ret = _argv[0];
00689 #endif
00690
00691   if (!ret || !ret[0])
00692      return (NULL);
00693   return (ret);
00694 }
00695
00696 #if !defined(USE_UDP_ONLY)
00697 static void set_recv_win (const char *value)
00698 {
00699   DWORD val = ATOL (value);
00700
00701   if (val < tcp_MaxBufSize)
00702       val = tcp_MaxBufSize;
00703   if (val > MAX_WINDOW)
00704       val = MAX_WINDOW;  /* Window-scaling not yet supported */
00705   tcp_recv_win = val;
00706 }
00707 #endif
00708
00709
00710
00711 /*
00712  * Our table of Wattcp "core" values. Other modules have their
00713  * own tables which are hooked into the chain via `usr_init'.
00714  * If `name' (left column) isn't found in table below, `usr_init'
00715  * is called to pass on `name' and `value' to another module or
00716  * application.
00717  */
00718 static const struct config_table normal_cfg[] = {
00719        { "MY_IP",         ARG_FUNC,   (void*)set_my_ip          },
00720        { "HOSTNAME",      ARG_FUNC,   (void*)set_hostname       },
00721        { "NETMASK",       ARG_ATOIP,  (void*)&sin_mask          },
00722        { "GATEWAY",       ARG_FUNC,   (void*)set_gateway        },
00723        { "NAMESERVER",    ARG_FUNC,   (void*)set_nameserv       },
00724        { "COOKIE",        ARG_FUNC,   (void*)set_cookie         },
00725        { "EADDR",         ARG_FUNC,   (void*)set_eaddr          },
00726        { "ETHIP",         ARG_FUNC,   (void*)set_ethip          },
00727        { "DEBUG",         ARG_FUNC,   (void*)set_debug_on       },
00728        { "BOOTP",         ARG_RESOLVE,(void*)&_bootp_host       },
00729        { "BOOTPTO",       ARG_ATOI,   (void*)&_bootp_timeout    },
00730        { "BOOTP_TO",      ARG_ATOI,   (void*)&_bootp_timeout    },
00731        { "SOCKDELAY",     ARG_ATOI,   (void*)&sock_delay        },
00732        { "MSS",           ARG_ATOI,   (void*)&_mss              },
00733        { "MTU",           ARG_ATOI,   (void*)&_mtu              },
00734
00735        { "DOMAIN.SUFFIX", ARG_FUNC,   (void*)set_domain         },
00736        { "DOMAIN.TIMEOUT",ARG_ATOI,   (void*)&dns_timeout       },
00737        { "DOMAIN.RECURSE",ARG_ATOI,   (void*)&dns_recurse       },
00738        { "DOMAIN.IDNA",   ARG_ATOI,   (void*)&dns_do_idna       },
00739        { "DOMAIN.DO_IPV6",ARG_ATOI,   (void*)&dns_do_ipv6       },
00740        { "DOMAIN.WINDNS", ARG_ATOX_W, (void*)&dns_windns        },
00741
00742        /* These are kept for backward compatability. Delete
00743         * them some day.
00744         */
00745        { "DOMAINSLIST",   ARG_FUNC,   (void*)depr_set_domain1   },
00746        { "DOMAIN_LIST",   ARG_FUNC,   (void*)depr_set_domain2   },
00747        { "DOMAINTO",      ARG_FUNC,   (void*)depr_dns_timeout1  },
00748        { "DOMAIN_TO",     ARG_FUNC,   (void*)depr_dns_timeout2  },
00749        { "DOMAIN_RECURSE",ARG_FUNC,   (void*)depr_dns_recurse   },
00750
00751        { "MULTIHOMES",    ARG_ATOI,   (void*)&multihomes        },
00752        { "ICMP_MASK_REQ", ARG_ATOI,   (void*)&_do_mask_req      },
00753        { "DYNAMIC_HOST",  ARG_ATOI,   (void*)&dynamic_host      },
00754        { "RAND_LPORT",    ARG_ATOI,   (void*)&use_rand_lport    },
00755        { "REDIRECTS",     ARG_FUNC,   (void*)icmp_doredirect    },
00756        { "PRINT",         ARG_FUNC,   (void*)do_print           },
00757        { "INCLUDE",       ARG_FUNC,   (void*)do_include_file    },
00758 #if defined(USE_PROFILER)
00759        { "PROFILE.ENABLE",ARG_ATOI,   (void*)&profile_enable    },
00760        { "PROFILE.FILE",  ARG_STRCPY, (void*)&profile_file      },
00761 #endif
00762 #if defined (USE_LANGUAGE)
00763        { "LANGUAGE",      ARG_FUNC,   (void*)lang_init          },
00764 #endif
00765 #if defined (USE_BSD_API)
00766        { "HOSTS",         ARG_FUNC,   (void*)ReadHostsFile      },
00767        { "SERVICES",      ARG_FUNC,   (void*)ReadServFile       },
00768        { "PROTOCOLS",     ARG_FUNC,   (void*)ReadProtoFile      },
00769        { "NETWORKS",      ARG_FUNC,   (void*)ReadNetworksFile   },
00770        { "NETDB_ALIVE",   ARG_ATOI,   (void*)&netdbCacheLife    },
00771        { "ETHERS",        ARG_FUNC,   (void*)InitEthersFile     },
00772 #endif
00773        { "IP.DEF_TTL",    ARG_ATOI,   (void*)&_default_ttl      },
00774        { "IP.DEF_TOS",    ARG_ATOX_B, (void*)&_default_tos      },
00775        { "IP.ID_INCR",    ARG_ATOI,   (void*)&_ip4_id_increment },
00776        { "IP.DONT_FRAG",  ARG_ATOI,   (void*)&_ip4_dont_frag    },
00777        { "IP.FRAG_REASM", ARG_ATOI,   (void*)&_ip4_frag_reasm   },
00778        { "IP.LOOPBACK",   ARG_ATOX_W, (void*)&loopback_mode     },
00779 #if !defined(USE_UDP_ONLY)
00780        { "DATATIMEOUT",         ARG_ATOI, (void*)&sock_data_timeout }, /* EE Aug-99 */
00781        { "INACTIVE",            ARG_ATOI, (void*)&sock_inactive     },
00782        { "TCP.NAGLE",           ARG_ATOI, (void*)&tcp_nagle         },
00783        { "TCP.OPT.TS",          ARG_ATOI, (void*)&tcp_opt_ts        },
00784        { "TCP.OPT.SACK",        ARG_ATOI, (void*)&tcp_opt_sack      },
00785        { "TCP.OPT.WSCALE",      ARG_ATOI, (void*)&tcp_opt_wscale    },
00786        { "TCP.TIMER.OPEN_TO",   ARG_ATOI, (void*)&tcp_OPEN_TO       },
00787        { "TCP.TIMER.CLOSE_TO",  ARG_ATOI, (void*)&tcp_CLOSE_TO      },
00788        { "TCP.TIMER.RTO_ADD",   ARG_ATOI, (void*)&tcp_RTO_ADD       },
00789        { "TCP.TIMER.RTO_BASE",  ARG_ATOI, (void*)&tcp_RTO_BASE      },
00790        { "TCP.TIMER.RTO_SCALE", ARG_ATOI, (void*)&tcp_RTO_SCALE     },
00791        { "TCP.TIMER.RESET_TO",  ARG_ATOI, (void*)&tcp_RST_TIME      },
00792        { "TCP.TIMER.RETRAN_TO", ARG_ATOI, (void*)&tcp_RETRAN_TIME   },
00793        { "TCP.TIMER.KEEPALIVE", ARG_ATOI, (void*)&tcp_keep_idle     },
00794        { "TCP.TIMER.KEEPINTVL", ARG_ATOI, (void*)&tcp_keep_intvl    },
00795        { "TCP.TIMER.MAX_IDLE",  ARG_ATOI, (void*)&tcp_max_idle      },
00796        { "TCP.TIMER.MAX_VJSA",  ARG_ATOI, (void*)&tcp_MAX_VJSA      },
00797        { "TCP.TIMER.MAX_VJSD",  ARG_ATOI, (void*)&tcp_MAX_VJSD      },
00798        { "TCP.MTU_DISCOVERY",   ARG_ATOI, (void*)&mtu_discover      },
00799        { "TCP.BLACKHOLE_DETECT",ARG_ATOI, (void*)&mtu_blackhole     },
00800        { "TCP.RECV_WIN",        ARG_FUNC, (void*)set_recv_win       },
00801 #endif
00802        { NULL, 0, NULL }
00803      };
00804
00809 void tcp_set_debug_state (WORD x)
00810 {
00811   debug_on = x;
00812 }
00813
00819 static void tcp_inject_config_direct (
00820             const struct config_table *cfg,
00821             const char                *key,
00822             const char                *value)
00823 {
00824   WATT_ASSERT (key);
00825   WATT_ASSERT (value);
00826
00827   if (!key[0])
00828   {
00829     CONFIG_DBG_MSG (1, ("empty keyword\n"));
00830     return;
00831   }
00832   if (!value[0])  /* don't pass empty values to the parser */
00833   {
00834     CONFIG_DBG_MSG (1, ("keyword `%s' with no value\n", key));
00835     return;
00836   }
00837
00838   value = ExpandVarStr (value);
00839   if (!parse_config_table(cfg, NULL, key, value) && usr_init)
00840      (*usr_init) (key, value);
00841 }
00842
00848 void tcp_inject_config (const struct config_table *cfg,
00849                         const char                *key,
00850                         const char                *value)
00851 {
00852   char  theKey  [MAX_NAMELEN +1];
00853   char  theValue[MAX_VALUELEN+1];
00854   char *save_current_file = current_file;
00855   UINT  save_current_line = current_line;
00856
00857   if (!key)
00858   {
00859     CONFIG_DBG_MSG (1, ("NULL keyword\n"));
00860     return;
00861   }
00862
00863   strntrimcpy (theKey, key, MAX_NAMELEN);
00864   theKey[MAX_NAMELEN] = '\0';
00865   strupr (theKey);
00866
00867   if (!value)
00868   {
00869     CONFIG_DBG_MSG (1, ("keyword `%s' with NULL value\n", theKey));
00870     return;
00871   }
00872
00873   strntrimcpy (theValue, value, MAX_VALUELEN);
00874   theValue[MAX_VALUELEN] = '\0';
00875
00876   current_file = NULL;
00877   current_line = 0;
00878
00879   tcp_inject_config_direct (cfg, theKey, theValue);
00880
00881   current_file = save_current_file;
00882   current_line = save_current_line;
00883 }
00884
00885
00886 /*
00887  * Read a character:
00888  *  - if failed (EOF) or read a ^Z, set 'eof' and return '\0'.
00889  *  - else update 'num_read' counter and return char read.
00890  */
00891 #define READNEXTCH(ch, f) \
00892         ((FREAD(&(ch), f) == 1) && (ch != 26) ? (++num_read, ch) : \
00893           (last_eol = got_eol, got_eol = eof = TRUE, ch = '\0'))
00894
00895 /* Either read a char or retrieve the one "read ahead" before.
00896  */
00897 #define READCH(ch, next, f) \
00898         (next ? (ch = next, next = '\0', ch) : READNEXTCH(ch, f))
00899
00900 long tcp_parse_file (WFILE f, const struct config_table *cfg)
00901 {
00902   char   key  [MAX_NAMELEN+1];
00903   char   value[MAX_VALUELEN+1];
00904   char   ch, nextch;
00905   size_t num;            /* # of char in key/value */
00906   long   num_read;       /* # of bytes read */
00907   enum   ParseMode mode;
00908   BOOL   quotemode;
00909   BOOL   stripping;
00910   BOOL   eof;
00911   BOOL   last_eol = FALSE;
00912   BOOL   equal_sign;
00913
00914   num_read = 0;
00915   nextch   = '\0';
00916   eof      = FALSE;
00917
00918   while (!eof)
00919   {
00920     *key = *value = '\0';
00921     mode = ModeKeyword;
00922     num  = 0;
00923     got_eol    = FALSE;
00924     quotemode  = FALSE;
00925     stripping  = TRUE;
00926     equal_sign = FALSE;
00927
00928     for (;;)
00929     {
00930       switch (READCH(ch, nextch, f))
00931       {
00932         case '\0':
00933              if (!last_eol && num)
00934                 CONFIG_DBG_MSG (0, ("Missing line-termination "
00935                                 "could break old WatTcp programs.\n"));
00936              break;
00937
00938         case '\r':
00939              if (READNEXTCH(nextch, f) == '\n')
00940                 nextch = '\0';
00941              /* Fall through */
00942
00943         case '\n':
00944              got_eol = TRUE;
00945              ch = '\0';  /* Do not add */
00946              break;
00947
00948         case '#':
00949         case ';':
00950              if (!quotemode)
00951                 mode = ModeComment;
00952              break;
00953
00954         case '=':
00955              if (!quotemode && mode == ModeKeyword)
00956              {
00957                mode = ModeValue;
00958                num  = 0;
00959                ch   = '\0'; /* Don't add */
00960                stripping  = TRUE;
00961                equal_sign = TRUE;
00962              }
00963              break;
00964
00965         case '\"':
00966              if (mode != ModeValue)
00967              {
00968                ch = '\0';
00969                break;
00970              }
00971
00972              /* Double quotes may be inserted by doubling them (VB-style)
00973               * Ex.: SETTING_1 = "This is a ""quoted"" string."
00974               *      SETTING_2 = This_is_a_""quoted""_string.
00975               */
00976               if (READNEXTCH(nextch, f) == '\"')
00977               {
00978                 nextch = '\0'; /* Ignore next, but keep this 'ch' */
00979               }
00980               else
00981               {
00982                 quotemode ^= 1;
00983                 stripping = FALSE;
00984                 ch = '\0'; /* Do not add */
00985               }
00986               break;
00987
00988         case ' ':
00989         case '\t':
00990              if (stripping)
00991                 ch = '\0';
00992              break;
00993       }   /* end switch */
00994
00995       if (ch)
00996       {
00997         switch (mode)
00998         {
00999           case ModeKeyword:
01000                stripping = FALSE;
01001                if (num <= sizeof(key)-2)
01002                {
01003                  key[num++] = toupper (ch);
01004                  key[num]   = '\0';
01005                }
01006                break;
01007           case ModeValue:
01008                stripping = FALSE;
01009                if (num <= sizeof(value)-2)
01010                {
01011                  value[num++] = ch;
01012                  value[num]   = '\0';
01013                }
01014                break;
01015           default:      /* squelch gcc warning */
01016                break;
01017         }
01018       }
01019
01020       if (got_eol)
01021       {
01022         if (!eof)
01023            current_line++;
01024         if (quotemode)
01025            CONFIG_DBG_MSG (0, ("Missing right \" in quoted string: `%s'\n",
01026                            value));
01027         strrtrim (key);
01028         strrtrim (value);
01029         if (key[0] && value[0])
01030            tcp_inject_config_direct (cfg, key, value);
01031         else if (!key[0] && !value[0] && equal_sign)
01032            CONFIG_DBG_MSG (0, ("Both keyword and value missing\n"));
01033         break;
01034       }
01035     }   /* end for (;;) */
01036   }     /* end while (!eof) */
01037
01038   return (num_read);
01039 }
01040
01041 /*
01042  * Public only because of tcpinfo program.
01043  */
01044 int tcp_config_name (char *name, int max)
01045 {
01046   char *path, *temp;
01047   int   i;
01048
01049   for (i = 0; i < DIM(environ_names); i++)
01050   {
01051     path = getenv (environ_names[i]);
01052     if (path)
01053     {
01054       path = StrLcpy (name, path, max-2);
01055       break;
01056     }
01057   }
01058
01059   if (path)
01060   {
01061     temp = strrchr (path, '\0');
01062     if (temp[-1] != '\\' && temp[-1] != '/')
01063     {
01064       *temp++ = '\\';
01065       *temp = '\0';
01066     }
01067   }
01068   else if (access(config_name,0) == 0)  /* found in current directory */
01069   {
01070     strcpy (name, ".\\");
01071     path = name;
01072   }
01073   else if (_watt_os_ver >= 0x300)  /* not found, get path from argv[0] */
01074   {
01075     const char *argv0 = get_argv0();
01076
01077     if (!argv0 || !argv0[0])
01078        return (0);
01079
01080     StrLcpy (name, argv0, max);
01081     strreplace ('/', '\\', name);
01082
01083     /* If path == "x:", extract path.
01084      * temp -> last '\\' in path.
01085      */
01086     path = (isalpha(name[0]) && name[1] == ':') ? name+2 : name;
01087     temp = strrchr (path, '\\');
01088     if (!temp)
01089        temp = (char*)path;
01090     temp++;
01091     *temp = '\0';             /* 'name' = path of program ("x:\path\") */
01092   }
01093
01094   i = max - strlen (name) - 1;
01095   if (i < 0)
01096      return (0);
01097
01098   strncat (name, config_name, i); /* 'name' = "x:\path\wattcp.cfg" */
01099   strlwr (name);
01100   return (1);
01101 }
01102
01103 /*
01104  * Hack for pcpkt.c/winpcap.c: Bypass parsing of "normal_cfg".
01105  * tcp_config() is called in pcpkt.c/winpcap.c with another config-table.
01106  */
01107 const struct config_table *watt_init_cfg = normal_cfg;
01108
01109 long tcp_config (const char *path)
01110 {
01111   char  name[MAX_PATHLEN] = { 0 };
01112   char *fname = config_name;
01113   WFILE file;
01114   long  len;
01115   int   pass = (usr_init == NULL) ? 1 : 2;
01116
01117   if (_watt_no_config && !path)
01118   {
01119     if (!_watt_user_config_fn)
01120        return (0);
01121     current_file = NULL;
01122     current_line = 0;
01123     return (*_watt_user_config_fn) (pass, watt_init_cfg);
01124   }
01125
01126   if (!path)
01127   {
01128     if (!tcp_config_name(name, sizeof(name)))
01129        goto not_found;
01130     fname = name;
01131   }
01132   else
01133   {
01134     fname = name;
01135     StrLcpy (name, path, sizeof(name));
01136     if (access(fname,0) != 0)
01137        goto not_found;
01138   }
01139
01140   if (!FOPEN(file,fname))  /* shouldn't happen */
01141      goto not_found;
01142
01143   current_file = name;
01144   current_line = 0;
01145
01146   TCP_CONSOLE_MSG (2, ("Parsing `%s' (pass %d)\n", fname, pass));
01147
01148   len = tcp_parse_file (file, watt_init_cfg);
01149
01150   FCLOSE (file);
01151   return (len);
01152
01153 not_found:
01154
01155   /* Warn unless parsing from pcpkt.c/winpcap.c.
01156    */
01157   if (watt_init_cfg == normal_cfg)
01158   {
01159     outs (fname);
01160     outsnl (_LANG(" not found"));
01161   }
01162   return (0);
01163 }
01164
01165 #if defined(USE_BSD_API)
01166
01170 int netdb_init (void)
01171 {
01172   int rc, save = _watt_do_exit;
01173
01174   _watt_do_exit = 0;    /* don't make watt_sock_init() call exit() */
01175   rc = watt_sock_init (0, 0);
01176   _watt_do_exit = save;
01177   return (rc == 0);
01178 }
01179
01180 void netdb_warn (const char *fname)
01181 {
01182   fprintf (stderr, "Warning: `%s' not found\n", fname);
01183 }
01184 #endif
01185
01186 /*
01187  * A test program.
01188  */
01189
01190 #if defined(TEST_PROG)
01191
01192 #include "getopt.h"
01193
01194 const char *cfg_file;
01195
01196 static void not_found2 (const char *key, const char *value)
01197 {
01198   size_t len = strlen (value);
01199   DWORD  ret = 0;
01200
01201   printf ("Unmatched: key `%s', value `%s', len %lu  %s\n",
01202           key, value, len, len >= MAX_VALUELEN-1 ? "(truncated)" : "");
01203
01204   if (!stricmp("HEX_BYTE",key))
01205      set_value (TRUE, value, &ret, sizeof(BYTE));
01206
01207   if (!stricmp("HEX_WORD",key))
01208      set_value (TRUE, value, &ret, sizeof(WORD));
01209
01210   if (!stricmp("HEX_DWORD",key))
01211      set_value (TRUE, value, &ret, sizeof(DWORD));
01212 }
01213
01214 static long my_injector (int pass, const struct config_table *cfg)
01215 {
01216   printf ("my_injector(), pass %d\n", pass);
01217   tcp_inject_config (cfg, "My_IP", "192.168.0.98");
01218   tcp_inject_config (cfg, "NetMask", "255.255.255.0");
01219
01220   /* doing the file again doesn't work
01221    */
01222   tcp_inject_config (cfg, "include", cfg_file);
01223   return (1);
01224 }
01225
01226 void Usage (void)
01227 {
01228   puts ("Usage: pcconfig [-d debug-level] [config-file]\n"
01229         "if config-file is omitted, the default "
01230         "$(WATTCP.CFG)\\WATTCP.CFG is used.");
01231   exit (0);
01232 }
01233
01234 int main (int argc, char **argv)
01235 {
01236   int  ch, cfg_len;
01237   long file_len = 0L;
01238
01239   while ((ch = getopt(argc, argv, "h?d:")) != EOF)
01240     switch (ch)
01241     {
01242       case 'd':
01243            debug_on = ATOI (optarg);
01244            break;
01245       case '?':
01246       case 'h':
01247       default:
01248            Usage();
01249            break;
01250     }
01251
01252   argc -= optind;
01253   argv += optind;
01254   cfg_file = NULL;    /* the default one */
01255
01256   if (*argv)
01257   {
01258     FILE *cfg;
01259
01260     cfg_file = *argv;
01261     cfg = fopen (cfg_file, "rb");
01262     if (cfg)
01263     {
01264       file_len = filelength (fileno(cfg));
01265       fclose (cfg);
01266     }
01267   }
01268
01269   usr_init = not_found2;
01270   cfg_len  = tcp_config (cfg_file);
01271
01272   if (file_len)
01273      printf ("filesize %ld, %d bytes parsed\n", file_len, cfg_len);
01274
01275   printf ("\nTest the config injector:\n");
01276   _watt_user_config (my_injector);
01277   _watt_no_config = 1;
01278   tcp_config (NULL);
01279   return (0);
01280 }
01281 #endif
Generated on Wed Jan 25 15:42:36 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/PCCONFIG.H Source File

SRC/PCCONFIG.H

Go to the documentation of this file.
00001
00003 #ifndef _w32_PCCONFIG_H
00004 #define _w32_PCCONFIG_H
00005
00006 #if !defined (USE_BUFFERED_IO)
00007 #include <fcntl.h> /* Defines O_RDONLY and O_BINARY, needed by FOPEN macro */
00008 #endif
00009
00010 #ifndef __WATT_TCP_H
00011
00014 enum config_tab_types {
00015      ARG_ATOI,
00016      ARG_ATOB,
00017      ARG_ATOW,
00018      ARG_ATOIP,
00019      ARG_ATOX_B,
00020      ARG_ATOX_W,
00021      ARG_ATOX_D,
00022      ARG_STRDUP,
00023      ARG_STRCPY,
00024      ARG_RESOLVE,
00025      ARG_FUNC
00026    };
00027
00030 struct config_table {
00031        const char            *keyword;
00032        enum config_tab_types  type;
00033        void                  *arg_func;
00034      };
00035 #endif
00036
00037 #define sock_inactive      NAMESPACE (sock_inactive)
00038 #define sock_data_timeout  NAMESPACE (sock_data_timeout)
00039 #define sock_delay         NAMESPACE (sock_delay)
00040 #define debug_on           NAMESPACE (debug_on)
00041 #define ctrace_on          NAMESPACE (ctrace_on)
00042 #define multihomes         NAMESPACE (multihomes)
00043 #define usr_init           NAMESPACE (usr_init)
00044 #define usr_post_init      NAMESPACE (usr_post_init)
00045 #define cookies            NAMESPACE (cookies)
00046 #define last_cookie        NAMESPACE (last_cookie)
00047 #define dynamic_host       NAMESPACE (dynamic_host)
00048 #define print_hook         NAMESPACE (print_hook)
00049 #define get_argv0          NAMESPACE (get_argv0)
00050 #define parse_config_table NAMESPACE (parse_config_table)
00051 #define ExpandVarStr       NAMESPACE (ExpandVarStr)
00052
00053 W32_DATA int  sock_inactive;
00054 W32_DATA int  sock_data_timeout;
00055 W32_DATA int  sock_delay;
00056 W32_DATA WORD multihomes;
00057
00058 W32_DATA void (*print_hook)   (const char *);
00059 W32_DATA void (*usr_init)     (const char *, const char*);
00060 W32_DATA void (*usr_post_init)(void);
00061
00062 W32_DATA DWORD cookies [MAX_COOKIES];
00063 W32_DATA WORD  last_cookie;
00064 W32_DATA int   debug_on;
00065 W32_DATA int   ctrace_on;
00066 W32_DATA BOOL  dynamic_host;
00067
00068 extern const struct config_table *watt_init_cfg;
00069
00070 extern const char *get_argv0  (void);
00071 extern void       _add_server (WORD *counter, WORD max, DWORD *array, DWORD value);
00072 extern int         netdb_init (void);
00073 extern void        netdb_warn (const char *fname);
00074
00075 W32_FUNC int  tcp_config_name (char *name, int max);
00076 W32_FUNC long tcp_config      (const char *path);
00077 W32_FUNC void tcp_set_debug_state (WORD x);
00078
00079 W32_FUNC int parse_config_table (const struct config_table *tab,
00080                                  const char *section,
00081                                  const char *name,
00082                                  const char *value);
00083
00084 W32_FUNC const char *ExpandVarStr (const char *str);
00085
00086 /*
00087  * Using buffered I/O speeds up reading config-file, but uses more data/code.
00088  * Non-DOSX targets where memory is tight doesn't "#define USE_BUFFERED_IO"
00089  * by default (see config.h)
00090  */
00091 #if defined (USE_BUFFERED_IO)
00092   typedef FILE*        WFILE;
00093   #define FOPEN(f,n)   ( f = fopen (n, "rb"), (f != NULL) )
00094   #define FREAD(p,f)   fread ((char*)(p), 1, 1, f)
00095   #define FCLOSE(f)    fclose (f)
00096 #else
00097   typedef int          WFILE;
00098   #define FOPEN(f,n)   ( f = open (n, O_RDONLY | O_BINARY), (f != -1) )
00099   #define FREAD(p,f)   read (f, (char*)(p), 1)
00100   #define FCLOSE(f)    close (f)
00101 #endif
00102
00103 extern long tcp_parse_file (WFILE f, const struct config_table *cfg);
00104
00105 extern void tcp_inject_config (
00106             const struct config_table *cfg,
00107             const char                *key,
00108             const char                *value);
00109
00110 #ifndef __WATT_TCP_H
00111 typedef long (*WattUserConfigFunc) (int pass, const struct config_table *cfg);
00112 #endif
00113
00114 /*
00115  * Really is in sock_ini.c, but we need the definition of above
00116  * 'struct config_table'
00117  */
00118 extern   WattUserConfigFunc _watt_user_config_fn;
00119 W32_FUNC WattUserConfigFunc _watt_user_config (WattUserConfigFunc fn);
00120
00121 #endif
00122
Generated on Wed Jan 25 15:42:36 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/PCDBUG.C Source File

SRC/PCDBUG.C

Go to the documentation of this file.
00001
00011 #include <stdio.h>
00012 #include <stdlib.h>
00013 #include <stdarg.h>
00014 #include <string.h>
00015 #include <setjmp.h>
00016 #include <limits.h>
00017 #include <sys/types.h>
00018 #include <sys/stat.h>
00019 #include <ctype.h>
00020 #include <io.h>
00021 #include <arpa/nameser.h>
00022 #include <resolv.h>
00023
00024 #if defined(__DJGPP__) && (DJGPP_MINOR >= 4)
00025 #include <sys/xdevices.h>
00026 #endif
00027
00028 #if defined(WIN32) || defined(_WIN32)
00029 #include <fcntl.h>
00030 #include <share.h>
00031 #endif
00032
00033 #include "wattcp.h"
00034 #include "strings.h"
00035 #include "udp_dom.h"
00036 #include "misc.h"
00037 #include "timer.h"
00038 #include "sock_ini.h"
00039 #include "chksum.h"
00040 #include "ip4_in.h"
00041 #include "ip6_in.h"
00042 #include "ip6_out.h"
00043 #include "pctcp.h"
00044 #include "pcsed.h"
00045 #include "pcarp.h"
00046 #include "pcqueue.h"
00047 #include "pcpkt.h"
00048 #include "pcstat.h"
00049 #include "pcicmp.h"
00050 #include "pcicmp6.h"
00051 #include "pcconfig.h"
00052 #include "netaddr.h"
00053 #include "language.h"
00054 #include "printk.h"
00055 #include "gettod.h"
00056 #include "pppoe.h"
00057 #include "ppp.h"
00058 #include "split.h"
00059 #include "bsddbug.h"
00060 #include "pcdbug.h"
00061
00062 #if defined(USE_GZIP_COMPR)
00063 #include "zlib/zlib.h"
00064 #endif
00065
00066 #define DEBUG_RTP 1
00068 const char *tcpStateName (UINT state)
00069 {
00070   static char  buf[20];
00071   static const char *tcpStates[] = {
00072                     "LISTEN",   "RESOLVE", "SYNSENT", "SYNREC", "ESTAB",
00073                     "ESTCLOSE", "FINWT1",  "FINWT2",  "CLOSWT", "CLOSING",
00074                     "LASTACK",  "TIMEWT",  "CLOSED"
00075                   };
00076
00077   if (state < DIM(tcpStates))
00078      return tcpStates [(int)state];
00079   return itoa (state, buf, 10);
00080 }
00081
00082 DebugProc _dbugxmit = NULL;
00083 DebugProc _dbugrecv = NULL;
00084
00085 #if !defined(USE_DEBUG)
00086
00087 void dbug_init (void)
00088 {
00089   outsnl ("Debug-mode disabled");
00090 }
00091
00092 #else  /* rest of file */
00093
00094 static void  dbug_exit   (void);
00095 static void  dbug_close  (void);
00096 static void  dbug_flush  (void);
00097 static void  dump_options(const void *opt, int len, DWORD ack, BOOL is_ip);
00098 static DWORD dump_data   (const void *data, UINT datalen);
00099 static int   udp_dump    (const _udp_Socket *sock, const in_Header *ip);
00100 static int   tcp_dump    (const _tcp_Socket *sock, const in_Header *ip);
00101
00102 static unsigned    dns_dump     (const BYTE *, unsigned, unsigned);
00103 static const BYTE *dns_resource (const BYTE *, const BYTE *, const BYTE *);
00104 static const BYTE *dns_labels   (const BYTE *, const BYTE *, const BYTE *);
00105
00106 static int write_pcap_header (void);
00107 static int write_pcap_packet (const void *pkt, BOOL out);
00108
00109 #if defined(USE_PPPOE)
00110   static unsigned ccp_dump  (const BYTE *bp);
00111   static unsigned lcp_dump  (const BYTE *bp);
00112   static unsigned ipcp_dump (const BYTE *bp);
00113 #endif
00114
00115 static jmp_buf dbg_jmp;
00116 static void (*prev_hook) (const char*, const char*) = NULL;
00117 static char   dbg_name [MAX_PATHLEN+1] = "WATTCP.DBG";
00118 static BOOL   dbg_linebuf = FALSE;
00119 static BOOL   pcap_mode   = FALSE;
00120 static DWORD  now;         /* ticks or milli-sec */
00121 static BOOL   outbound;    /* transmitting packet? */
00122 static BOOL   in_dbug_dump;
00123 static BOOL   use_gzip;
00124 static char   ip4_src [20];
00125 static char   ip4_dst [20];
00126
00127 static union {
00128        FILE  *stream;
00129        void  *gz_stream;
00130      } dbg_file;
00131
00132
00133 /* IP-fragment handling
00134  */
00135 #define IS_FRAG   0x01      /* is this a fragment? */
00136 #define IS_LAST   0x02      /* is this first fragment? */
00137 #define IS_FIRST  0x04      /* is this last fragment? */
00138
00139 static int frag_status;
00140
00141
00142 #if defined(USE_IPV6)
00143   static char ip6_src [50];
00144   static char ip6_dst [50];
00145   static int  udp6_dump (const _udp_Socket *sock, const in6_Header *ip);
00146 #endif
00147
00148 static struct {
00149        char MAC;
00150        char ARP;
00151        char RARP;
00152        char IP;    /* both IPv/IPv6 */
00153        char BCAST;
00154        char MCAST;
00155        char LOOP;
00156        char NONE;
00157      } filter = { 1,1,1,1,1,1,0,0 };
00158
00159 static struct {
00160        char MAC;
00161        char LLC;
00162        char ARP;
00163        char RARP;
00164        char IP;
00165        char UDP;
00166        char TCP;
00167        char ICMP;
00168        char IGMP;
00169      } debug = { 0,0,1,1,1,1,1,1,1 };
00170
00175 BOOL dbg_mode_all    = 1;
00176 BOOL dbg_print_stat  = 1;
00177 BOOL dbg_dns_details = 1;
00178
00179 #if defined(USE_GZIP_COMPR)
00180 static DWORD bytes_raw = 0UL;  /* raw bytes written */
00181 #endif
00182
00183
00184 /*----------------------------------------------------------------------*/
00185
00186 FILE *dbug_file (void)
00187 {
00188   if (pcap_mode)    /* don't let anyone mess with this file */
00189      return (NULL);
00190   return (dbg_file.stream);
00191 }
00192
00193 void dbug_open (void)
00194 {
00195   const char *fmode = pcap_mode ? "w+b" : "w+t";
00196   const char *end;
00197
00198   if (dbg_file.stream)
00199      return;
00200
00201 #if defined(__DJGPP__) && (DJGPP_MINOR >= 4) /* Just for testing */
00202   if (!stricmp(dbg_name,"/dev/zero"))
00203      __install_dev_zero();
00204
00205   else if (!stricmp(dbg_name,"/dev/full"))
00206      __install_dev_full();
00207 #endif
00208
00209   end = strchr (dbg_name, '\0');
00210   use_gzip = (end && !stricmp(end-3,".gz"));
00211
00212   if (!stricmp(dbg_name,"con") || !stricmp(dbg_name,"stdout"))
00213      dbg_file.stream = stdout;
00214
00215   else if (!stricmp(dbg_name,"stderr"))
00216      dbg_file.stream = stderr;
00217
00218 #if defined(USE_GZIP_COMPR)
00219   else if (pcap_mode && use_gzip)
00220   {
00221 #if defined(WIN32) && !defined(__WATCOMC__)
00222     int fd = _sopen (dbg_name, _O_CREAT | _O_TRUNC | _O_WRONLY,
00223                      SH_DENYWR, S_IREAD | S_IWRITE);
00224     if (fd > -1)
00225        dbg_file.gz_stream = gzdopen (fd, "w+b2"); /* comp-level 2 */
00226 #else
00227     errno = 0;
00228     dbg_file.gz_stream = gzopen (dbg_name, "w+b2");
00229 #endif
00230   }
00231 #endif  /* USE_GZIP_COMPR */
00232   else
00233   {
00234     dbg_file.stream = fopen_excl (dbg_name, fmode);
00235     use_gzip = FALSE;
00236   }
00237
00238   if (!dbg_file.stream)
00239   {
00240     (*_printf) (_LANG("ERROR: unable to open debug file %s; %s\n"),
00241                 dbg_name, strerror(errno));
00242     errno = 0;  /* clear it. It coult confuse callers */
00243     return;
00244   }
00245
00246   if (pcap_mode)
00247   {
00248     if (dbg_file.stream == stdout || dbg_file.stream == stderr)
00249     {
00250       outsnl (_LANG("ERROR: cannot debug to screen with \"DEBUG.PCAP=1\""));
00251       dbug_close();
00252       return;
00253     }
00254     if (write_pcap_header() < 0)
00255     {
00256       (*_printf) (_LANG("ERROR: Failed to write pcap header; %s\n"),
00257                   strerror(errno));
00258       dbug_close();
00259       return;
00260     }
00261   }
00262 #if !defined(__BORLANDC__)  /* buggy output with this */
00263   else if (dbg_linebuf)
00264   {
00265     static char buf[256];
00266     setvbuf (dbg_file.stream, buf, _IOLBF, sizeof(buf));
00267   }
00268 #endif
00269   RUNDOWN_ADD (dbug_exit, 5);
00270 }
00271
00272 /*
00273  * Return TRUE if MAC address is multicast (LSB bit 0 set).
00274  */
00275 static __inline BOOL MAC_is_mcast (const void *addr)
00276 {
00277   return ((*(const BYTE*)addr & 1) == 1);
00278 }
00279
00280 static __inline BOOL MAC_is_bcast (const void *addr)
00281 {
00282   return (!memcmp(addr, _eth_brdcast, _eth_mac_len));
00283 }
00284
00285 /*
00286  * Using NDIS3PKT causes all non-broadcast packets sent to
00287  * appear in receive buffer approx 100 msec later.
00288  * WIN32: Also if _pkt_rxmode == RXMODE_ALL_LOCAL.
00289  *
00290  * To avoid confusion, we print a warning in this case.
00291  */
00292 static __inline BOOL is_looped (const in_Header *ip)
00293 {
00294   if (outbound || _pktserial)
00295      return (FALSE);
00296
00297   if (memcmp(MAC_SRC(ip), _eth_addr, _eth_mac_len))
00298      return (FALSE);
00299
00300   if (MAC_TYP(ip) != IP4_TYPE) /* assume looped if not IPv4 */
00301      return (TRUE);
00302
00303   /* if MAC-src matches, but IP-src is different it could be
00304    * Winsock sending. Thus it's not a looped packet.
00305    */
00306   return (ntohl(ip->source) == my_ip_addr);
00307 }
00308
00309 /*
00310  * Return TRUE if MAC destination address of received/sent link-layer
00311  * packet:
00312  *  - matches our link-layer address.
00313  *  - is broadcast and we don't filter broadcast.
00314  *  - is multicast and we don't filter multicast.
00315  */
00316 static __inline BOOL MatchLinkDestination (const void *addr)
00317 {
00318   if (!memcmp(addr, _eth_addr, _eth_mac_len) ||
00319       (!filter.BCAST && MAC_is_bcast(addr)) ||
00320       (!filter.MCAST && MAC_is_mcast(addr)))
00321      return (TRUE);
00322   return (FALSE);
00323 }
00324
00325 /*
00326  * Return TRUE if destination address of received/sent ARP packet:
00327  *  - matches our ether-address.
00328  *  - is broadcast and we don't filter broadcast
00329  *    (ARP/RARP packets should never use multicast in it's header).
00330  */
00331 static __inline BOOL MatchArpRarp (const arp_Header *arp)
00332 {
00333   if (!memcmp(&arp->dstEthAddr, _eth_addr, _eth_mac_len))
00334      return (TRUE);
00335
00336   if (!filter.BCAST && MAC_is_bcast(&arp->dstEthAddr))
00337      return (TRUE);
00338   return (FALSE);
00339 }
00340
00341 /*
00342  * Return TRUE if destination address of received/sent IP packet:
00343  *  - matches our IP-address.
00344  *  - is broadcast and we don't filter (directed) IP-broadcast.
00345  */
00346 static __inline BOOL MatchIp4Dest (const in_Header *ip)
00347 {
00348   DWORD destin = intel (ip->destination);
00349
00350   if (_ip4_is_local_addr(destin) || (!filter.BCAST && _ip4_is_ip_brdcast(ip)))
00351      return (TRUE);
00352   return (FALSE);
00353 }
00354
00355 #if defined(USE_IPV6)
00356 static __inline BOOL MatchIp6Dest (const in6_Header *ip)
00357 {
00358   const void *dest = &ip->destination;
00359
00360   if (_ip6_is_local_addr(dest) ||
00361       IN6_IS_ADDR_MC_GLOBAL(dest))
00362      return (TRUE);
00363   return (FALSE);
00364 }
00365 #endif
00366
00367 /*
00368  * Return checksum and print "ok" or "ERROR"
00369  */
00370 static __inline const char *DoCheckSum (WORD value, const void *p, int len)
00371 {
00372   static char buf[20];
00373   WORD   chk = CHECKSUM (p, len);
00374
00375   sprintf (buf, "%04X (%s)", value, (chk == 0xFFFF) ? "ok" : "ERROR");
00376   return (buf);
00377 }
00378
00379 /*
00380  * Return name of some known link-layer protocols.
00381  */
00382 static __inline const char *LinkProtocol (WORD type)
00383 {
00384   switch (type)
00385   {
00386     case IP4_TYPE:
00387          return ("IP");
00388     case IP6_TYPE:
00389          return ("IP6");
00390     case ARP_TYPE:
00391          return ("ARP");
00392     case RARP_TYPE:
00393          return ("RARP");
00394     case PPPOE_DISC_TYPE:
00395          return ("PPPoE DISCOVERY");
00396     case PPPOE_SESS_TYPE:
00397          return ("PPPoE SESSION");
00398     default:
00399          return ("unknown");
00400   }
00401 }
00402
00403 /*
00404  * Return name of known IP-protocols.
00405  */
00406 static __inline const char *IpProtocol (BYTE prot)
00407 {
00408   static char buf[4];
00409
00410   switch (prot)
00411   {
00412     case UDP_PROTO:
00413          return ("UDP");
00414     case TCP_PROTO:
00415          return ("TCP");
00416     case ICMP_PROTO:
00417          return ("ICMP");
00418     case IGMP_PROTO:
00419          return ("IGMP");
00420   }
00421   itoa (prot, buf, 10);
00422   return (buf);
00423 }
00424
00425 /*
00426  * Return name for IP's "Type Of Service".
00427  */
00428 static const char *TypeOfService (BYTE tos)
00429 {
00430   static char buf[30];
00431   char  *p = buf;
00432
00433   if (tos == 0)
00434      return (" 0");
00435
00436   *p = '\0';
00437   if (tos & IP_MINCOST)
00438   {
00439     strcat (buf, " Mcost");
00440     tos &= ~IP_MINCOST;
00441   }
00442   if (tos & IP_RELIABILITY)
00443   {
00444     strcat (buf, " Rel");
00445     tos &= ~IP_RELIABILITY;
00446   }
00447   if (tos & IP_THROUGHPUT)
00448   {
00449     strcat (buf, " ThPut");
00450     tos &= ~IP_THROUGHPUT;
00451   }
00452   if (tos & IP_LOWDELAY)
00453   {
00454     strcat (buf, " LwDly");
00455     tos &= ~IP_LOWDELAY;
00456   }
00457   p = strchr (buf, '\0');
00458   if (tos)
00459      sprintf (p, " %02X", tos);
00460   return (buf);
00461 }
00462
00463 /*
00464  * Format time for "Round Trip Time" in msec.
00465  */
00466 static __inline const char *RTT_str (DWORD rtt, DWORD now)
00467 {
00468   static char buf[40];
00469
00470   if (rtt == 0UL || rtt < now)
00471      return ("--");      /* RTT timer stopped */
00472
00473   sprintf (buf, "%ld", get_timediff (rtt, now));
00474   return (buf);
00475 }
00476
00477
00478 /*
00479  * Return string for ARP/RARP opcodes.
00480  */
00481 static __inline const char *ArpOpcode (WORD code)
00482 {
00483   if (code == ARP_REQUEST || code == RARP_REQUEST)
00484      return ("Request");
00485
00486   if (code == ARP_REPLY || code == RARP_REPLY)
00487      return ("Reply");
00488
00489   return ("? op");
00490 }
00491
00492 /*
00493  * Print IP source/destination addresses and ports;
00494  *   "host1 (a) -> host2 (b)"
00495  *
00496  * Note: the udp_Header src/dst port field are not printed.
00497  */
00498 static void dump_addr_port (const char      *proto,
00499                             const void      *sock,
00500                             const in_Header *ip)
00501 {
00502   const tcp_Header *tcp = (const tcp_Header*) ((BYTE*)ip + in_GetHdrLen(ip));
00503
00504   if (!sock)
00505      dbug_printf ("%s:   NO SOCKET: %s (%d) -> %s (%d)\n", proto,
00506                   ip4_src, intel16(tcp->srcPort),
00507                   ip4_dst, intel16(tcp->dstPort));
00508   else
00509   {
00510     const _tcp_Socket *sk = (const _tcp_Socket*) sock;
00511
00512     if (outbound)
00513          dbug_printf ("%s:   %s (%d) -> %s (%d), sock %08lX\n", proto,
00514                       _inet_ntoa(NULL,my_ip_addr),  sk->myport,
00515                       _inet_ntoa(NULL,sk->hisaddr), sk->hisport,
00516                       (DWORD)sock);
00517
00518     else dbug_printf ("%s:   %s (%d) -> %s (%d), sock %08lX\n", proto,
00519                       _inet_ntoa(NULL,sk->hisaddr), sk->hisport,
00520                       _inet_ntoa(NULL,my_ip_addr),  sk->myport,
00521                       (DWORD)sock);
00522   }
00523 }
00524
00525 #if defined(USE_IPV6)
00526 static __inline void ip6_addr_type (char *ret, const void *addr)
00527 {
00528   if (IN6_IS_ADDR_UNSPECIFIED(addr))
00529      strcpy (ret, "(anycast) ");
00530
00531   else if (IN6_IS_ADDR_MULTICAST(addr))
00532      strcpy (ret, "(multicast) ");
00533
00534   else if (IN6_IS_ADDR_MC_NODELOCAL(addr))
00535      strcpy (ret, "(MC node) ");
00536
00537   else if (IN6_IS_ADDR_MC_LINKLOCAL(addr))
00538      strcpy (ret, "(MC link) ");
00539
00540   else if (IN6_IS_ADDR_MC_SITELOCAL(addr))
00541      strcpy (ret, "(MC site) ");
00542
00543   else if (IN6_IS_ADDR_MC_GLOBAL(addr))
00544      strcpy (ret, "(MC global) ");
00545
00546   else if (IN6_IS_ADDR_V4MAPPED(addr))
00547      strcpy (ret, "(ip4-mapped) ");
00548
00549   else if (IN6_IS_ADDR_V4COMPAT(addr))
00550      strcpy (ret, "(ip4-compat) ");
00551
00552   else if (IN6_IS_ADDR_LOOPBACK(addr))
00553      strcpy (ret, "(loopback) ");
00554
00555   else *ret = '\0';
00556 }
00557
00558 static void dump_addr6_port (const char       *proto,
00559                              const void       *sock,
00560                              const in6_Header *ip)
00561 {
00562   const tcp_Header  *tcp = (const tcp_Header*) (ip + 1);
00563   const _tcp_Socket *sk  = (const _tcp_Socket*) sock;
00564
00565   if (!sock)
00566        dbug_printf ("%s:   NO SOCKET: %s (%d) -> %s (%d)\n", proto,
00567                     ip6_src, intel16(tcp->srcPort),
00568                     ip6_dst, intel16(tcp->dstPort));
00569
00570   else if (outbound)
00571        dbug_printf ("%s:   %s (%d) -> %s (%d)\n", proto,
00572                     _inet6_ntoa(&in6addr_my_ip),sk->myport,
00573                     _inet6_ntoa(sk->his6addr),  sk->hisport);
00574
00575   else dbug_printf ("%s:   %s (%d) -> %s (%d)\n", proto,
00576                     _inet6_ntoa(sk->his6addr),  sk->hisport,
00577                     _inet6_ntoa(&in6addr_my_ip),sk->myport);
00578 }
00579 #endif
00580
00581
00582 /*----------------------------------------------------------------------*/
00583
00584 static void link_head_dump (const union link_Packet *pkt)
00585 {
00586   const struct eth_Header *eth;
00587   WORD  type;
00588
00589   if (_pktdevclass == PDCLASS_TOKEN || _pktdevclass == PDCLASS_TOKEN_RIF)
00590   {
00591     const struct tok_Header *tok = &pkt->tok.head;
00592
00593     dbug_printf ("TR:    destin %s, AC %02X, FC %02X\n"
00594                  "       source %s, DSAP %02X, SSAP %02X, Ctrl %02X\n"
00595                  "       type %s (%04X)\n",
00596                  MAC_address (tok->destination), tok->accessCtrl, tok->frameCtrl,
00597                  MAC_address (tok->source), tok->DSAP, tok->SSAP, tok->ctrl,
00598                  LinkProtocol(tok->type), intel16(tok->type));
00599     return;
00600   }
00601
00602   if (_pktdevclass == PDCLASS_FDDI)
00603   {
00604     const struct fddi_Header *fddi = &pkt->fddi.head;
00605
00606     dbug_printf ("FDDI:  destin %s, FC %02X\n"
00607                  "       source %s, DSAP %02X, SSAP %02X, Ctrl %02X\n"
00608                  "       type %s (%04X)\n",
00609                  MAC_address (fddi->destination), fddi->frameCtrl,
00610                  MAC_address (fddi->source), fddi->DSAP, fddi->SSAP,
00611                  fddi->ctrl, LinkProtocol(fddi->type), intel16(fddi->type));
00612     return;
00613   }
00614
00615   if (_pktdevclass == PDCLASS_ARCNET)
00616   {
00617     static const struct search_list arcnet_protos[] = {
00618          { ARCNET_DP_BOOT,    "DataPoint Boot"   },
00619          { ARCNET_DP_MOUNT,   "DataPoint Mount"  },
00620          { ARCNET_PL_BEACON,  "PowerLAN Beacon"  },
00621          { ARCNET_PL_BEACON2, "PowerLAN Beacon2" },
00622          { ARCNET_DIAG,       "Diagnose"         },
00623          { ARCNET_IP6,        "IPv6"             },
00624          { ARCNET_BACNET,     "BACNET"           },
00625          { ARCNET_IP_1201,    "IPv4 (RFC-1201)"  },
00626          { ARCNET_ARP_1201,   "ARP (RFC-1201)"   },
00627          { ARCNET_RARP_1201,  "RARP (RFC-1201)"  },
00628          { ARCNET_ATALK,      "AppleTalk"        },
00629          { ARCNET_ETHER,      "Raw Ether"        }, /* MS LAN-Man/WfWg */
00630          { ARCNET_NOVELL,     "Novell Encap"     },
00631          { ARCNET_IP_1051,    "IPv4 (RFC-1051)"  },
00632          { ARCNET_ARP_1051,   "ARP (RFC-1051)"   },
00633          { ARCNET_BANYAN,     "Banyan"           },
00634          { ARCNET_IPX,        "IPX"              },
00635          { ARCNET_LANSOFT,    "LanSoft"          }
00636        };
00637     const struct arcnet_Header *arc = &pkt->arc.head;
00638     const char  *proto = list_lookup (arc->type, arcnet_protos,
00639                                       DIM(arcnet_protos));
00640
00641     dbug_printf ("ARCNET:destin %02X, flags %02X, sequence %04X\n"
00642                  "       source %02X  %s\n"
00643                  "       type %s\n",
00644                  arc->destination, arc->flags, arc->sequence,
00645                  arc->source, arc->flags == 0xFF ? "Exc-packet" : "",
00646                  proto);
00647     return;
00648   }
00649
00650   WATT_ASSERT (_pktdevclass == PDCLASS_ETHER);
00651
00652   eth = &pkt->eth.head;
00653
00654   dbug_printf ("ETH:   destin %s %s\n"
00655                "       source %s %s\n",
00656                MAC_address (&eth->destination),
00657                MAC_is_bcast(&eth->destination) ? "(broadcast)" :
00658                MAC_is_mcast(&eth->destination) ? "(multicast)" : "",
00659                MAC_address (&eth->source),
00660                MAC_is_bcast(&eth->source) ? "(broadcast)" :
00661                MAC_is_mcast(&eth->source) ? "(multicast)" : "");
00662
00663   type = intel16 (eth->type);
00664   if (type == 0xFFFF)
00665   {
00666     dbug_printf ("       Novell IPX\n");
00667   }
00668   else if (type < 0x600)      /* type is LLC length field */
00669   {
00670     const llc_Header *llc = (const llc_Header*) (eth+1);
00671     unsigned len = type;
00672
00673     dbug_printf ("       IEEE 802.3 encap (LLC: DSAP %02X, SSAP %02X, len %u)\n",
00674                  llc->DSAP, llc->SSAP, len);
00675   }
00676   else
00677     dbug_printf ("       type %s (%04X)\n", LinkProtocol(eth->type), type);
00678 }
00679
00680 /*----------------------------------------------------------------------*/
00681
00682 static int arp_dump (const arp_Header *arp)
00683 {
00684   _inet_ntoa (ip4_src, intel(arp->srcIPAddr));
00685   _inet_ntoa (ip4_dst, intel(arp->dstIPAddr));
00686
00687   return dbug_printf ("ARP:   %s (%d), hw %04X, type %04X\n"
00688                       "       %s (%s) -> %s (%s)\n",
00689                       ArpOpcode(arp->opcode), intel16(arp->opcode),
00690                       arp->hwType, intel16(arp->protType),
00691                       MAC_address (&arp->srcEthAddr), ip4_src,
00692                       MAC_address (&arp->dstEthAddr), ip4_dst);
00693 }
00694
00695 /*----------------------------------------------------------------------*/
00696
00697 static int rarp_dump (const rarp_Header *rarp)
00698 {
00699   _inet_ntoa (ip4_src, intel(rarp->srcIPAddr));
00700   _inet_ntoa (ip4_dst, intel(rarp->dstIPAddr));
00701
00702   return dbug_printf ("RARP:  %s (%d), hw %04X, type %04X\n"
00703                       "       %s (%s) -> %s (%s)\n",
00704                       ArpOpcode(rarp->opcode), intel16(rarp->opcode),
00705                       rarp->hwType, intel16(rarp->protType),
00706                       MAC_address (&rarp->srcEthAddr), ip4_src,
00707                       MAC_address (&rarp->dstEthAddr), ip4_dst);
00708 }
00709
00710 /*----------------------------------------------------------------------*/
00711
00712 static void ip4_dump (const in_Header *ip)
00713 {
00714   WORD  ihl, flg;
00715   DWORD ofs;
00716   int   opt_len;
00717
00718   ofs = intel16 (ip->frag_ofs);
00719   flg = (WORD) (ofs & ~IP_OFFMASK);
00720   ofs = (ofs & IP_OFFMASK) << 3;
00721
00722   frag_status = 0;
00723
00724   if (flg & IP_MF)
00725   {
00726     frag_status |= IS_FRAG;
00727     if (ofs == 0)
00728     {
00729       /* This is 1st fragment. Assume this upper header isn't be fragmented
00730        */
00731       frag_status |= IS_FIRST;
00732     }
00733   }
00734   else if (ofs)
00735           frag_status = (IS_FRAG | IS_LAST);  /* last fragment */
00736
00737   if (!debug.IP)
00738      return;
00739
00740   dbug_printf ("IP4:   %s -> %s\n", ip4_src, ip4_dst);
00741
00742   ihl = in_GetHdrLen (ip);
00743   if (ihl < sizeof(*ip))
00744   {
00745     dbug_write ("       Bad header\n");
00746     return;
00747   }
00748
00749   dbug_printf ("       IHL %u, ver %u, tos%s, len %u,"
00750                " ttl %u, prot %s, chksum %s\n"
00751                "       id %04X, ofs %lu",
00752                ihl, (BYTE)ip->ver, TypeOfService(ip->tos), intel16(ip->length),
00753                (BYTE)ip->ttl, IpProtocol (ip->proto),
00754                DoCheckSum (ip->checksum, ip, ihl),
00755                intel16 (ip->identification), ofs);
00756
00757   if (flg & IP_CE)
00758      dbug_write (", CE");
00759
00760   if (flg & IP_DF)
00761      dbug_write (", DF");
00762
00763   if (frag_status)
00764   {
00765     if (frag_status & IS_FIRST)
00766          dbug_write (", MF");
00767     else dbug_write (", MF (following header invalid)");
00768   }
00769   if (frag_status & IS_LAST)
00770      dbug_write (" (last frag)");
00771
00772   fputc ('\n', dbg_file.stream);
00773   opt_len = ihl - sizeof(*ip);
00774   if (opt_len > 0)
00775      dump_options (ip+1, opt_len, 0, TRUE);
00776 }
00777
00778 /*----------------------------------------------------------------------*/
00779
00780 static int ip4_orig_dump (const in_Header *this_ip,
00781                           const in_Header *orig_ip, int icmp_len)
00782 {
00783   WORD  ihl;
00784   DWORD ofs;
00785
00786   if (icmp_len < SIZEOF(*orig_ip))
00787   {
00788     dbug_write ("           Too little of original IP-header\n");
00789     return dump_data (this_ip, intel16(this_ip->length));
00790   }
00791
00792   ihl = in_GetHdrLen (orig_ip);
00793   if (ihl < sizeof(*orig_ip))
00794   {
00795     dbug_write ("           Bad header\n");
00796     return dump_data (this_ip, intel16(this_ip->length));
00797   }
00798
00799   dbug_printf ("  Orig IP: %s -> %s\n",
00800                _inet_ntoa(NULL,intel(orig_ip->source)),
00801                _inet_ntoa(NULL,intel(orig_ip->destination)));
00802
00803   ofs = (intel16(orig_ip->frag_ofs) & IP_OFFMASK) << 3;
00804
00805   dbug_printf ("           IHL %u, ver %u, tos%s, len %u,"
00806                " ttl %u, prot %s\n"
00807                "           chksum %s, id %04X, ofs %lu\n",
00808                ihl, (BYTE)orig_ip->ver, TypeOfService(orig_ip->tos),
00809                intel16(orig_ip->length), (BYTE)orig_ip->ttl,
00810                IpProtocol (orig_ip->proto),
00811                DoCheckSum (orig_ip->checksum, orig_ip, ihl),
00812                intel16 (orig_ip->identification), ofs);
00813
00814   if (icmp_len <= ihl)
00815      dbug_write ("           No transport header present\n");
00816
00817   else if (orig_ip->proto == TCP_PROTO && icmp_len - ihl >= 4)
00818   {
00819     const tcp_Header *tcp = (const tcp_Header*) ((const BYTE*)orig_ip + ihl);
00820     dbug_printf ("           TCP: port %u -> %u\n",
00821                  intel16(tcp->srcPort), intel16(tcp->dstPort));
00822   }
00823   else if (orig_ip->proto == UDP_PROTO && icmp_len - ihl >= 4)
00824   {
00825     const udp_Header *udp = (const udp_Header*) ((const BYTE*)orig_ip + ihl);
00826     dbug_printf ("           UDP: port %u -> %u\n",
00827                  intel16(udp->srcPort), intel16(udp->dstPort));
00828   }
00829
00830   if (icmp_len > 0)  /* consider only original IP as payload */
00831      return dump_data (orig_ip, icmp_len);
00832   return (1);
00833 }
00834
00835 /*----------------------------------------------------------------------*/
00836
00837 static int icmp4_dump (const in_Header *ip)
00838 {
00839   WORD  len  = in_GetHdrLen (ip);
00840   const ICMP_PKT *icmp = (const ICMP_PKT*) ((const BYTE*)ip + len);
00841   const char     *type_str;
00842   char  buf[200] = "";
00843   char *p = buf;
00844   int   type, code;
00845
00846   len  = intel16 (ip->length) - len;   /* ICMP length */
00847   type = icmp->unused.type;
00848   code = icmp->unused.code;
00849
00850   if (len < sizeof(struct ICMP_info))
00851   {
00852     dbug_write ("ICMP:  Short header\n");
00853     return (1);
00854   }
00855
00856   if (!(frag_status & IS_FRAG))
00857      switch (type)
00858      {
00859        case ICMP_UNREACH:
00860             type_str = icmp_type_str [ICMP_UNREACH];
00861             if (code < DIM(icmp_unreach_str))
00862                  sprintf (buf, "%s: %s", type_str, icmp_unreach_str[code]);
00863             else sprintf (buf, "%s: code %d", type_str, code);
00864             break;
00865
00866        case ICMP_TIMXCEED:
00867             type_str = icmp_type_str [ICMP_TIMXCEED];
00868             if (code < DIM(icmp_exceed_str))
00869                  p += sprintf (p, "%s: %s", type_str, icmp_exceed_str[code]);
00870             else p += sprintf (buf, "%s: code %d", type_str, code);
00871             break;
00872
00873        case ICMP_REDIRECT:
00874             if (code < DIM(icmp_redirect_str))
00875                  strcpy (buf, icmp_redirect_str[code]);
00876             else sprintf (buf, "Redirect; code %d", code);
00877             break;
00878
00879        case ICMP_PARAMPROB:
00880             if (code)
00881                  sprintf (buf, "Param prob code %d", code);
00882             else sprintf (buf, "Param prob at %d", icmp->pointer.pointer);
00883             break;
00884
00885        case ICMP_MASKREQ:
00886        case ICMP_MASKREPLY:
00887             sprintf (buf, "ICMP %s: %s", icmp_type_str[type],
00888                      _inet_ntoa(NULL, intel(icmp->mask.mask)));
00889             break;
00890
00893 #if 0
00894        case ICMP_ROUTERADVERT:
00895        case ICMP_ROUTERSOLICIT:
00896        case ICMP_TSTAMP:
00897        case ICMP_TSTAMPREPLY:
00898        case ICMP_IREQ:
00899        case ICMP_IREQREPLY:
00900 #endif
00901
00902        default:
00903             sprintf (buf, "%s (%d), code %d",
00904                      type < DIM(icmp_type_str) ?
00905                        icmp_type_str[type] : "Unknown", type, code);
00906      }
00907
00908   dbug_printf ("ICMP:  %s -> %s\n", ip4_src, ip4_dst);
00909
00910   if (frag_status)
00911      dbug_printf ("       <%sfragment>\n",
00912                   (frag_status & IS_LAST) ? "last " : "");
00913   else
00914   {
00915     dbug_printf ("       %s, chksum %s\n",
00916                  buf, DoCheckSum(icmp->unused.checksum,icmp,len));
00917
00918     if (type == ICMP_UNREACH || type == ICMP_PARAMPROB)
00919        return ip4_orig_dump (ip, &icmp->ip.ip, len - 8);
00920
00921     if (type == ICMP_TIMXCEED)
00922        return ip4_orig_dump (ip, &icmp->unused.ip, len - 8);
00923   }
00924   return dump_data (icmp, len);
00925 }
00926
00927 /*----------------------------------------------------------------------*/
00928
00929 #if defined(USE_MULTICAST)
00930 static int igmp_dump (const in_Header *ip)
00931 {
00932   WORD  len               = in_GetHdrLen (ip);
00933   const IGMP_packet *igmp = (const IGMP_packet*) ((const BYTE*)ip + len);
00934   char  type[20];
00935
00936   len = intel16 (ip->length) - len;   /* IGMP length */
00937
00938   if (len < sizeof(*igmp))
00939   {
00940     dbug_write ("IGMP:  Short header\n");
00941     return (1);
00942   }
00943
00944   switch (igmp->type)
00945   {
00946     case IGMPv1_QUERY:
00947          strcpy (type, "Query");
00948          break;
00949     case IGMPv1_REPORT:
00950          strcpy (type, "Report");
00951          break;
00952     default:
00953          sprintf (type, "type %d?", igmp->type);
00954          break;
00955   }
00956
00957   dbug_printf ("IGMP:  %s, ver %d, chksum %s, addr %s\n",
00958                type, igmp->version,
00959                DoCheckSum(igmp->checksum, igmp, len),
00960                _inet_ntoa (NULL, intel(igmp->address)));
00961
00962   len -= sizeof(*igmp);
00963   return dump_data (igmp+1, len);
00964 }
00965 #endif  /* USE_MULTICAST */
00966
00967 /*----------------------------------------------------------------------*/
00968
00969 static unsigned ip4_payload_dump (const void *sock, const in_Header *ip)
00970 {
00971 #if defined(USE_MULTICAST)
00972   if (ip->proto == IGMP_PROTO && debug.IGMP)
00973      return igmp_dump (ip);
00974 #endif
00975
00976   if (ip->proto == ICMP_PROTO && debug.ICMP)
00977      return icmp4_dump (ip);
00978
00979   if (ip->proto == UDP_PROTO && debug.UDP)
00980      return udp_dump ((const _udp_Socket*)sock, ip);
00981
00982   if (ip->proto == TCP_PROTO && debug.TCP)
00983      return tcp_dump ((const _tcp_Socket*)sock, ip);
00984
00985   if (debug.IP)  /* dump unsupported IPv4 protocols as hex */
00986   {
00987     WORD  hlen       = in_GetHdrLen (ip);
00988     WORD  len        = intel16 (ip->length) - hlen;
00989     const BYTE *data = (const BYTE*)ip + hlen;
00990     return dump_data (data, min(len,MAX_IP4_DATA-hlen));
00991   }
00992   return (0);
00993 }
00994
00995 /*----------------------------------------------------------------------*/
00996
00997 #if defined(USE_IPV6)
00998 static const char *ip6_next_hdr (BYTE nxt)
00999 {
01000   switch (nxt)
01001   {
01002     case IP6_NEXT_HOP:
01003          return ("HBH");
01004     case IP6_NEXT_TCP:
01005          return ("TCP");
01006     case IP6_NEXT_UDP:
01007          return ("UDP");
01008     case IP6_NEXT_IPV6:
01009          return ("IPV6");
01010     case IP6_NEXT_ROUTING:
01011          return ("ROUTE");
01012     case IP6_NEXT_FRAGMENT:
01013          return ("FRAG");
01014     case IP6_NEXT_ESP:
01015          return ("ESP");
01016     case IP6_NEXT_AUTH:
01017          return ("AUTH");
01018     case IP6_NEXT_ICMP:
01019          return ("ICMP6");
01020     case IP6_NEXT_NONE:
01021          return ("NONE");
01022     case IP6_NEXT_DEST:
01023          return ("DEST");
01024     default:
01025          return ("??");
01026   }
01027 }
01028
01029 const char *icmp6_options (const BYTE *opt, int tot_len)
01030 {
01031   static char buf[50];
01032   char  *p = buf;
01033   int    len, val;
01034
01035   while (tot_len > 0 && p < buf + DIM(buf))
01036   {
01037     switch (val = *opt++)
01038     {
01039       case ND_OPT_SOURCE_LINKADDR:
01040            p += sprintf (p, "src MAC %s, ", MAC_address(opt));
01041            break;
01042       case 0:
01043            p += sprintf (p, "EOL, ");
01044            break;
01045       default:
01046            p += sprintf (p, "opt %d?, ", val);
01047            break;
01048     }
01049     len = (*opt++) << 3;
01050     tot_len -= len;
01051     if (tot_len <= 0)
01052     {
01053       p -= 2;
01054       *p = '\0';
01055       return (buf);
01056     }
01057   }
01058   return (NULL);
01059 }
01060
01061 static int icmp6_dump (const in6_Header *ip)
01062 {
01063   const union ICMP6_PKT *icmp = (const union ICMP6_PKT*) (ip + 1);
01064   unsigned    len      = intel16 (ip->len);
01065   unsigned    type     = icmp->unused.type;
01066   char        buf[200] = "";
01067   char       *p   = buf;
01068   const BYTE *opt = NULL;
01069   int         rc;
01070
01071   if (len < sizeof(icmp->unused))
01072   {
01073     dbug_write ("ICMP6: Short packet\n");
01074     return (1);
01075   }
01076
01077   switch (type)
01078   {
01079     case ICMP6_DST_UNREACH:
01080          sprintf (buf, "Dest unreach");
01081          break;
01082
01083     case ICMP6_PACKET_TOO_BIG:
01084          sprintf (buf, "Pkt too big");
01085          break;
01086
01087     case ICMP6_TIME_EXCEEDED:
01088          sprintf (buf, "Time exceeded");
01089          break;
01090
01091     case ICMP6_PARAM_PROB:
01092          sprintf (buf, "Param problem");
01093          break;
01094
01095     case ICMP6_ECHO_REQUEST:
01096          sprintf (buf, "Echo request");
01097          break;
01098
01099     case ICMP6_ECHO_REPLY:
01100          sprintf (buf, "Echo reply");
01101          break;
01102
01103     case ICMP6_MEMBERSHIP_QUERY:
01104          sprintf (buf, "Member query");
01105          break;
01106
01107     case ICMP6_MEMBERSHIP_REPORT:
01108          sprintf (buf, "Member report");
01109          break;
01110
01111     case ICMP6_MEMBERSHIP_REDUCTION:
01112          sprintf (buf, "Member reduction");
01113          break;
01114
01115     case ICMP6_ROUTER_RENUMBERING:
01116          sprintf (buf, "Router renum");
01117          break;
01118
01119     case ICMP6_WRUREQUEST:
01120          sprintf (buf, "Who are you request");
01121          break;
01122
01123     case ICMP6_WRUREPLY:
01124          sprintf (buf, "Who are you reply");
01125          break;
01126
01127     case ND_ROUTER_SOLICIT:
01128          sprintf (buf, "Router solicitation");
01129          break;
01130
01131     case ND_ROUTER_ADVERT:
01132          p += sprintf (p, "Router advert");
01133          if (len >= sizeof(icmp->radvert))
01134               p += sprintf (p, ", hop-lim %d, managed %d, lifetime %u\n"
01135                                "       reach-time %lu, retrans-time %lu",
01136                             icmp->radvert.hop_limit, icmp->radvert.managed,
01137                             intel16(icmp->radvert.lifetime),
01138                             intel(icmp->radvert.reach_time),
01139                             intel(icmp->radvert.retrans_time));
01140          else p += sprintf (p, ", short packet");
01141          break;
01142
01143     case ND_NEIGHBOR_SOLICIT:
01144          sprintf (buf, "Neighbor solicitation, target %s",
01145                   _inet6_ntoa(&icmp->nd_solic.target));
01146          opt = (const BYTE*)icmp + sizeof(icmp->nd_solic);
01147          opt = (const BYTE*)icmp6_options (opt, len - sizeof(icmp->nd_solic));
01148          break;
01149
01150     case ND_NEIGHBOR_ADVERT:
01151          sprintf (buf, "Neighbor advert");
01152          break;
01153
01154     case ND_REDIRECT:
01155          sprintf (buf, "Redirect");
01156          break;
01157
01158     default:
01159          sprintf (buf, "Unknown type %d", type);
01160          break;
01161   }
01162
01163   rc = dbug_printf ("ICMP6: %s, code %d\n"
01164                     "       chksum %04X (%s)\n",
01165                     buf, icmp->unused.code, icmp->unused.checksum,
01166                     _ip6_icmp_checksum(ip,icmp,len) ? "ok" : "ERROR");
01167   if (opt)
01168       rc += dbug_printf ("       Opt: %s\n", opt);
01169   return (rc);
01170 }
01171
01172 static int ip6_header_dump (const in6_Header *ip)
01173 {
01174   char src_type [20];
01175   char dst_type [20];
01176   int  len;
01177
01178   ip6_addr_type (src_type, &ip->source);
01179   ip6_addr_type (dst_type, &ip->destination);
01180
01181   len = dbug_printf ("IP6:   %s %s-> %s %s\n",
01182                      ip6_src, src_type, ip6_dst, dst_type);
01183   len += dbug_printf ("       ver %d, pri %d, flow %d,%d,%d, len %u, "
01184                       "next-hdr %s (%u), hop-lim %d\n",
01185                       ip->ver, ip->pri, ip->flow_lbl[0],
01186                       ip->flow_lbl[1], ip->flow_lbl[2], intel16(ip->len),
01187                       ip6_next_hdr(ip->next_hdr), ip->next_hdr, ip->hop_limit);
01188   return (len);
01189 }
01190
01191 static unsigned ip6_payload_dump (const void *sock, const in6_Header *ip)
01192 {
01193   if (ip->next_hdr == IP6_NEXT_ICMP && debug.ICMP)
01194      return icmp6_dump (ip);
01195
01196   if (ip->next_hdr == IP6_NEXT_UDP && debug.UDP)
01197      return udp6_dump ((const _udp_Socket*)sock, ip);
01198
01199   if (ip->next_hdr == IP6_NEXT_TCP && debug.TCP)
01200      return tcp_dump ((const _tcp_Socket*)sock, (const in_Header*)ip);
01201
01202   if (debug.IP)    /* dump IPv6-network protocols as hex */
01203   {
01204     WORD len = intel16 (ip->len);
01205     len = min (len, MAX_IP6_DATA-sizeof(*ip));
01206     return dump_data (ip+1, len);
01207   }
01208   return (0);
01209 }
01210 #endif
01211
01212 /*----------------------------------------------------------------------*/
01213
01214 #if defined(USE_PPPOE)
01215 struct token {
01216        int         v;
01217        const char *s;
01218      };
01219
01220 struct token ppp_type2str[] = {
01221              { PPP_IP,    "IP"    },
01222              { PPP_IPV6,  "IP6"   },
01223              { PPP_IPX,   "IPX"   },
01224              { PPP_VJC,   "VJC"   },
01225              { PPP_VJNC,  "VJNC"  },
01226              { PPP_IPCP,  "IPCP"  },
01227              { PPP_IPXCP, "IPXCP" },
01228              { PPP_LCP,   "LCP"   },
01229              { PPP_LQR,   "LQR"   },
01230              { PPP_CCP,   "CCP"   },
01231              { PPP_PAP,   "PAP"   },
01232              { PPP_CHAP,  "CHAP"  },
01233              { PPP_CBCP,  "CBCP"  },
01234              { PPP_COMP,  "COMP"  },
01235              { 0,         NULL    }
01236            };
01237
01238 /*
01239  * Convert a token value to a string; use "fmt" if not found.
01240  */
01241 static const char *tok2str (const struct token *lp, const char *fmt, int v)
01242 {
01243   static char buf[128];
01244
01245   while (lp->s)
01246   {
01247     if (lp->v == v)
01248        return (lp->s);
01249     ++lp;
01250   }
01251   if (!fmt)
01252      fmt = "#%d";
01253   sprintf (buf, fmt, v);
01254   return (buf);
01255 }
01256
01257 static const char *pppoe_get_tag (const BYTE *tag)
01258 {
01259   static char buf[100];
01260   char  *p = buf;
01261   WORD   type = *(WORD*)tag;
01262   int    len  = intel16 (*(WORD*)(tag+2));
01263
01264   switch (type)
01265   {
01266     case PPPOE_TAG_END_LIST:
01267          return ("end");
01268
01269     case PPPOE_TAG_SERVICE_NAME:
01270          len = min (len, SIZEOF(buf)-12);
01271          sprintf (buf, "service-name `%.*s'", len, tag+PPPOE_TAG_HDR_SIZE);
01272          break;
01273
01274     case PPPOE_TAG_AC_NAME:
01275          len = min (len, SIZEOF(buf)-12);
01276          sprintf (buf, "AC-name `%.*s'", len, tag+PPPOE_TAG_HDR_SIZE);
01277          break;
01278
01279     case PPPOE_TAG_AC_COOKIE:
01280          p   += sprintf (p, "AC-cookie ");
01281          tag += PPPOE_TAG_HDR_SIZE;
01282          while (len > 0 && p < buf+sizeof(buf)-4)
01283          {
01284            p += sprintf (p, "%02X-", *tag & 255);
01285            tag++;
01286            len--;
01287          }
01288          *(p-1) = '\0';
01289          break;
01290
01291     case PPPOE_TAG_HOST_UNIQ:
01292          p   += sprintf (p, "host-uniq ");
01293          tag += PPPOE_TAG_HDR_SIZE;
01294          while (len > 0 && p < buf+sizeof(buf)-4)
01295          {
01296            p += sprintf (p, "%02X-", *tag & 255);
01297            tag++;
01298            len--;
01299          }
01300          *(p-1) = '\0';
01301          break;
01302
01303     case PPPOE_TAG_VENDOR_SPES:
01304          sprintf (buf, "vendor spec ID %08lX", *(DWORD*)(tag+4));
01305          break;
01306
01307     case PPPOE_TAG_RELAY_SESS:
01308          sprintf (buf, "relay session %d", *(WORD*)(tag+4));
01309          break;
01310
01311     case PPPOE_TAG_HOST_URL:
01312          len = min (len, SIZEOF(buf)-12);
01313          sprintf (buf, "host URL `%.*s'", len, tag+PPPOE_TAG_HDR_SIZE);
01314          break;
01315
01316     case PPPOE_TAG_MOTM:
01317          len = min (len, SIZEOF(buf)-12);
01318          sprintf (buf, "msg-of-the-minute `%.*s'",
01319                   len, tag+PPPOE_TAG_HDR_SIZE);
01320          break;
01321
01322     case PPPOE_TAG_IP_ROUTE_ADD:
01323          {
01324            char  buf1[20], buf2[20], buf3[20];
01325            const char *dest_net  = _inet_ntoa (buf1, intel(*(DWORD*)(tag+4)));
01326            const char *dest_mask = _inet_ntoa (buf2, intel(*(DWORD*)(tag+8)));
01327            const char *gateway   = _inet_ntoa (buf3, intel(*(DWORD*)(tag+12)));
01328            DWORD metric          = intel (*(DWORD*)(tag+16));
01329
01330            sprintf (buf, "route add: %s %s %s / %lu",
01331                     dest_net, dest_mask, gateway, metric);
01332          }
01333          break;
01334
01335     case PPPOE_TAG_SERVICE_ERR:
01336          return ("service error");
01337
01338     case PPPOE_TAG_AC_SYSTEM_ERR:
01339          return ("AC-system err");
01340
01341     case PPPOE_TAG_GENERIC_ERR:
01342          return ("generic error");
01343
01344     default:
01345          sprintf (buf, "unknown %04X", intel16(type));
01346          break;
01347   }
01348   return (buf);
01349 }
01350
01351 const char *pppoe_get_code (WORD code)
01352 {
01353   switch (code)
01354   {
01355     case PPPOE_CODE_PADI:
01356          return ("PADI");
01357     case PPPOE_CODE_PADO:
01358          return ("PADO");
01359     case PPPOE_CODE_PADR:
01360          return ("PADR");
01361     case PPPOE_CODE_PADS:
01362          return ("PADS");
01363     case PPPOE_CODE_PADT:
01364          return ("PADT");
01365     case PPPOE_CODE_PADM:
01366          return ("PADM");
01367     case PPPOE_CODE_PADN:
01368          return ("PADN");
01369     default:
01370          return ("??");
01371   }
01372 }
01373
01374 static __inline int pppoe_head_dump (const struct pppoe_Packet *pppoe,
01375                                      const char *proto)
01376 {
01377   WORD len = intel16 (pppoe->length);
01378
01379   if (pppoe->ver != 1 || pppoe->type != 1 || len > PPPOE_MAX_DATA)
01380   {
01381     dbug_printf ("PPPOE:  bogus header: ver %u, type %u, len %u\n",
01382                  pppoe->ver, pppoe->type, len);
01383     return (0);
01384   }
01385   return dbug_printf ("PPPOE:  %s, len %u, code %s (%04X), session %d\n",
01386                       proto, len, pppoe_get_code(pppoe->code), pppoe->code,
01387                       intel16(pppoe->session));
01388 }
01389
01390 static int pppoe_disc_dump (const struct pppoe_Packet *pppoe)
01391 {
01392   WORD  tlen = intel16 (pppoe->length);
01393   const BYTE *tags;
01394
01395   if (!pppoe_head_dump(pppoe, "Discovery"))
01396      return (1);
01397
01398   tags = (const BYTE*) &pppoe->data[0];
01399   while (tlen > 0)
01400   {
01401     WORD tag_len = intel16 (*(WORD*)(tags+2));
01402
01403     dbug_printf ("        tag: %s\n", pppoe_get_tag(tags));
01404     tlen -= (PPPOE_TAG_HDR_SIZE + tag_len);
01405     tags += (PPPOE_TAG_HDR_SIZE + tag_len);
01406   }
01407   return (1);
01408 }
01409
01410 static int pppoe_sess_dump (const void *sock, const struct pppoe_Packet *pppoe)
01411 {
01412   WORD  proto, len;
01413   const BYTE *buf;
01414
01415   if (!pppoe_head_dump(pppoe, "Session"))
01416      return (1);
01417
01418   len   = intel16 (pppoe->length) - 2;
01419   proto = intel16 (*(WORD*)&pppoe->data[0]);
01420   buf   = &pppoe->data[2];
01421
01422   dbug_printf ("        Protocol %04X (%s)\n", proto,
01423                tok2str(ppp_type2str, "%u??",proto));
01424
01425   if (proto == PPP_IP)
01426   {
01427     const in_Header *ip = (const in_Header*)buf;
01428
01429     _inet_ntoa (ip4_src, intel(ip->source));
01430     _inet_ntoa (ip4_dst, intel(ip->destination));
01431
01432     ip4_dump (ip);
01433     return ip4_payload_dump (sock, ip);
01434   }
01435
01436   if (proto == PPP_CCP)
01437      return ccp_dump (buf);
01438
01439   if (proto == PPP_LCP)
01440      return lcp_dump (buf);
01441
01442   if (proto == PPP_IPCP)
01443      return ipcp_dump (buf);
01444
01445   return dump_data (buf, len);
01446 }
01447 #endif
01448
01449 /*----------------------------------------------------------------------*/
01450
01451 static const char *udp_tcp_checksum (const in_Header  *ip,
01452                                      const udp_Header *udp,
01453                                      const tcp_Header *tcp)
01454 {
01455   tcp_PseudoHeader ph;
01456   int              len;
01457
01458   memset (&ph, 0, sizeof(ph));
01459   if (udp)
01460   {
01461     len = intel16 (udp->length);
01462     ph.protocol = UDP_PROTO;
01463     ph.checksum = CHECKSUM (udp, len);
01464   }
01465   else
01466   {
01467     len = intel16 (ip->length) - in_GetHdrLen (ip);
01468     ph.protocol = TCP_PROTO;
01469     ph.checksum = CHECKSUM (tcp, len);
01470   }
01471
01472   ph.src    = ip->source;
01473   ph.dst    = ip->destination;
01474   ph.length = intel16 (len);
01475
01476   if (CHECKSUM(&ph,sizeof(ph)) == 0xFFFF)
01477      return ("ok");
01478   return ("ERROR");
01479 }
01480
01481 #if defined(USE_IPV6)
01482 static const char *udp_checksum (const in6_Header *ip, const udp_Header *udp)
01483 {
01484   if (_ip6_checksum(ip, IP6_NEXT_UDP, udp, intel16(ip->len)) == 0xFFFF)
01485      return ("ok");
01486   return ("ERROR");
01487 }
01488
01489 static const char *tcp_checksum (const in6_Header *ip, const tcp_Header *tcp)
01490 {
01491   if (_ip6_checksum(ip, IP6_NEXT_TCP, tcp, intel16(ip->len)) == 0xFFFF)
01492      return ("ok");
01493   return ("ERROR");
01494 }
01495 #endif
01496
01497 /*----------------------------------------------------------------------*/
01498
01499 static __inline BOOL is_dns_packet (WORD src_port, WORD dst_port)
01500 {
01501   WORD dns_port;
01502
01503   if (!dbg_dns_details)
01504      return (FALSE);
01505
01506   dns_port = intel16 (DOM_DST_PORT);
01507
01508 #if 1
01509   if (src_port == dns_port || dst_port == dns_port)
01510      return (TRUE);
01511 #else
01512   if ((!outbound && src_port == dns_port) || /* Rx from DNS */
01513       ( outbound && dst_port == dns_port))   /* Tx to DNS */
01514      return (TRUE);
01515 #endif
01516   return (FALSE);
01517 }
01518
01519 /*----------------------------------------------------------------------*/
01520
01521 static int udp_dump (const _udp_Socket *sock, const in_Header *ip)
01522 {
01523   const char *chk_ok    = "n/a";
01524   WORD  iplen           = intel16 (ip->length) - sizeof(*ip);
01525   const udp_Header *udp = (const udp_Header*) ((BYTE*)ip + in_GetHdrLen(ip));
01526   WORD  udplen          = intel16 (udp->length) - sizeof(*udp);
01527   const BYTE *data      = (const BYTE*) (udp+1);
01528
01529   if (udp->checksum && !frag_status)
01530      chk_ok = udp_tcp_checksum (ip, udp, NULL);
01531
01532   if (frag_status || udplen > iplen)
01533      udplen = min (udplen, iplen);
01534
01535   if (frag_status && !(frag_status & IS_FIRST)) /* is a fragment and not 1st */
01536      return dump_data (udp, iplen);
01537
01538   dump_addr_port ("UDP", sock, ip);
01539
01540   dbug_printf ("       len %d, chksum %04X (%s)\n",
01541                intel16(udp->length), intel16(udp->checksum), chk_ok);
01542
01543   if (udplen >= sizeof(struct DNS_head) &&
01544       is_dns_packet(udp->srcPort,udp->dstPort))
01545      return dns_dump (data, udplen, 0);
01546   return dump_data (data, udplen);
01547 }
01548
01549 #if defined(USE_IPV6)
01550 static int udp6_dump (const _udp_Socket *sock, const in6_Header *ip)
01551 {
01552   WORD  iplen           = intel16 (ip->len);
01553   const udp_Header *udp = (const udp_Header*) (ip + 1);
01554   WORD  udplen          = intel16 (udp->length) - sizeof(*udp);
01555   const BYTE *data      = (const BYTE*) (udp + 1);
01556   const char *chk_ok    = udp_checksum (ip, udp);
01557
01558   udplen = min (udplen, iplen - sizeof(*udp));
01559
01560   dump_addr6_port ("UDP", sock, ip);
01561
01562   dbug_printf ("       len %d, chksum %04X (%s)\n",
01563                intel16(udp->length), intel16(udp->checksum), chk_ok);
01564
01565   if (udplen >= sizeof(struct DNS_head) &&
01566       is_dns_packet(udp->srcPort,udp->dstPort))
01567      return dns_dump (data, udplen, 0);
01568   return dump_data (data, udplen);
01569 }
01570 #endif   /* USE_IPV6 */
01571
01572 /*----------------------------------------------------------------------*/
01573
01574 static int tcp_dump (const _tcp_Socket *sock, const in_Header *ip)
01575 {
01576   const tcp_Header *tcp;
01577   const BYTE       *data;
01578   const char       *chk_ok;
01579   WORD  hlen;
01580   WORD  iplen, dlen, olen;
01581   DWORD win, ack, seq;
01582   char  flgBuf [4*8+1] = { 0 };
01583
01584 #if defined(USE_IPV6)
01585   const in6_Header *ip6 = (const in6_Header*) ip;
01586
01587   if (ip->ver == 6)
01588   {
01589     iplen = intel16 (ip6->len);
01590     tcp   = (const tcp_Header*) (ip6 + 1);
01591     hlen  = tcp->offset << 2;
01592     dlen  = iplen - hlen;
01593   }
01594   else
01595 #endif
01596   {
01597     int j;
01598     iplen = intel16 (ip->length) - sizeof(*ip);
01599     j     = in_GetHdrLen (ip);
01600     tcp   = (const tcp_Header*) ((const BYTE*)ip + j);
01601     hlen  = tcp->offset << 2;
01602     dlen  = intel16 (ip->length) - j - hlen;
01603   }
01604
01605   data = (const BYTE*) tcp + hlen;
01606   win  = intel16 (tcp->window);
01607
01608   if (frag_status || dlen > iplen)
01609      dlen = min (dlen, iplen);
01610
01611   if (hlen < sizeof(*tcp))
01612   {
01613     dbug_write ("       Bad header\n");
01614     return (0);
01615   }
01616
01617   if (frag_status && !(frag_status & IS_FIRST))
01618      return dump_data (tcp, iplen);
01619
01620   if (tcp->flags & tcp_FlagACK)  strcat (flgBuf, " ACK");
01621   if (tcp->flags & tcp_FlagFIN)  strcat (flgBuf, " FIN");
01622   if (tcp->flags & tcp_FlagSYN)  strcat (flgBuf, " SYN");
01623   if (tcp->flags & tcp_FlagPUSH) strcat (flgBuf, " PSH");
01624   if (tcp->flags & tcp_FlagRST)  strcat (flgBuf, " RST");
01625   if (tcp->flags & tcp_FlagURG)  strcat (flgBuf, " URG");
01626   if (tcp->flags & tcp_FlagECN)  strcat (flgBuf, " ECN");
01627   if (tcp->flags & tcp_FlagCWR)  strcat (flgBuf, " CWR");
01628
01629   if (frag_status && !(frag_status & IS_FIRST))
01630      chk_ok = "n/a";
01631   else
01632 #if defined(USE_IPV6)
01633   if (ip->ver == 6)
01634      chk_ok = tcp_checksum (ip6, tcp);
01635   else
01636 #endif
01637      chk_ok = udp_tcp_checksum (ip, NULL, tcp);
01638
01639 #if defined(USE_IPV6)
01640   if (ip->ver == 6)
01641      dump_addr6_port ("TCP", sock, ip6);
01642   else
01643 #endif
01644      dump_addr_port ("TCP", sock, ip);
01645
01646   if (sock)
01647      win <<= outbound ? sock->tx_wscale : sock->rx_wscale;
01648
01649   ack = intel (tcp->acknum);
01650   seq = intel (tcp->seqnum);
01651
01652   dbug_printf ("       flags%s, win %lu, chksum %04X (%s), urg %u\n"
01653                "                  SEQ %10lu,  ACK %10lu\n",
01654                flgBuf, win, intel16(tcp->checksum), chk_ok,
01655                intel16(tcp->urgent), seq, ack);
01656   if (sock)
01657   {
01658     BOOL  in_seq_space;
01659     UINT  state = sock->state;
01660     long  delta_seq, delta_ack;
01661     long  ms_left, ms_right;
01662
01663     if (outbound)
01664     {
01665       if (state == tcp_StateSYNREC && sock->last_acknum[0] == 0)
01666            delta_ack = 0;
01667       else delta_ack = ack - sock->last_acknum[0];
01668
01669       if (state == tcp_StateSYNSENT && sock->last_seqnum[0] == 0)
01670            delta_seq = 0;
01671       else delta_seq = seq - sock->last_seqnum[0];
01672
01673       ((_tcp_Socket*)sock)->last_seqnum[0] = seq;  /* !! unconst */
01674       ((_tcp_Socket*)sock)->last_acknum[0] = ack;
01675     }
01676     else
01677     {
01678       if (state == tcp_StateLISTEN && sock->last_seqnum[1] == 0)
01679            delta_seq = 0;
01680       else delta_seq = seq - sock->last_seqnum[1];
01681
01682       if (state == tcp_StateSYNSENT && sock->last_acknum[1] == 0)
01683            delta_ack = 0;
01684       else delta_ack = ack - sock->last_acknum[1];
01685
01686       ((_tcp_Socket*)sock)->last_seqnum[1] = seq;
01687       ((_tcp_Socket*)sock)->last_acknum[1] = ack;
01688     }
01689
01690     if (sock->missed_seq[0] != sock->missed_seq[1] && !outbound)
01691     {
01692       /* show missing edges relative to his SEQ
01693        */
01694       ms_left  = (long) (seq - sock->missed_seq[1]);
01695       ms_right = (long) (seq - sock->missed_seq[0]);
01696       in_seq_space = SEQ_BETWEEN (seq, sock->missed_seq[1], sock->missed_seq[0]);
01697     }
01698     else if (sock->missed_seq[0] != sock->missed_seq[1] && outbound)
01699     {
01700       /* show missing edges relative to our ACK
01701        */
01702       ms_left  = (long) (ack - sock->missed_seq[1]);
01703       ms_right = (long) (ack - sock->missed_seq[0]);
01704       in_seq_space = FALSE;
01705     }
01706     else
01707     {
01708       ms_left  = 0UL;
01709       ms_right = 0UL;
01710       in_seq_space = FALSE;
01711     }
01712
01713     dbug_printf ("       %-8.8s (dSEQ %10ld, dACK %10ld), MS %ld/%ld%s%s\n"
01714                  "       RCV.NXT %lu, SND.NXT %lu, SND.UNA %ld\n"
01715                  "       KC %d, vjSA %lu, vjSD %lu, CW %d, WW %d, RTO %d, ",
01716                  tcpStateName(state), delta_seq, delta_ack, ms_left, ms_right,
01717                  in_seq_space  ? ", in-SEQ"  : "",
01718                  sock->unhappy ? ", Unhappy" : "",
01719                  sock->recv_next, sock->send_next, sock->send_una,
01720                  sock->karn_count, sock->vj_sa, sock->vj_sd,
01721                  sock->cwindow, sock->wwindow, sock->rto);
01722     dbug_printf ("RTT-diff %s\n", RTT_str(sock->rtt_time, now));
01723   }
01724
01725   olen = (WORD) (hlen - sizeof(*tcp));
01726   if (olen > 0)
01727      dump_options (tcp+1, olen, ack, FALSE);
01728
01729   if (dlen > sizeof(struct DNS_head) &&
01730       is_dns_packet(tcp->srcPort,tcp->dstPort))
01731   {
01732     WORD dns_len = intel16 (*(WORD*)data);
01733
01734     if (dns_len == dlen-2)
01735        return dns_dump (data+2, dlen-2, dns_len);
01736   }
01737   return dump_data (data, dlen);
01738 }
01739
01740 /*----------------------------------------------------------------------*/
01741
01742 static BOOL dbug_filter (void)
01743 {
01744   const struct pkt_split *ps = outbound ? pkt_get_split_out() :
01745                                           pkt_get_split_in();
01746   for ( ; ps->data; ps++)
01747   {
01748     switch (ps->type)
01749     {
01750       case TYPE_ETHER_HEAD:
01751            if (!outbound)
01752            {
01753              const eth_Header *eth = (const eth_Header*) ps->data;
01754
01755              if (filter.MAC && !MatchLinkDestination(&eth->destination))
01756                 return (FALSE);
01757              if (filter.LOOP && !memcmp(&eth->source,_eth_addr,_eth_mac_len))
01758                 return (FALSE);
01759            }
01760            break;
01761
01762       case TYPE_TOKEN_HEAD:
01763            if (!outbound)
01764            {
01765              const tok_Header *tok = (const tok_Header*) ps->data;
01766
01767              if (filter.MAC && !MatchLinkDestination(&tok->destination))
01768                 return (FALSE);
01769              if (filter.LOOP && !memcmp(&tok->source,_eth_addr,_eth_mac_len))
01770                 return (FALSE);
01771            }
01772            break;
01773
01774       case TYPE_FDDI_HEAD:
01775            if (!outbound)
01776            {
01777              const fddi_Header *fddi = (const fddi_Header*) ps->data;
01778
01779              if (filter.MAC && !MatchLinkDestination(&fddi->destination))
01780                 return (FALSE);
01781              if (filter.LOOP && !memcmp(&fddi->source,_eth_addr,_eth_mac_len))
01782                 return (FALSE);
01783            }
01784            break;
01785
01786       case TYPE_ARP:
01787            if (!outbound)
01788            {
01789              const arp_Header *arp = (const arp_Header*) ps->data;
01790
01791              if (filter.ARP && !MatchArpRarp(arp))
01792                 return (FALSE);
01793              if (filter.LOOP && !memcmp(&arp->srcEthAddr,_eth_addr,_eth_mac_len))
01794                 return (FALSE);
01795            }
01796            return (debug.ARP);
01797
01798       case TYPE_RARP:
01799            if (!outbound)
01800            {
01801              const rarp_Header *rarp = (const rarp_Header*) ps->data;
01802
01803              if (filter.RARP && !MatchArpRarp(rarp))
01804                 return (FALSE);
01805              if (filter.LOOP && !memcmp(&rarp->srcEthAddr,_eth_addr,_eth_mac_len))
01806                 return (FALSE);
01807            }
01808            return (debug.RARP);
01809
01810       case TYPE_PPPOE_SESS:
01811       case TYPE_PPPOE_DISC:
01812            break;
01813
01814       case TYPE_IP4:
01815            if (!outbound)
01816            {
01817              const in_Header *ip = (const in_Header*) ps->data;
01818
01819              if (filter.IP && !MatchIp4Dest(ip))
01820                 return (FALSE);
01821              if (filter.LOOP && intel(ip->source) == my_ip_addr)
01822                 return (FALSE);
01823            }
01824            return (TRUE);
01825
01826 #if defined(USE_IPV6)
01827       case TYPE_IP6:
01828            if (!outbound)
01829            {
01830              const in6_Header *ip6 = (const in6_Header*) ps->data;
01831
01832              if (filter.IP && !MatchIp6Dest(ip6))
01833                 return (FALSE);
01834              if (filter.LOOP &&
01835                  IN6_ARE_ADDR_EQUAL(ip6->source, &in6addr_my_ip))
01836                 return (FALSE);
01837            }
01838            return (TRUE);
01839 #endif
01840
01841       default:
01842            return (TRUE);  /* don't have filter for anything else */
01843     }
01844   }
01845   return (TRUE);           /* didn't match the component; allow it */
01846 }
01847
01848 /*----------------------------------------------------------------------*/
01849
01850 static const char *pkt_driver_ver (void)
01851 {
01852   static char buf[10];
01853   BYTE   ver[4];
01854
01855   if (!pkt_get_drvr_ver((DWORD*)&ver))
01856      return ("?");
01857
01858 #if defined(WIN32)  /* NPF.SYS ver e.g. 3.1.0.22 */
01859   sprintf (buf, "%d.%d.%d.%d", ver[3], ver[2], ver[1], ver[0]);
01860 #else
01861   sprintf (buf, "%d.%02d", ver[1], ver[0]);
01862 #endif
01863   return (buf);
01864 }
01865
01866 static const char *pkt_api_ver (void)
01867 {
01868   static char buf[10];
01869   DWORD  ver;
01870
01871   if (!pkt_get_api_ver(&ver))
01872      return ("?");
01873
01874   if (ver >= 255)  /* assumed to be MSB.LSB */
01875        sprintf (buf, "%d.%02d", hiBYTE(ver), loBYTE(ver));
01876   else sprintf (buf, "%d", (BYTE)ver);
01877   return (buf);
01878 }
01879
01880 /*----------------------------------------------------------------------*/
01881
01882 static void dbug_dump (const void *sock, const in_Header *ip,
01883                        const char *fname, unsigned line, BOOL out)
01884 {
01885   static BOOL arp_dumped = FALSE;
01886   int    errno_save = errno;
01887
01888   WATT_ASSERT (ip);
01889
01890   outbound = out;
01891   frag_status = 0;
01892   now = set_timeout (0);
01893
01894   if (setjmp(dbg_jmp))
01895   {
01896     (*_printf) ("\ndbug_dump: write failed; %s\n", strerror(errno));
01897     dbug_close();
01898     goto quit;
01899   }
01900
01901   if (pcap_mode)
01902   {
01903     int rc = 0;
01904
01905     if (!dbg_file.stream || !(filter.NONE || dbug_filter()))
01906        goto quit;
01907
01908     if (out && _eth_last.tx.size)
01909        rc = write_pcap_packet (MAC_HDR(ip), TRUE);
01910
01911     else if (!out && _eth_last.rx.size)
01912        rc = write_pcap_packet (MAC_HDR(ip), FALSE);
01913
01914     if (rc < 0)
01915     {
01916       (*_printf) (_LANG("\ndbug_dump: write failed; %s\n"), strerror(errno));
01917       dbug_close();
01918     }
01919     goto quit;
01920   }
01921
01922   if (!arp_dumped)
01923   {
01924     arp_dumped = TRUE;
01925
01926 #if defined(WIN32)
01927   #define FORMAT "%s\nWinPcap: \"%s\"\n          NPF.SYS ver %s, NDIS ver %s, mode 0x%02X\n\n"
01928 #else
01929   #define FORMAT "%s\nPKTDRVR: \"%s\", ver %s, API ver %s, mode %d\n\n"
01930 #endif
01931     dbug_printf (FORMAT, wattcpVersion(), _pktdrvrname,
01932                  pkt_driver_ver(), pkt_api_ver(), _pkt_rxmode);
01933
01934 #if !defined(__BORLANDC__) /* Some weird bug with Borland */
01935     _arp_debug_dump();     /* GvB 2002-09 now encapsuled in pcarp.c */
01936
01937     if (_bootp_on || _dhcp_on || _rarp_on)
01938        dbug_printf ("       Above routing data may be overridden by "
01939                     "DHCP/BOOTP/RARP\n");
01940 #endif
01941   }
01942
01943   if (!filter.NONE && !dbug_filter())
01944      goto quit;
01945
01946   dbug_printf ("\n%s: ", outbound ? "Transmitted" : "Received");
01947   dbug_printf ("%s (%u), ", fname, line);
01948   dbug_printf ("time %s", elapsed_str(now));
01949   dbug_printf ("%s\n", is_looped(ip) ? ", Link-layer loop!" : "");
01950
01951   /* One of PDCLASS_ETHER/PDCLASS_TOKEN/PDCLASS_FDDI/PDCLASS_ARCNET
01952    */
01953   if (!_pktserial)
01954   {
01955     union link_Packet *pkt  = (union link_Packet*) MAC_HDR (ip);
01956     WORD               type = MAC_TYP (ip);
01957
01958     if (debug.MAC)
01959        link_head_dump (pkt);
01960
01961     if (_pktdevclass == PDCLASS_ARCNET)
01962     {
01963       if (type == ARCNET_IP_1051 ||  /* Map to IANA proto-numbers */
01964           type == ARCNET_IP_1201)
01965            type = IP4_TYPE;
01966       else if (type == ARCNET_ARP_1051 ||
01967                type == ARCNET_ARP_1201)
01968            type = ARP_TYPE;
01969       else type = 0;                 /* unsupported */
01970     }
01971     else if (type == 0xFFFF)
01972     {
01973       dbug_printf ("IPX:   unsupported\n");
01974       goto quit;
01975     }
01976     else if (intel16(type) < 0x600)  /* type is IEEE 802.3 length field */
01977     {
01978       const llc_Header *llc = (const llc_Header*) (&pkt->eth.head + 1);
01979
01980       /* !! could be NetBeui, VLAN etc. */
01981       dbug_printf ("LLC:   unsupported\n");
01982       if (debug.LLC)
01983          dump_data (llc+1, intel16(type));
01984       goto quit;
01985     }
01986
01987     if (type == ARP_TYPE)
01988     {
01989       arp_dump ((const arp_Header*)ip);
01990       goto quit;
01991     }
01992
01993     if (type == RARP_TYPE)
01994     {
01995       rarp_dump ((const rarp_Header*)ip);
01996       goto quit;
01997     }
01998
01999 #if defined(USE_PPPOE)
02000     if (type == PPPOE_DISC_TYPE)
02001     {
02002       pppoe_disc_dump ((const struct pppoe_Packet*)pkt->eth.data);
02003       goto quit;
02004   }
02005     if (type == PPPOE_SESS_TYPE)
02006     {
02007       pppoe_sess_dump (sock, (const struct pppoe_Packet*)pkt->eth.data);
02008       goto quit;
02009     }
02010 #endif
02011
02012 #if defined(USE_IPV6)
02013     if (type == IP6_TYPE && ip->ver == 6)
02014        goto ip6_dmp;
02015 #endif
02016
02017     if (type != IP4_TYPE)
02018     {
02019       const BYTE *data;
02020
02021       if (!debug.MAC)
02022          dbug_printf ("Unknown type %04X\n",
02023                       _pktdevclass == PDCLASS_ARCNET ? type : intel16(type));
02024
02025       data = (const BYTE*)pkt + _pkt_ip_ofs;
02026       if (out && _eth_last.tx.size > _pkt_ip_ofs)
02027          dump_data (data, _eth_last.tx.size - _pkt_ip_ofs);
02028       else if (!out && _eth_last.rx.size > _pkt_ip_ofs)
02029          dump_data (data, _eth_last.rx.size - _pkt_ip_ofs);
02030       goto quit;
02031     }
02032   }
02033
02034   if (ip->ver == 4)
02035   {
02036     _inet_ntoa (ip4_src, intel(ip->source));
02037     _inet_ntoa (ip4_dst, intel(ip->destination));
02038
02039     ip4_dump (ip);
02040     ip4_payload_dump (sock, ip);
02041   }
02042 #if defined(USE_IPV6)
02043   else if (ip->ver == 6)
02044   {
02045     const struct in6_Header *ip6;
02046     const char  *addr;
02047
02048 ip6_dmp:
02049     ip6  = (const struct in6_Header*) ip;
02050     addr = _inet6_ntoa (ip6->source);
02051     strcpy (ip6_src, addr ? addr : "(null)");
02052
02053     addr = _inet6_ntoa (ip6->destination);
02054     strcpy (ip6_dst, addr ? addr : "(null)");
02055
02056     if (debug.IP)
02057        ip6_header_dump (ip6);
02058     ip6_payload_dump (sock, ip6);
02059   }
02060 #endif
02061   else
02062   {
02063     WORD len = intel16 (ip->length);
02064     dbug_printf ("IP?:   ver %d\n", ip->ver);
02065     dump_data (ip, min(ETH_MAX_DATA,len));
02066   }
02067
02068 quit:
02069   errno = errno_save;
02070 }
02071
02072 /*----------------------------------------------------------------------*/
02073
02074 static void dbug_send (const void *sock, const in_Header *ip,
02075                        const char *fname, unsigned line)
02076 {
02077   if (!dbg_file.stream)
02078      return;
02079
02080   in_dbug_dump = TRUE;
02081   dbug_dump (sock, ip, fname, line, TRUE);
02082   in_dbug_dump = FALSE;
02083   dbug_flush();
02084 }
02085
02086 static void dbug_recv (const void *sock, const in_Header *ip,
02087                        const char *fname, unsigned line)
02088 {
02089   if (!dbg_file.stream)
02090      return;
02091
02092   in_dbug_dump = TRUE;
02093   dbug_dump (sock, ip, fname, line, FALSE);
02094   in_dbug_dump = FALSE;
02095   dbug_flush();
02096 }
02097
02098 /*
02099  * Print IP or TCP-options
02100  */
02101 static void dump_options (const void *opt_p, int len, DWORD ack, BOOL is_ip)
02102 {
02103   const BYTE *opt   = (const BYTE*) opt_p;
02104   const BYTE *start = opt;
02105   BYTE  val8;
02106   WORD  val16;
02107   DWORD val32;
02108   int   i, num, num_opt = 0;
02109
02110   dbug_write ("       Options:");
02111
02112   while (opt < start+len && num_opt < 10)
02113   {
02114     switch (*opt)  /* Note: IP-option includes copy/class bits */
02115     {
02116       case TCPOPT_EOL:
02117    /* case IPOPT_EOL: */
02118            dbug_write (" EOL\n");
02119            return;
02120
02121       case TCPOPT_NOP:
02122    /* case IPOPT_NOP: */
02123            dbug_write (" NOP");
02124            opt++;
02125            continue;
02126
02127       case TCPOPT_MAXSEG:
02128            if (!is_ip)
02129            {
02130              val16 = intel16 (*(WORD*)(opt+2));
02131              dbug_printf (" MSS %u", val16);
02132            }
02133            break;
02134
02135       case TCPOPT_WINDOW:
02136            if (!is_ip)
02137            {
02138              val8 = opt[2];
02139              dbug_printf (" Wscale 2^%d", val8);
02140            }
02141            break;
02142
02143       case TCPOPT_SACK:
02144            if (is_ip)
02145               break;
02146            dbug_write (" SACK ");
02147            num = (*(opt+1) - 2) / SIZEOF(DWORD);
02148            num = min (num, len/SIZEOF(DWORD));
02149
02150            for (i = 0; i < num; i++)
02151            {
02152              DWORD origin  = intel (*(DWORD*)(opt+2+4*i));
02153              DWORD relsize = intel (*(DWORD*)(opt+6+4*i));
02154              dbug_printf ("blk %d {%ld/%ld}, ", i+1,
02155                           (long)(ack-origin-1),
02156                           (long)(ack-origin+relsize));
02157            }
02158            break;
02159
02160       case TCPOPT_SACK_PERM:
02161            if (!is_ip)
02162               dbug_write (" SACK-OK");
02163            break;
02164
02165       case TCPOPT_ECHO:
02166            if (!is_ip)
02167            {
02168              val32 = intel (*(DWORD*)(opt+2));
02169              dbug_printf (" Echo %lu", val32);
02170            }
02171            break;
02172
02173       case TCPOPT_CHKSUM_REQ:
02174            if (!is_ip)
02175            {
02176              val8 = opt[2];
02177              dbug_printf (" ChkReq %d", val8);
02178            }
02179            break;
02180
02181       case TCPOPT_CHKSUM_DAT:
02182            if (!is_ip)
02183            {
02184              num = opt[1];
02185              dbug_write (" ChkDat ");
02186              for (i = 0; i < num; i++)
02187                  dbug_printf ("%02X", opt[2+i]);
02188            }
02189            break;
02190
02191       case TCPOPT_ECHOREPLY:
02192    /* case IPOPT_RR: */
02193            if (is_ip)
02194            {
02195              dbug_write (" RR");
02196              num = *(opt+1) - 3;
02197              num = min (num, len-1);
02198              for (i = 0; i < num; i += sizeof(DWORD))
02199              {
02200                val32 = intel (*(DWORD*)(opt+3+i));
02201                dbug_printf (" %s", _inet_ntoa(NULL,val32));
02202              }
02203            }
02204            else
02205            {
02206              val32 = intel (*(DWORD*)(opt+2));
02207              dbug_printf (" Echoreply %lu", val32);
02208            }
02209            break;
02210
02211       case TCPOPT_TIMESTAMP:
02212            if (!is_ip)
02213            {
02214              val32 = intel (*(DWORD*)(opt+2));
02215              dbug_printf (" TS <%lu", val32);
02216              val32 = intel (*(DWORD*)(opt+6));
02217              dbug_printf ("/%lu>", val32);
02218            }
02219            break;
02220
02221       case TCPOPT_CC:
02222            if (!is_ip)
02223            {
02224              val32 = intel (*(DWORD*)(opt+2));
02225              dbug_printf (" CC %lu", val32);
02226            }
02227            break;
02228
02229       case TCPOPT_CCNEW:
02230            if (!is_ip)
02231            {
02232              val32 = intel (*(DWORD*)(opt+2));
02233              dbug_printf (" CCnew %lu", val32);
02234            }
02235            break;
02236
02237       case TCPOPT_CCECHO:
02238            if (!is_ip)
02239            {
02240              val32 = intel (*(DWORD*)(opt+2));
02241              dbug_printf (" CCecho %lu", val32);
02242            }
02243            break;
02244
02245       case TCPOPT_SIGNATURE:
02246            if (!is_ip)
02247            {
02248              if (opt > (const BYTE*)opt_p)
02249                 dbug_write ("\n               ");
02250              dbug_write (" MD5 ");
02251              for (i = 0; i < TCPOPT_SIGN_LEN; i++)
02252                  dbug_printf ("%02X ", opt[2+i]);
02253            }
02254            break;
02255
02256       case IPOPT_TS:
02257            if (is_ip)
02258            {
02259              DWORD ip = intel (*(DWORD*)(opt+4));
02260              DWORD ts = intel (*(DWORD*)(opt+8));
02261              dbug_printf (" TS <%s/%lus..>", _inet_ntoa(NULL,ip), ts);
02262            }
02263            break;
02264
02265       case IPOPT_SECURITY:
02266            if (is_ip)
02267            {
02268              val32 = intel (*(DWORD*)(opt+2));
02269              dbug_printf (" SEC %08lX", val32);
02270            }
02271            break;
02272
02273       case IPOPT_SATID:
02274            if (is_ip)
02275            {
02276              val16 = intel16 (*(WORD*)(opt+2));
02277              dbug_printf (" SATID %04X", val16);
02278            }
02279            break;
02280
02281       case IPOPT_RA:
02282            if (is_ip)
02283            {
02284              val16 = intel16 (*(WORD*)(opt+2));
02285              dbug_printf (" RA %u", val16);
02286            }
02287            break;
02288
02289       case IPOPT_LSRR:
02290       case IPOPT_SSRR:
02291            if (!is_ip)
02292               break;
02293            dbug_write (*opt == IPOPT_LSRR ? " LSRR" : " SSRR");
02294            num = *(opt+1) - 3;
02295            num = min (num, len-1);
02296            for (i = 0; i < num; i += sizeof(DWORD))
02297            {
02298              DWORD route = intel (*(DWORD*)(opt+3+i));
02299              dbug_printf (" %s", _inet_ntoa(NULL,route));
02300            }
02301            break;
02302
02303       default:
02304            dbug_printf (" opt %d?", *opt);
02305     }
02306     opt += *(opt+1);
02307     num_opt++;
02308   }
02309   fputc ('\n', dbg_file.stream);
02310 }
02311
02312 /*----------------------------------------------------------------------*/
02313
02314 static DWORD dump_data (const void *data_p, UINT datalen)
02315 {
02316   const BYTE *data = (const BYTE*) data_p;
02317   UINT  ofs;
02318   DWORD len = 0;
02319
02320   if (!dbg_mode_all)
02321      return (1);
02322
02323   for (ofs = 0; ofs < datalen; ofs += 16)
02324   {
02325     UINT j;
02326
02327     if (ofs == 0)
02328          len += dbug_printf ("%u:%s%04X: ", datalen,
02329                              datalen > 9999 ? " "   :
02330                              datalen > 999  ? "  "  :
02331                              datalen > 99   ? "   " :
02332                              "    ", ofs);
02333     else len += dbug_printf ("       %04X: ", ofs);
02334
02335     for (j = 0; j < 16 && j+ofs < datalen; j++)
02336         len += dbug_printf ("%02X%c", (unsigned)data[j+ofs],
02337                             j == 7 ? '-' : ' ');
02338
02339     for ( ; j < 16; j++)       /* pad line to 16 positions */
02340         len += dbug_write ("   ");
02341
02342     for (j = 0; j < 16 && j+ofs < datalen; j++)
02343     {
02344       if (data[j+ofs] < ' ')   /* non-printable */
02345            fputc ('.', dbg_file.stream);
02346       else fputc (data[j+ofs], dbg_file.stream);
02347       len++;
02348     }
02349     fputc ('\n', dbg_file.stream);
02350     len++;
02351   }
02352   return (len);
02353 }
02354
02355 /*----------------------------------------------------------------------*/
02356
02357 static void set_debug_file (const char *value)
02358 {
02359   StrLcpy (dbg_name, value, sizeof(dbg_name)-1);
02360 }
02361
02362 static void set_debug_mode (const char *value)
02363 {
02364   if (!stricmp(value,"ALL"))
02365      dbg_mode_all = 1;
02366   if (!stricmp(value,"HEADER"))
02367      dbg_mode_all = 0;
02368 }
02369
02370 static void set_debug_filter (const char *value)
02371 {
02372   char val[80];
02373
02374   StrLcpy (val, value, sizeof(val));
02375   strupr (val);
02376
02377   if (strstr(val,"ALL"))
02378   {
02379     memset (&filter, 1, sizeof(filter));
02380     filter.NONE = FALSE;
02381   }
02382   else if (strstr(val,"NONE"))
02383   {
02384     memset (&filter, 0, sizeof(filter));
02385     filter.NONE = TRUE;
02386   }
02387   else
02388   {
02389     filter.NONE  = FALSE;
02390     filter.MAC   = (strstr(val,"ETH" )  != NULL) || (strstr(val,"MAC") != NULL);
02391     filter.ARP   = (strstr(val,"ARP" )  != NULL);
02392     filter.RARP  = (strstr(val,"RARP")  != NULL);
02393     filter.IP    = (strstr(val,"IP"  )  != NULL);
02394     filter.BCAST = (strstr(val,"BCAST") != NULL);
02395     filter.MCAST = (strstr(val,"MCAST") != NULL);
02396     filter.LOOP  = (strstr(val,"LOOP")  != NULL);
02397   }
02398 }
02399
02400 static void set_debug_proto (const char *value)
02401 {
02402   char val[80];
02403
02404   StrLcpy (val, value, sizeof(val));
02405   strupr (val);
02406
02407   if (!strcmp(val,"ALL"))
02408      memset (&debug, 1, sizeof(debug));
02409   else
02410   {
02411     memset (&debug, 0, sizeof(debug));
02412     debug.MAC  = (strstr(val,"ETH" ) != NULL) || (strstr(val,"MAC") != NULL);
02413     debug.LLC  = (strstr(val,"LLC" ) != NULL);
02414     debug.ARP  = (strstr(val,"ARP" ) != NULL);
02415     debug.RARP = (strstr(val,"RARP") != NULL);
02416     debug.IP   = (strstr(val,"IP"  ) != NULL);
02417     debug.TCP  = (strstr(val,"TCP" ) != NULL);
02418     debug.UDP  = (strstr(val,"UDP" ) != NULL);
02419     debug.ICMP = (strstr(val,"ICMP") != NULL);
02420     debug.IGMP = (strstr(val,"IGMP") != NULL);
02421   }
02422 }
02423
02424 static void ourinit (const char *name, const char *value)
02425 {
02426   static const struct config_table debug_cfg[] = {
02427              { "FILE",   ARG_FUNC, (void*)set_debug_file   },
02428              { "MODE",   ARG_FUNC, (void*)set_debug_mode   },
02429              { "LINEBUF",ARG_ATOI, (void*)&dbg_linebuf     },
02430              { "FILTER", ARG_FUNC, (void*)set_debug_filter },
02431              { "PROTO",  ARG_FUNC, (void*)set_debug_proto  },
02432              { "STAT",   ARG_ATOI, (void*)&dbg_print_stat  },
02433              { "DNS",    ARG_ATOI, (void*)&dbg_dns_details },
02434              { "PCAP",   ARG_ATOI, (void*)&pcap_mode       },
02435              { NULL,     0,        NULL                    }
02436            };
02437   if (!parse_config_table(&debug_cfg[0], "DEBUG.", name, value) && prev_hook)
02438      (*prev_hook) (name, value);
02439 }
02440
02441 int MS_CDECL dbug_printf (const char *format, ...)
02442 {
02443   int len = 0;
02444
02445   /* don't let anyone else write if pcap-mode
02446    */
02447   if (dbg_file.stream && !pcap_mode)
02448   {
02449     va_list arg;
02450     va_start (arg, format);
02451     len = vfprintf (dbg_file.stream, format, arg);
02452     va_end (arg);
02453     if (in_dbug_dump && ferror(dbg_file.stream))
02454        longjmp (dbg_jmp, 1);
02455   }
02456   return (len);
02457 }
02458
02459 int dbug_write (const char *buf)
02460 {
02461   int rc = -1;
02462
02463   if (dbg_file.stream && !pcap_mode)
02464   {
02465     rc = fputs (buf, dbg_file.stream);
02466     if (in_dbug_dump && (rc < 0 || ferror(dbg_file.stream)))
02467        longjmp (dbg_jmp, 1);
02468   }
02469   return (rc);
02470 }
02471
02472 int db_write_raw (const char *buf) /* old name */
02473 {
02474   return dbug_write (buf);
02475 }
02476
02477 static void dbug_close (void)
02478 {
02479   if (dbg_file.stream &&
02480       dbg_file.stream != stdout && dbg_file.stream != stderr)
02481   {
02482 #if defined(USE_GZIP_COMPR)
02483     if (use_gzip)
02484        gzclose (dbg_file.gz_stream);
02485     else
02486 #endif
02487        fclose (dbg_file.stream);
02488   }
02489   dbg_file.stream = NULL;
02490 }
02491
02492 static void dbug_flush (void)
02493 {
02494   if (dbg_file.stream && !pcap_mode)
02495   {
02496     fflush (dbg_file.stream);
02497 #if 0
02498     if (dbg_file.stream != stdout &&  /* no point */
02499         dbg_file.stream != stderr)
02500        _dos_commit (fileno(dbg_file.stream));
02501 #endif
02502   }
02503 }
02504
02505 /*
02506  * Public initialisation
02507  */
02508 void dbug_init (void)
02509 {
02510   static BOOL init = FALSE;
02511
02512   if (init)
02513   {
02514     outsnl ("dbug_init() already called");
02515     return;
02516   }
02517   init = TRUE;
02518   prev_hook = usr_init;
02519   usr_init  = ourinit;
02520   _dbugxmit = dbug_send;
02521   _dbugrecv = dbug_recv;
02522
02523 #if defined(USE_BSD_API)
02524   _sock_dbug_init();
02525 #endif
02526
02527   if (_watt_is_init && !dbg_file.stream)
02528        fprintf (stderr, "`dbug_init()' called after `sock_init()'.\n\7");
02529   else memset (&filter, 0, sizeof(filter));
02530 }
02531
02532 #if defined(USE_STATISTICS)
02533 static void dbug_dump_arp_cache (int pfx_chr)
02534 {
02535   struct arp_entry ae[100];
02536   int    i, num;
02537   DWORD  now;
02538
02539   num = _arp_list_cache (ae, DIM(ae));
02540   now = set_timeout (0);
02541   (*_printf) (" %c\nARP-cache:\n", pfx_chr);
02542
02543   for (i = 0; i < num; i++)
02544   {
02545     const char *remain = "no expiry";
02546     char  buf[30];
02547
02548     if (ae[i].expiry)
02549     {
02550       if (ae[i].expiry > now)
02551       {
02552         sprintf (buf, "expires in %s s", time_str(ae[i].expiry-now));
02553         remain = buf;
02554       }
02555       else
02556         remain = "timedout";
02557     }
02558     (*_printf) ("      IP: %-15s -> %s, %s, %s\n",
02559                 _inet_ntoa(NULL,ae[i].ip), MAC_address(&ae[i].hardware),
02560                 (ae[i].flags & ARP_FIXED)   ? "Fixed  " :
02561                 (ae[i].flags & ARP_DYNAMIC) ? "Dynamic" :
02562                 (ae[i].flags & ARP_PENDING) ? "Pending" : "??     ",
02563                 remain);
02564   }
02565   if (num == 0)
02566      (*_printf) ("      <Empty>\n");
02567   (*_printf) (" \n");
02568 }
02569 #endif /* USE_STATISTICS */
02570
02571
02579 static void dbug_exit (void)
02580 {
02581   int (MS_CDECL *save_printf) (const char*, ...) = _printf;
02582   int ch = ' ';
02583
02584   if (!_watt_fatal_error)  /* an assert isn't fatal */
02585   {
02586     if (dbg_file.stream && !pcap_mode)
02587          _printf = dbug_printf;              /* dump to wattcp.dbg */
02588 #if defined(USE_BSD_API)
02589     else if (_sock_dbug_active())
02590          _printf = _sock_debugf, ch = '\n';  /* dump to wattcp.sk */
02591 #endif
02592     else _printf = NULL;
02593
02594     if (_printf)
02595     {
02596 #if defined(USE_STATISTICS)
02597       if (dbg_print_stat)
02598       {
02599         dbug_dump_arp_cache (ch);
02600         print_all_stats();
02601       }
02602 #endif
02603
02604       if (_watt_cbroke)
02605          dbug_printf ("\nTerminating on SIGINT\n");
02606       if (_watt_assert_buf[0])
02607          dbug_printf ("\n%s\n", _watt_assert_buf);
02608       _watt_assert_buf[0] = '\0';
02609     }
02610   }
02611   dbug_close();
02612
02613 #if defined(USE_GZIP_COMPR)
02614   if (use_gzip && !_watt_fatal_error)
02615   {
02616     struct stat st;
02617
02618     if (stat(dbg_name,&st) == 0 && st.st_size > 0)
02619        (*_printf) (" \ngzip compression: %lu raw, %lu compressed (%lu%%)\n",
02620                    bytes_raw, (DWORD)st.st_size,
02621                    100 - (100*st.st_size)/bytes_raw);
02622   }
02623 #endif
02624
02625   ARGSUSED (ch);
02626   _printf = save_printf;
02627 }
02628
02629
02640 struct DNS_Hdr {
02641        WORD  dns_id;
02642 #if defined(USE_BIGENDIAN)
02643        WORD  dns_fl_qr    : 1;
02644        WORD  dns_fl_opcode: 4;
02645        WORD  dns_fl_aa    : 1;
02646        WORD  dns_fl_tc    : 1;
02647        WORD  dns_fl_rd    : 1;
02648
02649        WORD  dns_fl_ra    : 1;
02650        WORD  dns_fl_unused: 1;
02651        WORD  dns_fl_ad    : 1;
02652        WORD  dns_fl_cd    : 1;
02653        WORD  dns_fl_rcode : 4;
02654 #else
02655        WORD  dns_fl_rd    : 1;  /* recursion desired */
02656        WORD  dns_fl_tc    : 1;  /* truncated message */
02657        WORD  dns_fl_aa    : 1;  /* authoritative answer */
02658        WORD  dns_fl_opcode: 4;  /* purpose of message */
02659        WORD  dns_fl_qr    : 1;  /* response flag */
02660        WORD  dns_fl_rcode : 4;  /* response code */
02661        WORD  dns_fl_cd    : 1;  /* checking disabled by resolver */
02662        WORD  dns_fl_ad    : 1;  /* authentic data from named */
02663        WORD  dns_fl_unused: 1;  /* unused bits (MBZ as of 4.9.3a3) */
02664        WORD  dns_fl_ra    : 1;  /* recursion available */
02665 #endif
02666        WORD  dns_num_q;
02667        WORD  dns_num_ans;
02668        WORD  dns_num_auth;
02669        WORD  dns_num_add;
02670      };
02671
02672 static const char *dns_opcodes[16] = {
02673             "standard",       /* DNS_OP_QUERY */
02674             "inverse",        /* DNS_OP_INVERSE */
02675             "server status",
02676             "op 3??",
02677             "op 4??",
02678             "update",
02679             "op 6??",
02680             "op 7??",
02681             "op 8??",
02682             "op 9??",
02683             "op 10??",
02684             "op 11??",
02685             "op 12??",
02686             "op 13??",
02687             "op 14??",
02688             "op 15??"
02689           };
02690
02691 static const char *dns_responses[16] = {
02692             "no error",         /* DNS_SRV_OK */
02693             "format error",     /* DNS_SRV_FORM */
02694             "server error",     /* DNS_SRV_FAIL */
02695             "NXDOMAIN",         /* DNS_SRV_NAME */
02696             "not implemented",  /* DNS_SRV_NOTIMP */
02697             "service refused",  /* DNS_SRV_REFUSE */
02698             "resp 6??",
02699             "resp 7??",
02700             "resp 8??",
02701             "resp 9??",
02702             "resp 10??",
02703             "resp 11??",
02704             "resp 12??",
02705             "resp 13??",
02706             "resp 14??",
02707             "resp 15??"
02708           };
02709
02710 /*
02711  * dns_query()
02712  *
02713  * Return a string describing the numeric value of a DNS query type
02714  */
02715 static __inline const char *dns_query (WORD type)
02716 {
02717   switch (type)
02718   {
02719     case T_A:
02720          return ("A");
02721     case T_AAAA:
02722          return ("AAAA");
02723     case T_NS:
02724          return ("NS");
02725     case T_CNAME:
02726          return ("CNAME");
02727     case T_PTR:
02728          return ("PTR");
02729     case T_HINFO:
02730          return ("HINFO");
02731     case T_MX:
02732          return ("MX");
02733     case T_MB:
02734          return ("MB");
02735     case T_SOA:
02736          return ("SOA");
02737     case T_SRV:
02738          return ("SRV");
02739     case T_AXFR:
02740          return ("AXFR");
02741     case T_TXT:
02742          return ("TXT");
02743     case T_WINS:
02744          return ("WINS");
02745     case T_WINSR:
02746          return ("WINS-R");
02747     case T_ANY:
02748          return ("ANY");
02749     default:
02750          return ("??");
02751   }
02752 }
02753
02754 /*
02755  * Parse DNS packet and dump fields
02756  */
02757 static unsigned dns_dump (const BYTE *bp, unsigned length, unsigned dns_len)
02758 {
02759   #define CHK_BOGUS(p) if (p > bp+length) goto bogus
02760
02761   const struct DNS_Hdr *dns = (const struct DNS_Hdr*) bp;
02762   const BYTE  *body   = (const BYTE*)bp + sizeof(*dns);
02763   const BYTE  *end_p  = (const BYTE*)bp + length;
02764   const char  *opcode = dns->dns_fl_opcode < DIM(dns_opcodes) ?
02765                           dns_opcodes [dns->dns_fl_opcode] : NULL;
02766   const char  *rcode  = dns->dns_fl_rcode < DIM(dns_responses) ?
02767                           dns_responses [dns->dns_fl_rcode] : NULL;
02768   int      i, t;
02769   unsigned len = 0;
02770
02771   if (!dbg_mode_all)
02772      return (1);
02773
02774   dbug_write ("DNS:   ");
02775   if (dns_len)
02776      dbug_printf ("length %u, ", dns_len);
02777
02778   len += dbug_printf ("Ident %u, %s, Opcode: %s, %sAuth\n",
02779                       intel16(dns->dns_id), dns->dns_fl_qr ?
02780                       "Response" : "Query", opcode ? opcode : "??",
02781                       !dns->dns_fl_ad ? "Non-" : "");
02782
02783   if (!dns->dns_fl_qr && rcode)  /* Response code only in responses */
02784      rcode = "";
02785
02786   len += dbug_printf ("       auth answer %d, truncated %d, rec-req %d, "
02787                       "rec-avail %d, %s\n",
02788                       dns->dns_fl_aa, dns->dns_fl_tc, dns->dns_fl_rd,
02789                       dns->dns_fl_ra, rcode ? rcode : "??");
02790   if (!opcode || !rcode)
02791      goto bogus;
02792
02793   if (length <= sizeof(*dns))  /* no body present */
02794      return (length);
02795
02796   /* Do the question part of the packet.
02797    */
02798   i = intel16 (dns->dns_num_q);
02799
02800   while (i > 0)
02801   {
02802     WORD qtype, qclass;
02803
02804     dbug_write ("       Question: query name ");
02805     body = dns_labels (body, bp, end_p);
02806     CHK_BOGUS (body);
02807
02808     qtype  = intel16 (*(WORD*)body);  body += sizeof(qtype);
02809     qclass = intel16 (*(WORD*)body);  body += sizeof(qclass);
02810
02811     dbug_printf ("       query type %d (%s), class %d\n",
02812                  qtype, dns_query(qtype), qclass);
02813     i--;
02814   }
02815
02816   /* Dump the resource records for the answers
02817    */
02818   i = intel16 (dns->dns_num_ans);
02819   t = i;
02820   while (i > 0)
02821   {
02822     dbug_printf ("       Answer %d: ", t-i+1);
02823     body = dns_resource (body, bp, end_p);
02824     CHK_BOGUS (body);
02825     i--;
02826   }
02827
02828   /* Dump the resource records for the authoritative answers
02829    */
02830   i = intel16 (dns->dns_num_auth);
02831   t = i;
02832   while (i > 0)
02833   {
02834     dbug_printf ("       Auth %d: ", t-i+1);
02835     body = dns_resource (body, bp, end_p);
02836     CHK_BOGUS (body);
02837     i--;
02838   }
02839
02840   /* Dump the resource records for the additional info
02841    */
02842   i = intel16 (dns->dns_num_add);
02843   t = i;
02844   while (i > 0)
02845   {
02846     dbug_printf ("       Additional %d: ", t-i+1);
02847     body = dns_resource (body, bp, end_p);
02848     CHK_BOGUS (body);
02849     i--;
02850   }
02851   return (len);
02852
02853 bogus:
02854   dbug_printf ("       Looks like a bogus packet; length %d\n", length);
02855   return (len);
02856 }
02857
02858 /*
02859  * Print the contents of a resource record
02860  */
02861 static const BYTE *dns_resource (const BYTE *p, const BYTE *bp, const BYTE *ep)
02862 {
02863   DWORD ttl, val;
02864   WORD  qtype, qclass, reslen;
02865   const char *ip;
02866
02867   dbug_write ("server name: ");
02868   p = dns_labels (p, bp, ep);
02869
02870   /* Do query type, class, ttl and resource length
02871    */
02872   qtype  = intel16 (*(WORD*)p);  p += sizeof(qtype);
02873   qclass = intel16 (*(WORD*)p);  p += sizeof(qclass);
02874   ttl    = intel  (*(DWORD*)p);  p += sizeof(ttl);
02875   reslen = intel16 (*(WORD*)p);  p += sizeof(reslen);
02876
02877   dbug_printf ("         type %d (%s), class %d, TTL %s, length %u\n",
02878                qtype, dns_query(qtype), qclass, hms_str(ttl), reslen);
02879
02880   /* Do resource data.
02881    */
02882   switch (qtype)
02883   {
02884     case T_A:     /* A record; ip4 address(es) */
02885          if (reslen == 4)
02886          {
02887            ip = _inet_ntoa (NULL, intel(*(DWORD*)p));
02888            dbug_printf ("         IP4 address: %s\n", ip);
02889          }
02890          else if (reslen == 7)
02891          {
02892            ip = _inet_ntoa (NULL, intel(*(DWORD*)p));
02893            dbug_printf ("         IP4 address: %s, proto %u, port %u\n",
02894                         ip, *(p+4), intel16(*(WORD*)(p+5)));
02895          }
02896          else
02897            dbug_printf ("         IP4 address: bogus reslen %u\n", reslen);
02898
02899          p += reslen;
02900          break;
02901
02902 #if defined(USE_IPV6)
02903     case T_AAAA:     /* AAAA record; ip6 address(es) */
02904          while (reslen >= sizeof(ip6_address))
02905          {
02906            const char *addr = _inet6_ntoa ((const ip6_address*)p);
02907            dbug_printf ("         IP6 address: %s\n", addr);
02908            p      += sizeof (ip6_address);
02909            reslen -= sizeof (ip6_address);
02910          }
02911          break;
02912 #endif
02913     case T_NS:    /* NS record; Name Server */
02914          dbug_write ("         auth host: ");
02915          p = dns_labels (p, bp, ep);
02916          break;
02917
02918     case T_MX:    /* MX record; Mail Exchange */
02919          dbug_printf ("         mail exchange host (%u): ", intel16(*(WORD*)p));
02920          p += 2;
02921          p = dns_labels (p, bp, ep);
02922          break;
02923
02924     case T_CNAME: /* CNAME record; canonical name */
02925          dbug_write ("         canon host: ");
02926          p = dns_labels (p, bp, ep);
02927          break;
02928
02929     case T_PTR:   /* PTR record; hostname for IP */
02930          dbug_write ("         host name: ");
02931          p = dns_labels (p, bp, ep);
02932          break;
02933
02934     case T_TXT:   /* TXT record; 1 or more text labels */
02935          dbug_write ("         TXT info: ");
02936          p = dns_labels (p, bp, ep);
02937          break;
02938
02939     case T_WINS:  /* WINS record;  */
02940          dbug_write ("         WINS name: ");
02941          p = dns_labels (p, bp, ep);
02942          break;
02943
02944     case T_WINSR:  /* WINS-reverse record;  */
02945          dbug_write ("         WINS-R addr: ");
02946          p = dns_labels (p, bp, ep);
02947          break;
02948
02949     case T_SOA:
02950          dbug_write ("         SOA: ");
02951          p = dns_labels (p, bp, ep);
02952          if (p < ep)
02953          {
02954            dbug_write ("              ");
02955            p = dns_labels (p, bp, ep);
02956
02957            val = intel (*(DWORD*)p);
02958            p += 4;
02959            dbug_printf ("              serial %lu", val);
02960
02961            val = intel (*(DWORD*)p);
02962            p += 4;
02963            dbug_printf (", refresh %s", hms_str(val));
02964
02965            val = intel (*(DWORD*)p);
02966            p += 4;
02967            dbug_printf (", retry %s\n", hms_str(val));
02968
02969            val = intel (*(DWORD*)p);
02970            p += 4;
02971            dbug_printf ("              expire %s", hms_str(val));
02972
02973            val = intel (*(DWORD*)p);
02974            p += 4;
02975            dbug_printf (", minimum %s\n", hms_str(val));
02976          }
02977          break;
02978
02979     default:
02980          p += reslen;
02981   }
02982   return (p);
02983 }
02984
02985 /*
02986  * Recursively parse a label entry in a DNS packet
02987  * 'p'  points to a DNS label.
02988  * 'bp' points to a beginning of DNS header.
02989  */
02990 static const BYTE *dns_labels (const BYTE *p, const BYTE *bp, const BYTE *ep)
02991 {
02992   while (1)
02993   {
02994     BYTE count = *p++;
02995
02996     if (count >= 0xC0)
02997     {
02998       /* There's a pointer (rel to 'bp' start) in this label.
02999        * Let's grab the 14 low-order bits and run with them.
03000        */
03001       WORD offset = (WORD) (((unsigned)(count - 0xC0) << 8) + *p++);
03002
03003    /* dbug_printf ("(ofs %u) ", offset); !! show where the offset is */
03004       dns_labels (bp+offset, bp, ep);
03005       return (p);
03006     }
03007     if (count == 0)
03008        break;
03009
03010     while (count > 0)
03011     {
03012       if (p <= ep)
03013       {
03014         fputc (*p++, dbg_file.stream);
03015         count--;
03016       }
03017       else
03018       {
03019         dbug_write ("\nPacket length exceeded\n");
03020         return (p);
03021       }
03022     }
03023     fputc ('.', dbg_file.stream);
03024   }
03025   fputc ('\n', dbg_file.stream);
03026   return (p);
03027 }
03028
03029
03030 #if defined(USE_PPPOE)
03031
03032 /* NCP Codes */
03033 enum ncp_codes {
03034      CONFREQ = 1,
03035      CONFACK = 2,
03036      CONFNAK = 3,
03037      CONFREJ = 4,
03038      TERMREQ = 5,
03039      TERMACK = 6,
03040      CODEREJ = 7,
03041      PROTREJ = 8,
03042      ECHOREQ = 9,
03043      ECHOREP = 10,
03044      DISCARD = 11
03045    };
03046
03047 enum lcp_options {
03048      LCP_RESERVED  = 0,
03049      LCP_MRU       = 1,
03050      LCP_ASYNCMAP  = 2,
03051      LCP_AUTHPROTO = 3,
03052      LCP_QUALPROTO = 4,
03053      LCP_MAGICNUM  = 5,
03054      LCP_PCOMP     = 7,
03055      LCP_ACFCOMP   = 8,
03056      LCP_CALLBACK  = 13
03057    };
03058
03059 enum ipcp_options {
03060      IPCP_RESERVED  = 0,
03061      IPCP_ADDRS     = 1,
03062      IPCP_COMPRTYPE = 2,
03063      IPCP_ADDR      = 3,
03064      IPCP_MS_DNS1   = 129,
03065      IPCP_MS_WINS1  = 130,
03066      IPCP_MS_DNS2   = 131,
03067      IPCP_MS_WINS2  = 132,
03068    };
03069
03070 static const struct token ncp_code2str[] = {   /* LCP/IPCP codes */
03071                     { CONFREQ, "ConfReq" },
03072                     { CONFACK, "ConfAck" },
03073                     { CONFNAK, "ConfNak" },
03074                     { CONFREJ, "ConfRej" },
03075                     { TERMREQ, "TermReq" },
03076                     { TERMACK, "TermAck" },
03077                     { CODEREJ, "CodeRej" },
03078                     { PROTREJ, "ProtRej" },
03079                     { ECHOREQ, "EchoReq" },
03080                     { ECHOREP, "EchoRep" },
03081                     { DISCARD, "Discard" },
03082                     { 0,       NULL      }
03083                   };
03084
03085 static const struct token lcp_option2str[] = {
03086                     { LCP_RESERVED, "reserved" },
03087                     { LCP_MRU,      "MRU"      },
03088                     { LCP_ASYNCMAP, "AsyncMap" },
03089                     { LCP_AUTHPROTO,"AUTH"     },
03090                     { LCP_QUALPROTO,"QUAL"     },
03091                     { LCP_MAGICNUM, "MAGIC"    },
03092                     { LCP_PCOMP,    "PCOMP"    },
03093                     { LCP_ACFCOMP,  "ACFcomp"  },
03094                     { LCP_CALLBACK, "CallBack" },
03095                     { 0,            NULL       }
03096                   };
03097
03098 static const struct token ipcp_option2str[] = {
03099                     { IPCP_RESERVED, "reserved" },
03100                     { IPCP_ADDRS,    "Addrs"    },
03101                     { IPCP_COMPRTYPE,"Compr"    },
03102                     { IPCP_ADDR,     "Addr"     },
03103                     { IPCP_MS_DNS1,  "DNS1"     },
03104                     { IPCP_MS_WINS1, "Wins1"    },
03105                     { IPCP_MS_DNS2,  "DNS2"     },
03106                     { IPCP_MS_WINS2, "Win2"     },
03107                     { 0,             NULL       }
03108                   };
03109
03110 static const struct token lcpauth2str[] = {
03111                     { 0xc023, "PAP"  },
03112                     { 0xc223, "CHAP" },
03113                     { 0,       NULL  }
03114                   };
03115
03116 static const struct token lcpqual2str[] = {
03117                     { 0xc025, "LQR" },
03118                     { 0,      NULL  }
03119                   };
03120
03121 static const struct token lcpchap2str[] = {
03122                     { 0x05, "MD5" },
03123                     { 0x80, "MS"  },
03124                     { 0,    NULL  }
03125                   };
03126
03127 /*
03128  * Dump PPP-LCP contents. Functions taken from tcpdump.
03129  */
03130 static unsigned lcp_dump (const BYTE *bp)
03131 {
03132   WORD  lcp_code, lcp_id, lcp_length, arg;
03133   const BYTE *lcp_data, *p;
03134   unsigned len = 0;
03135
03136   lcp_code   = bp[0];
03137   lcp_id     = bp[1];
03138   lcp_length = intel16 (*(WORD*)(bp+2));
03139   lcp_data   = bp + 4;
03140
03141   len += dbug_printf ("LCP:   %s id=0x%02x ",
03142                       tok2str(ncp_code2str,"LCP-#%d",lcp_code), lcp_id);
03143
03144   switch (lcp_code)
03145   {
03146     case CONFREQ:
03147     case CONFACK:
03148     case CONFNAK:
03149     case CONFREJ:
03150          p = lcp_data;
03151
03152          while (p + 2 < lcp_data + lcp_length)
03153          {
03154            BYTE opt_type   = p[0];
03155            BYTE opt_length = p[1];
03156
03157            p += 2;
03158            dbug_printf ("<%s ", tok2str(lcp_option2str,"option-#%d",opt_type));
03159            if (opt_length)
03160            {
03161              switch (opt_type)
03162              {
03163                case LCP_MRU:
03164                     arg = intel16 (*(WORD*)p);
03165                     dbug_printf ("%u", arg);
03166                     break;
03167
03168                case LCP_AUTHPROTO:
03169                     arg = intel16 (*(WORD*)p);
03170                     dbug_printf (tok2str (lcpauth2str, "AUTH-%x", arg));
03171                     if (opt_length >= 5)
03172                        dbug_printf (" %s", tok2str(lcpchap2str, "%x", p[0]));
03173                     break;
03174
03175                case LCP_QUALPROTO:
03176                     arg = intel16 (*(WORD*)p);
03177                     dbug_printf (tok2str(lcpqual2str, "QUAL-%x", arg));
03178                     break;
03179
03180                case LCP_ASYNCMAP:
03181                case LCP_MAGICNUM:
03182                     arg = intel16 (*(WORD*)(p+4));
03183                     dbug_printf ("0x%08lX%04X", intel(*(DWORD*)p), arg);
03184                     break;
03185
03186                case LCP_PCOMP:
03187                case LCP_ACFCOMP:
03188                case LCP_RESERVED:
03189                     break;
03190
03191                default:
03192                     break;
03193              }
03194            }
03195            fputc ('>', dbg_file.stream);
03196            p += opt_length - 2;
03197          }
03198          break;
03199
03200     case ECHOREQ:
03201     case ECHOREP:
03202     case DISCARD:
03203          dbug_printf ("magic=0x%08lX", intel(*(DWORD*)lcp_data));
03204          lcp_data += 4;
03205          break;
03206
03207     case PROTREJ:
03208          arg = intel16 (*(WORD*)lcp_data);
03209          dbug_printf ("prot=%s", tok2str(ppp_type2str, "PROT-%#x",arg));
03210          break;
03211
03212     case CODEREJ:
03213          fputc ('\n', dbg_file.stream);
03214          lcp_dump (lcp_data);
03215          break;
03216
03217     case TERMREQ:
03218     case TERMACK:
03219          break;
03220
03221     default:
03222          break;
03223   }
03224   fputc ('\n', dbg_file.stream);
03225   return (len);
03226 }
03227
03228 /*
03229  * Dump PPP-CCP contents (compression control protocol).
03230  */
03231 static unsigned ccp_dump (const BYTE *bp)
03232 {
03233   ARGSUSED (bp);
03234   return (0);
03235 }
03236
03237 /*
03238  * Dump PPP-IPCP contents.
03239  */
03240 static unsigned ipcp_dump (const BYTE *bp)
03241 {
03242   WORD  ipcp_code, ipcp_id, ipcp_length;
03243   const BYTE *ipcp_data, *p;
03244   unsigned len = 0;
03245
03246   ipcp_code   = bp[0];
03247   ipcp_id     = bp[1];
03248   ipcp_length = intel16 (*(WORD*)(bp+2));
03249   ipcp_data   = bp + 4;
03250
03251   len += dbug_printf ("IPCP:  %s id=0x%02x ",
03252                       tok2str(ncp_code2str,"IPCP-#%d",ipcp_code), ipcp_id);
03253
03254   switch (ipcp_code)
03255   {
03256     case CONFREQ:
03257     case CONFACK:
03258     case CONFNAK:
03259     case CONFREJ:
03260          p = ipcp_data;
03261
03262          while (p + 2 < ipcp_data + ipcp_length)
03263          {
03264            BYTE  opt_type   = p[0];
03265            BYTE  opt_length = p[1];
03266            DWORD addr;
03267
03268            p += 2;
03269            dbug_printf ("<%s ", tok2str(ipcp_option2str,"option-#%d",opt_type));
03270            if (opt_length)
03271            {
03272              switch (opt_type)
03273              {
03274                case IPCP_ADDRS:
03275                     addr = intel (*(DWORD*)p);
03276                     dbug_printf ("addrs %s ", _inet_ntoa(NULL,addr));
03277                     addr = intel (*(DWORD*)(p+4));
03278                     dbug_printf ("%s", _inet_ntoa(NULL,addr));
03279                     break;
03280
03281                case IPCP_ADDR:
03282                     addr = intel (*(DWORD*)p);
03283                     dbug_printf ("addr %s", _inet_ntoa(NULL,addr));
03284                     break;
03285
03286                case IPCP_COMPRTYPE:
03287                     dbug_printf ("compress %u", intel16(*(WORD*)p));
03288                     break;
03289
03290                case IPCP_MS_DNS1:
03291                case IPCP_MS_DNS2:
03292                     addr = intel (*(DWORD*)p);
03293                     dbug_printf ("MS-DNS %s", _inet_ntoa(NULL,addr));
03294                     break;
03295
03296                case IPCP_MS_WINS1:
03297                case IPCP_MS_WINS2:
03298                     addr = intel (*(DWORD*)p);
03299                     dbug_printf ("MS-WINS %s", _inet_ntoa(NULL,addr));
03300                     break;
03301
03302                default:
03303                     break;
03304              }
03305            }
03306            fputc ('>', dbg_file.stream);
03307            p += opt_length - 2;
03308          }
03309          break;
03310
03311     case TERMREQ:
03312     case TERMACK:
03313          break;
03314
03315     default:
03316          break;
03317   }
03318   fputc ('\n', dbg_file.stream);
03319   return (len);
03320 }
03321 #endif  /* USE_PPPOE */
03322
03323 /*
03324  * Functions for writing dump-file in pcap-format
03325  *  (gzip compressed or normal pcap format).
03326  */
03327 #define TCPDUMP_MAGIC       0xA1B2C3D4
03328 #define PCAP_VERSION_MAJOR  2
03329 #define PCAP_VERSION_MINOR  4
03330
03331 #include <sys/packon.h>
03332
03333 struct pcap_file_header {
03334        DWORD  magic;
03335        WORD   version_major;
03336        WORD   version_minor;
03337        long   thiszone;        /* GMT to local correction */
03338        DWORD  sigfigs;         /* accuracy of timestamps */
03339        DWORD  snap_len;        /* max length saved portion of each pkt */
03340        DWORD  linktype;        /* data link type (DLT_*) */
03341      };
03342
03343 /*
03344  * Each packet in the dump file is prepended with this generic header.
03345  * This gets around the problem of different headers for different
03346  * packet interfaces.
03347  */
03348 struct pcap_pkt_header {
03349        struct timeval ts;      /* time stamp */
03350        DWORD          caplen;  /* length of portion present */
03351        DWORD          len;     /* length of this packet (off wire) */
03352        DWORD          family;  /* protocol family value (for DLT_NULL) */
03353      };
03354
03355 #include <sys/packoff.h>
03356
03357 static int write_pcap_header (void)
03358 {
03359   struct pcap_file_header pf_hdr;
03360   struct timeval  tv;
03361   struct timezone tz;
03362   size_t rc;
03363
03364   gettimeofday2 (&tv, &tz);
03365   memset (&pf_hdr, 0, sizeof(pf_hdr));
03366
03367   pf_hdr.magic         = TCPDUMP_MAGIC;
03368   pf_hdr.version_major = PCAP_VERSION_MAJOR;
03369   pf_hdr.version_minor = PCAP_VERSION_MINOR;
03370   pf_hdr.thiszone      = 60 * tz.tz_minuteswest;
03371   pf_hdr.sigfigs       = 0;
03372   pf_hdr.snap_len      = _mtu + _pkt_ip_ofs;
03373   pf_hdr.linktype      = _pktserial ? 101 : _eth_get_hwtype (NULL, NULL);
03374
03375 #if defined(USE_GZIP_COMPR)
03376   if (use_gzip)
03377   {
03378     rc = gzwrite (dbg_file.gz_stream, &pf_hdr, sizeof(pf_hdr));
03379     bytes_raw += sizeof(pf_hdr);
03380   }
03381   else
03382 #endif
03383      rc = fwrite (&pf_hdr, 1, sizeof(pf_hdr), dbg_file.stream);
03384   return (rc == 0 ? -1 : (int)rc);
03385 }
03386
03387 static int write_pcap_packet (const void *pkt, BOOL out)
03388 {
03389   const struct in_Header *ip = (const struct in_Header*) pkt;
03390   struct pcap_pkt_header  pc_hdr;
03391   size_t hlen, pkt_len, rc;
03392
03393   memset (&pc_hdr, 0, sizeof(pc_hdr));
03394
03395   if (out)
03396   {
03397 #if (DOSX) && defined(HAVE_UINT64) && !defined(WIN32)
03398     if (!_eth_last.tx.tstamp.lo ||
03399         !get_tv_from_tsc (&_eth_last.tx.tstamp, &pc_hdr.ts))
03400 #endif
03401        gettimeofday2 (&pc_hdr.ts, NULL);
03402     pkt_len = _eth_last.tx.size;
03403   }
03404   else
03405   {
03406 #if (DOSX) && defined(HAVE_UINT64) && !defined(WIN32)
03407     if (!_eth_last.rx.tstamp.lo ||
03408         !get_tv_from_tsc (&_eth_last.rx.tstamp, &pc_hdr.ts))
03409 #endif
03410        gettimeofday2 (&pc_hdr.ts, NULL);
03411     pkt_len = _eth_last.rx.size;
03412   }
03413
03414   if (_pktserial)  /* write DLT_NULL header */
03415   {
03416     pc_hdr.len    = pkt_len + sizeof(pc_hdr.family);
03417     pc_hdr.family = (ip->ver == 4) ? AF_INET : AF_INET6;
03418     hlen = sizeof (pc_hdr);
03419   }
03420   else
03421   {
03422     pc_hdr.len = pkt_len;
03423     hlen = sizeof (pc_hdr) - sizeof(pc_hdr.family);
03424   }
03425   pc_hdr.caplen = pkt_len;
03426
03427 #if defined(USE_GZIP_COMPR)
03428   if (use_gzip)
03429   {
03430     rc = gzwrite (dbg_file.gz_stream, &pc_hdr, hlen);
03431     bytes_raw += hlen;
03432     rc = gzwrite (dbg_file.gz_stream, pkt, pkt_len);
03433     bytes_raw += pkt_len;
03434   }
03435   else
03436 #endif
03437   {
03438     fwrite (&pc_hdr, hlen, 1, dbg_file.stream);
03439     rc = fwrite (pkt, 1, pkt_len, dbg_file.stream);
03440   }
03441   return (rc == 0 ? -1 : (int)rc);
03442 }
03443 #endif  /* USE_DEBUG */
Generated on Wed Jan 25 15:42:37 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/PCDBUG.H Source File

SRC/PCDBUG.H

Go to the documentation of this file.
00001
00003 #ifndef _w32_PCDBUG_H
00004 #define _w32_PCDBUG_H
00005
00006 typedef void (*DebugProc) (const void *sock, const in_Header *ip,
00007                            const char *file, unsigned line);
00008
00009 W32_DATA DebugProc _dbugxmit, _dbugrecv;
00010
00011 extern const char *tcpStateName (UINT state);
00012
00013 extern BOOL dbg_mode_all, dbg_print_stat, dbg_dns_details;
00014
00015 W32_FUNC void  dbug_init (void);
00016 extern   void  dbug_open (void);
00017 extern   FILE *dbug_file (void);
00018 extern   int   dbug_write (const char *);
00019
00020 extern int MS_CDECL dbug_printf (const char *fmt, ...) ATTR_PRINTF (1, 2);
00021
00022 #if defined(USE_PPPOE)
00023   extern const char *pppoe_get_code (WORD code);
00024 #endif
00025
00026 /*
00027  * Send Rx/Tx packet to debug-file.
00028  * 'nw_pkt' must point to network layer packet.
00029  */
00030 #if defined(USE_DEBUG)
00031   #define DEBUG_RX(sock, nw_pkt)                            \
00032           do {                                              \
00033             if (_dbugrecv)                                  \
00034               (*_dbugrecv) (sock, (const in_Header*)nw_pkt, \
00035                             __FILE__, __LINE__);            \
00036           } while (0)
00037
00038   #define DEBUG_TX(sock, nw_pkt)                            \
00039           do {                                              \
00040             if (_dbugxmit)                                  \
00041               (*_dbugxmit) (sock, (const in_Header*)nw_pkt, \
00042                            __FILE__, __LINE__);             \
00043           } while (0)
00044
00045   /* Generic trace to wattcp.dbg file
00046    */
00047   #define TCP_TRACE_MSG(args)    \
00048           do {                   \
00049             if (dbug_file())     \
00050                dbug_printf args; \
00051           } while (0)
00052
00053   /* Trace to console
00054    */
00055   #define TCP_CONSOLE_MSG(lvl, args) \
00056           do {                       \
00057             if (debug_on >= lvl) {   \
00058               (*_printf) args;       \
00059               fflush (stdout);       \
00060             }                        \
00061           } while (0)
00062 #else
00063   #define DEBUG_RX(sock, ip)         ((void)0)
00064   #define DEBUG_TX(sock, ip)         ((void)0)
00065   #define TCP_TRACE_MSG(args)        ((void)0)
00066   #define TCP_CONSOLE_MSG(args, lvl) ((void)0)
00067 #endif
00068
00069 #endif
00070
Generated on Wed Jan 25 15:42:37 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/PCDHCP.C Source File

SRC/PCDHCP.C

Go to the documentation of this file.
00001
00008 /*  Copyright (c) 1997-2002 Gisle Vanem <giva@bgnett.no>
00009  *
00010  *  Redistribution and use in source and binary forms, with or without
00011  *  modification, are permitted provided that the following conditions
00012  *  are met:
00013  *  1. Redistributions of source code must retain the above copyright
00014  *     notice, this list of conditions and the following disclaimer.
00015  *  2. Redistributions in binary form must reproduce the above copyright
00016  *     notice, this list of conditions and the following disclaimer in the
00017  *     documentation and/or other materials provided with the distribution.
00018  *  3. All advertising materials mentioning features or use of this software
00019  *     must display the following acknowledgement:
00020  *       This product includes software developed by Gisle Vanem
00021  *       Bergen, Norway.
00022  *
00023  *  THIS SOFTWARE IS PROVIDED BY ME (Gisle Vanem) AND CONTRIBUTORS ``AS IS''
00024  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00025  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00026  *  ARE DISCLAIMED.  IN NO EVENT SHALL I OR CONTRIBUTORS BE LIABLE FOR ANY
00027  *  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00028  *  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00029  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00030  *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00031  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00032  *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00033  */
00034
00035 /*  \version 0.5: Oct 28, 1996 :
00036  *    G. Vanem - implemented from RFC1541 with help from pcbootp.c.
00037  *
00038  *  \version 0.6: May 18, 1997 :
00039  *    G. Vanem - added RFC2131 DHCPINFORM message.
00040  *
00041  *  \version 0.7: Apr 25, 2002 :
00042  *     G. Vanem - added RFC3004 User Class option.
00043  *
00044  *  \version 0.8: Jul 24, 2002 :
00045  *    G. Vanem - Rewitten as a non-blocking FSM.
00046  *             - Removed DHCPINFORM message.
00047  *
00048  *  \version 0.9: Nov 08, 2002 :
00049  *    G. Vanem - added handling of option 60 (Vendor Class)
00050  *
00051  *  \version 0.91: Feb 21, 2003 :
00052  *    Greg Bredthauer found some bugs in DHCP_request(); DHCP_USER_CLASS
00053  *    and DHCP_CLASS_ID tags had 2 bytes of zeros in them.
00054  *    Added sending DHCP_CLIENT_ID in DHCP_request() since some DHCP-servers
00055  *    doesn't reply without it.
00056  *
00057  *  \version 0.92: Jul 17, 2003:
00058  *    Riccardo De Agostini contibuted changes for application hooking of
00059  *    transient configuration; dhcp_set_config_func() etc.
00060  *
00061  *  \version 0.93: Jul 2, 2004:
00062  *    Fixed logic around reading transient config.
00063  */
00064
00065 #include <stdio.h>
00066 #include <stdlib.h>
00067 #include <string.h>
00068 #include <time.h>
00069 #include <io.h>
00070 #include <ctype.h>
00071 #include <errno.h>
00072
00073 #define DHCP_IMPLEMENTATION
00074
00075 #include "wattcp.h"
00076 #include "strings.h"
00077 #include "language.h"
00078 #include "misc.h"
00079 #include "timer.h"
00080 #include "udp_dom.h"
00081 #include "netaddr.h"
00082 #include "bsdname.h"
00083 #include "ip4_out.h"
00084 #include "syslog2.h"
00085 #include "sock_ini.h"
00086 #include "printk.h"
00087 #include "tftp.h"
00088 #include "pctcp.h"
00089 #include "pcsed.h"
00090 #include "pcarp.h"
00091 #include "pcqueue.h"
00092 #include "pcdbug.h"
00093 #include "pcpkt.h"
00094 #include "pcconfig.h"
00095 #include "pcbootp.h"
00096 #include "pcdhcp.h"
00097
00098 #if defined(USE_DHCP)
00099
00100 #define BROADCAST_FLAG  intel16 (0x8000) /* network order (LSB=1) */
00101
00102 BOOL dhcp_did_gratuitous_arp = FALSE;
00103
00104 static WattDHCPConfigFunc config_func = NULL;
00105
00106 static DWORD exchange_id;
00107 static DWORD router, nameserver;
00108 static DWORD dhcp_server    = 0;
00109 static DWORD dhcp_renewal   = 0;
00110 static DWORD dhcp_rebind    = 0;
00111 static DWORD dhcp_iplease   = 0;
00112 static DWORD suggest_lease  = 0;
00113 static DWORD old_ip_addr    = 0;
00114
00115 static BOOL  bcast_flag     = TRUE;
00116 static BOOL  got_offer      = FALSE;
00117 static BOOL  configured     = FALSE;
00118 static BOOL  arp_check_ip   = FALSE;
00119 static BOOL  cfg_read       = FALSE;
00120 static BOOL  cfg_saved      = FALSE;
00121
00122 static int   dhcp_timeout   = 10;
00123 static int   max_retries    = 3;
00124 static int   discover_loops = 0;
00125
00126 static struct dhcp dhcp_in, dhcp_out;
00127
00128 static void (*DHCP_state) (int) = NULL;
00129 static time_t renewal_timeout;
00130 static time_t rebind_timeout;
00131 static time_t lease_timeout;
00132 static DWORD  send_timeout;
00133 static BOOL   trace_on = FALSE;
00134
00135 static char       config_file [MAX_VALUELEN+1] = "";
00136 static sock_type *sock = NULL;
00137
00138 /* Default list of DHCP request values
00139  */
00140 static const BYTE default_request_list[] = {
00141              DHCP_OPT_SUBNET_MASK,
00142              DHCP_OPT_ROUTERS_ON_SNET,
00143              DHCP_OPT_DNS_SRV,
00144              DHCP_OPT_COOKIE_SRV,
00145              DHCP_OPT_LPR_SRV,
00146              DHCP_OPT_HOST_NAME,
00147              DHCP_OPT_DOMAIN_NAME,
00148              DHCP_OPT_IP_DEFAULT_TTL,
00149              DHCP_OPT_IF_MTU,
00150              DHCP_OPT_ARP_CACHE_TIMEOUT,
00151              DHCP_OPT_ETHERNET_ENCAPSULATION,
00152              DHCP_OPT_TCP_DEFAULT_TTL,
00153 #if defined(USE_BSD_API)
00154              DHCP_OPT_LOG_SRV,         /* links in syslog2.c */
00155              DHCP_OPT_NBIOS_NAME_SRV,  /* SMB-lib needs these */
00156              DHCP_OPT_NBIOS_NODE_TYPE,
00157              DHCP_OPT_NBIOS_SCOPE,
00158 #endif
00159 #if defined(USE_TFTP)
00160              DHCP_OPT_TFTP_SERVER,
00161              DHCP_OPT_BOOT_FILENAME
00162 #endif
00163            };
00164
00165 static struct DHCP_list request_list = {
00166                         (BYTE*) &default_request_list,
00167                         sizeof (default_request_list)
00168                       };
00169
00170 static struct DHCP_list extra_options = { NULL, 0 };
00171 static struct DHCP_list user_class    = { NULL, 0 };
00172 static struct DHCP_list vend_class    = { (BYTE*)"Watt-32", 7 };
00173
00174 static void  DHCP_state_INIT (int event);
00175 static void  DHCP_state_BOUND (int event);
00176 static void  DHCP_state_RENEWING (int event);
00177 static void  DHCP_state_REQUESTING (int event);
00178 static void  DHCP_state_SELECTING (int event);
00179 static void  DHCP_state_REBINDING (int event);
00180
00181 static void  dhcp_fsm         (void);
00182 static void  dhcp_options_add (const BYTE *opt, unsigned max);
00183 static void  dhcp_set_timers  (void);
00184 static void  change_ip_addr   (void);
00185 static BYTE *put_request_list (BYTE *opt, int filled);
00186 static int   write_config     (void);
00187 static void  erase_config     (void);
00188
00189 #define DHCP_SEND(end) \
00190         sock_fastwrite (sock, (const BYTE*)&dhcp_out, end - (BYTE*)&dhcp_out)
00191
00192 #if defined(USE_DEBUG)
00193   #define TRACE(x)      do { if (trace_on) (*_printf) x; } while (0)
00194   #define INET_NTOA(x)  _inet_ntoa (NULL, x)
00195 #else
00196   #define TRACE(x)      ((void)0)
00197   #define INET_NTOA(x)  ((void)0)
00198 #endif
00199
00200 #if defined(USE_DEBUG)
00201
00204 static const char *state_name (void)
00205 {
00206   return (DHCP_state == DHCP_state_INIT       ? "INIT"       :
00207           DHCP_state == DHCP_state_BOUND      ? "BOUND"      :
00208           DHCP_state == DHCP_state_RENEWING   ? "RENEWING"   :
00209           DHCP_state == DHCP_state_REQUESTING ? "REQUESTING" :
00210           DHCP_state == DHCP_state_SELECTING  ? "SELECTING"  :
00211           DHCP_state == DHCP_state_REBINDING  ? "REBINDING"  : "??");
00212 }
00213
00217 static const char *period (DWORD sec)
00218 {
00219   static char buf[20];
00220   DWORD  hours = sec / 3600UL;
00221
00222   if (sec < 60UL)
00223        sprintf (buf, "%lus", sec);
00224   else if (sec < 3600UL)
00225        sprintf (buf, "%lu:%02lu", sec/60, sec % 60);
00226   else sprintf (buf, "%lu:%02lu:%02lu", hours, sec/60-hours*60, sec % 60);
00227   return (buf);
00228 }
00229 #endif
00230
00234 static BYTE *make_boot_header (void)
00235 {
00236   DWORD my_ip = 0UL;
00237
00238   if (DHCP_state == DHCP_state_BOUND    ||
00239       DHCP_state == DHCP_state_RENEWING ||
00240       DHCP_state == DHCP_state_REBINDING)
00241      my_ip = intel (my_ip_addr);
00242
00243   memset (&dhcp_out, 0, sizeof(dhcp_out));
00244
00245   _eth_get_hwtype (&dhcp_out.dh_htype, &dhcp_out.dh_hlen);
00246
00247   dhcp_out.dh_op     = BOOTP_REQUEST;
00248   dhcp_out.dh_xid    = exchange_id;
00249   dhcp_out.dh_secs   = 0;
00250   dhcp_out.dh_flags  = bcast_flag ? BROADCAST_FLAG : 0;
00251   dhcp_out.dh_yiaddr = 0;
00252   dhcp_out.dh_ciaddr = my_ip;
00253   dhcp_out.dh_giaddr = 0;
00254   memcpy (dhcp_out.dh_chaddr, _eth_addr, _eth_mac_len);
00255   *(DWORD*) &dhcp_out.dh_opt[0] = DHCP_MAGIC_COOKIE;
00256   return (&dhcp_out.dh_opt[4]);
00257 }
00258
00262 static BYTE *put_hardware_opt (BYTE *opt)
00263 {
00264   BYTE hw_type, hw_len;
00265
00266   _eth_get_hwtype (&hw_type, &hw_len);
00267   *opt++ = DHCP_OPT_CLIENT_ID;
00268   *opt++ = hw_len + 1;
00269   *opt++ = hw_type;
00270   memcpy (opt, _eth_addr, hw_len);
00271   opt += hw_len;
00272   return (opt);
00273 }
00274
00278 static int DHCP_discover (void)
00279 {
00280   BYTE *opt, *start;
00281
00282   exchange_id = set_timeout (0);    /* random exchange ID */
00283   opt = start = make_boot_header();
00284   *opt++ = DHCP_OPT_MSG_TYPE;
00285   *opt++ = 1;
00286   *opt++ = DHCP_DISCOVER;
00287
00288   opt = put_hardware_opt (opt);
00289
00290   *opt++ = DHCP_OPT_MAX_MSG_SIZE;   /* Maximum DHCP message size */
00291   *opt++ = 2;
00292   *(WORD*)opt = intel16 (sizeof(struct dhcp));
00293   opt += 2;
00294
00295   if (suggest_lease)
00296   {
00297     *opt++ = DHCP_OPT_IP_ADDR_LEASE_TIME;
00298     *opt++ = sizeof (suggest_lease);
00299     *(DWORD*)opt = intel (suggest_lease);
00300     opt += sizeof (suggest_lease);
00301   }
00302   opt = put_request_list (opt, opt-start);
00303   *opt++ = DHCP_OPT_END;
00304   return DHCP_SEND (opt);
00305 }
00306
00310 static int DHCP_request (BOOL renew)
00311 {
00312   BYTE *opt = make_boot_header();
00313
00314   *opt++ = DHCP_OPT_MSG_TYPE;
00315   *opt++ = 1;
00316   *opt++ = DHCP_REQUEST;
00317
00318   if (!renew)
00319   {
00320     *opt++ = DHCP_OPT_SRV_IDENTIFIER;
00321     *opt++ = sizeof (dhcp_server);
00322     *(DWORD*)opt = intel (dhcp_server);
00323     opt += sizeof (dhcp_server);
00324     *opt++ = DHCP_OPT_REQUESTED_IP_ADDR;
00325     *opt++ = sizeof (my_ip_addr);
00326     *(DWORD*)opt = intel (my_ip_addr);
00327     opt += sizeof (my_ip_addr);
00328   }
00329
00330   /* Some DHCP-daemons require this tag in a REQUEST.
00331    */
00332   opt = put_hardware_opt (opt);
00333
00334   if (dhcp_iplease && dhcp_iplease < (DWORD)-1)
00335   {
00336     *opt++ = DHCP_OPT_IP_ADDR_LEASE_TIME;
00337     *opt++ = sizeof (dhcp_iplease);
00338     *(DWORD*)opt = intel (dhcp_iplease);
00339     opt += sizeof (dhcp_iplease);
00340   }
00341
00342   if (user_class.data)
00343   {
00344     *opt++ = DHCP_OPT_USER_CLASS;
00345     *opt++ = user_class.size;
00346     memcpy (opt, user_class.data, user_class.size);
00347     opt += user_class.size;
00348   }
00349
00350   if (vend_class.data)
00351   {
00352     *opt++ = DHCP_OPT_CLASS_ID;
00353     *opt++ = vend_class.size;
00354     memcpy (opt, vend_class.data, vend_class.size);
00355     opt += vend_class.size;
00356   }
00357
00358   *opt++ = DHCP_OPT_END;
00359   return DHCP_SEND (opt);
00360 }
00361
00367 static int DHCP_release_decline (int msg_type, const char *msg)
00368 {
00369   BYTE *opt;
00370
00371   exchange_id = set_timeout (0);   /* new exchange ID */
00372   opt = make_boot_header();
00373
00374   *opt++ = DHCP_OPT_MSG_TYPE;
00375   *opt++ = 1;
00376   *opt++ = msg_type;
00377   *opt++ = DHCP_OPT_SRV_IDENTIFIER;
00378   *opt++ = sizeof (dhcp_server);
00379   *(DWORD*)opt = intel (dhcp_server);
00380   opt += sizeof (dhcp_server);
00381
00382   if (msg)
00383   {
00384     const BYTE *end = &dhcp_out.dh_opt [sizeof(dhcp_out.dh_opt)-1];
00385     size_t      len = strlen (msg);
00386
00387     len = min (len, 255);
00388     len = min (len, (size_t)(end-opt-3));
00389     *opt++ = DHCP_OPT_MSG;
00390     *opt++ = len;
00391     memcpy (opt, msg, len);
00392     opt += len;
00393   }
00394   *opt++ = DHCP_OPT_END;
00395   return DHCP_SEND (opt);
00396 }
00397
00405 static BOOL DHCP_arp_check (DWORD my_ip)
00406 {
00407   eth_address eth;
00408   DWORD bcast_ip;
00409
00410   if (_pktserial)
00411      return (TRUE);
00412
00413   bcast_ip = my_ip | ~sin_mask;
00414
00415   /* ARP broadcast to announce our new IP
00416    */
00417   _arp_reply (NULL, intel(bcast_ip), intel(my_ip));
00418   dhcp_did_gratuitous_arp = TRUE;
00419
00420   if (!arp_check_ip)
00421      return (TRUE);
00422
00423   /* Check if IP is used by anybody else
00424    */
00425   TRACE (("Checking ARP.."));
00426
00427   if (!_arp_check_own_ip(&eth))
00428   {
00429     TRACE (("station %s claims to have my IP %s! Declining..\n",
00430             MAC_address(&eth), INET_NTOA(my_ip)));
00431     if (!trace_on)
00432        outsnl ("Someone claims to have my IP! Declining..\7");
00433     return (FALSE);
00434   }
00435   TRACE (("\n"));
00436   return (TRUE);
00437 }
00438
00443 static int DHCP_offer (const struct dhcp *in)
00444 {
00445   int   len;
00446   DWORD ip;
00447   const BYTE *opt = (const BYTE*) &in->dh_opt[4];
00448
00449   while (opt < in->dh_opt + sizeof(in->dh_opt))
00450   {
00451     switch (*opt)
00452     {
00453       case DHCP_OPT_PAD:
00454            opt++;
00455            continue;
00456
00457       case DHCP_OPT_SUBNET_MASK:
00458            sin_mask = intel (*(DWORD*)(opt+2));
00459            TRACE (("Net-mask:  %s\n", INET_NTOA(sin_mask)));
00460            break;
00461
00462       case DHCP_OPT_TIME_OFFSET:
00463 #if defined(USE_DEBUG)
00464            {
00465              long ofs = *(long*)(opt+2);
00466              TRACE (("Time-ofs:  %.2fh\n", (double)ofs/3600.0));
00467            }
00468 #endif
00469            break;
00470
00471       case DHCP_OPT_ROUTERS_ON_SNET:
00472            {
00473              static BOOL gw_added = FALSE;
00474
00475              if (!gw_added)
00476                 _arp_kill_gateways(); /* delete gateways from cfg-file */
00477              gw_added = TRUE;
00478              router = intel (*(DWORD*)(opt+2));
00479              _arp_add_gateway (NULL, router);
00480              TRACE (("Gateway:   %s\n", INET_NTOA(router)));
00481            }
00482            break;
00483
00484       case DHCP_OPT_DNS_SRV:
00485            {
00486              static BOOL dns_added = FALSE;
00487
00488              for (len = 0; len < *(opt+1); len += sizeof(DWORD))
00489              {
00490                ip = intel (*(DWORD*)(opt+2+len));
00491                if (!dns_added)
00492                   last_nameserver = 0;  /* delete nameserver from cfg-file */
00493
00494                /*
00495                 * !!fix-me: Add only first name-server cause resolve() doesn't
00496                 * handle multiple servers (in different nets) very well
00497                 */
00498                if (len == 0)
00499                {
00500                  nameserver = ip;
00501                  _add_server (&last_nameserver,
00502                               MAX_NAMESERVERS, def_nameservers, ip);
00503                }
00504                dns_added = TRUE;
00505                TRACE (("DNS:       %s\n", INET_NTOA(ip)));
00506              }
00507            }
00508            break;
00509
00510 #if defined(USE_BSD_API)
00511       case DHCP_OPT_LOG_SRV:
00512            if (!syslog_hostName[0] &&   /* not already set */
00513                opt[1] % 4 == 0)         /* length = n * 4 */
00514            {
00515              ip = intel (*(DWORD*)(opt+2));   /* select 1st host */
00516              StrLcpy (syslog_hostName, _inet_ntoa(NULL,ip), sizeof(syslog_hostName));
00517              TRACE (("Syslog:    %s\n", syslog_hostName));
00518            }
00519            break;
00520
00521       case DHCP_OPT_NBIOS_NAME_SRV:
00522            ip = intel (*(DWORD*)(opt+2));
00523            TRACE (("WINS:      %s\n", INET_NTOA(ip)));
00525            break;
00526
00527       case DHCP_OPT_NBIOS_NODE_TYPE:
00528            TRACE (("NBT node:  %02X\n", opt[2]));
00529            break;
00530
00531       case DHCP_OPT_NBIOS_SCOPE:
00532            TRACE (("NBT scope: %.*s\n", opt[1], opt+2));
00533            break;
00534 #endif
00535       case DHCP_OPT_HOST_NAME:
00536           /* Don't use sethostname() because '*(opt+2)' is not a FQDN.
00537            */
00538            len = min (opt[1], sizeof(hostname));
00539            memcpy (hostname, opt+2, len);
00540            hostname[len] = '\0';
00541            TRACE (("Host name:  `%s'\n", hostname));
00542            break;
00543
00544       case DHCP_OPT_DOMAIN_NAME:
00545            len = min (opt[1], sizeof(defaultdomain)-1);
00546            setdomainname ((const char*)(opt+2), len+1);
00547            TRACE (("Domain:   `%s'\n", def_domain));
00548            break;
00549
00550       case DHCP_OPT_IP_DEFAULT_TTL:
00551       case DHCP_OPT_TCP_DEFAULT_TTL:
00552            _default_ttl = opt[2];
00553            break;
00554
00555       case DHCP_OPT_MSG_TYPE:
00556            if (opt[2] == DHCP_OFFER)
00557               got_offer = TRUE;
00558            break;
00559
00560       case DHCP_OPT_MSG:
00561            outsn ((const char*)(opt+2), *(opt+1));
00562            break;
00563
00564       case DHCP_OPT_SRV_IDENTIFIER:
00565            dhcp_server = intel (*(DWORD*)(opt+2));
00566            TRACE (("Server:    %s\n", INET_NTOA(dhcp_server)));
00567            break;
00568
00569       case DHCP_OPT_IP_ADDR_LEASE_TIME:
00570            dhcp_iplease = intel (*(DWORD*)(opt+2));
00571            TRACE (("IP lease:  %s\n", period(dhcp_iplease)));
00572            break;
00573
00574       case DHCP_OPT_T1_VALUE:
00575            dhcp_renewal = intel (*(DWORD*)(opt+2));
00576            TRACE (("Renewal:   %s\n", period(dhcp_renewal)));
00577            break;
00578
00579       case DHCP_OPT_T2_VALUE:
00580            dhcp_rebind = intel (*(DWORD*)(opt+2));
00581            TRACE (("Rebind:    %s\n", period(dhcp_rebind)));
00582            break;
00583
00584       case DHCP_OPT_TCP_KEEPALIVE_INTERVAL:
00585            tcp_keep_intvl = intel (*(DWORD*)(opt+2));
00586            break;
00587
00588       case DHCP_OPT_OVERLOAD:
00589            switch (opt[2])
00590            {
00591              case 1:
00592                   TRACE (("Overload:  `dh_file' options\n"));
00593                   dhcp_options_add (in->dh_file, sizeof(in->dh_file));
00594                   break;
00595              case 2:
00596                   TRACE (("Overload:  `dh_sname' options\n"));
00597                   dhcp_options_add (in->dh_sname, sizeof(in->dh_sname));
00598                   break;
00599              case 3:
00600                   TRACE (("Overload:  `dh_file/dh_sname' options\n"));
00601                   dhcp_options_add (in->dh_file, sizeof(in->dh_file));
00602                   dhcp_options_add (in->dh_sname, sizeof(in->dh_sname));
00603                   break;
00604            }
00605            break;
00606
00607 #if defined(USE_TFTP)
00608       case DHCP_OPT_TFTP_SERVER:
00609            {
00610              const char *serv;
00611              len  = opt[1];
00612              serv = tftp_set_server ((const char*)(opt+2), len);
00613              TRACE (("TFTP-serv: `%s'\n", serv));
00614            }
00615            break;
00616
00617       case DHCP_OPT_BOOT_FILENAME:
00618            {
00619              const char *file;
00620              len  = opt[1];
00621              file = tftp_set_boot_fname ((const char*)(opt+2), len);
00622              TRACE (("BOOT-file: `%s'\n", file));
00623            }
00624            break;
00625 #endif
00626
00627       case DHCP_OPT_USER_CLASS:  /* these options are ignored in replies */
00628       case DHCP_OPT_CLASS_ID:
00629            break;
00630
00631       case DHCP_OPT_GRUB_MENU:  /* GRUB loader config-file */
00632            TRACE (("GRUB:      %.*s\n", opt[1], opt+2));
00633            break;
00634
00635       case DHCP_OPT_ETHERNET_ENCAPSULATION:
00636            TRACE (("Encap:     %s\n", opt[2] ? "IEEE 802.3" : "Ethernet II"));
00637            if (opt[2] != 0)
00638               outsnl (_LANG("Only Ethernet II encapsulation supported"));
00639            break;
00640
00641       case DHCP_OPT_END:
00642            TRACE (("got end-option\n"));
00643            return (got_offer);
00644
00645       default:
00646            TRACE (("Ignoring option %d\n", *opt));
00647            break;
00648     }
00649     opt += *(opt+1) + 2;
00650   }
00651
00652   if (extra_options.data)
00653   {
00654     struct dhcp ext;
00655
00656     len = min (extra_options.size, sizeof(ext.dh_opt));
00657     extra_options.data [len] = DHCP_OPT_END;
00658     memcpy (ext.dh_opt, extra_options.data, len);
00659     DHCP_offer (&ext);
00660   }
00661   return (got_offer);
00662 }
00663
00667 static int DHCP_is_ack (void)
00668 {
00669   const BYTE *opt = (const BYTE*) &dhcp_in.dh_opt[4];
00670
00671   return (opt[0] == DHCP_OPT_MSG_TYPE && opt[1] == 1 && opt[2] == DHCP_ACK);
00672 }
00673
00677 static int DHCP_is_nack (void)
00678 {
00679   const BYTE *opt = (const BYTE*) &dhcp_in.dh_opt[4];
00680
00681   return (opt[0] == DHCP_OPT_MSG_TYPE && opt[1] == 1 && opt[2] == DHCP_NAK);
00682 }
00683
00690 void DHCP_release (BOOL force)
00691 {
00692   if (force)
00693   {
00694     TRACE (("Sending DHCP release\n"));
00695     DHCP_release_decline (DHCP_RELEASE, NULL);
00696   }
00697   else if (configured)
00698   {
00699     /* Don't release if:
00700      *   DHCP-config is saved on disk and remaining lease is
00701      *   above minimum.
00702      */
00703     if (!(cfg_saved &&
00704           (lease_timeout && (lease_timeout - time(NULL) > DHCP_MIN_LEASE))))
00705     {
00706       TRACE (("Sending DHCP release\n"));
00707       DHCP_release_decline (DHCP_RELEASE, NULL);
00708     }
00709   }
00710   delwattcpd (dhcp_fsm);
00711   if (sock)
00712   {
00713     sock_close (sock);
00714     free (sock);
00715     sock = NULL;
00716   }
00717 }
00718
00722 DWORD DHCP_get_server (void)
00723 {
00724   return (dhcp_server);
00725 }
00726
00730 static sock_type *dhcp_open (const char *msg, BOOL use_broadcast)
00731 {
00732   struct _udp_Socket *sock = malloc (sizeof(*sock));
00733   DWORD   host;
00734
00735   if (!sock)
00736   {
00737     outs (_LANG("DHCP: malloc failed\n"));
00738     return (NULL);
00739   }
00740
00741   if (msg && (trace_on || debug_on))
00742      outs (msg);
00743
00744   if (use_broadcast)
00745        host = IP_BCAST_ADDR; /* 255.255.255.255 */
00746   else host = dhcp_server;   /* default is 0.0.0.0 which maps to 255.255.255.255 */
00747
00748   if (!udp_open (sock, IPPORT_BOOTPC, host, IPPORT_BOOTPS, NULL))
00749   {
00750     if (trace_on || debug_on)
00751     {
00752       outs ("DHCP: ");
00753       outsnl (sock->err_msg);
00754     }
00755     free (sock);
00756     sock = NULL;
00757   }
00758   return (sock_type*)sock;
00759 }
00760
00764 static void arp_add_server (void)
00765 {
00766   if ((_pktdevclass == PDCLASS_ETHER || _pktdevclass == PDCLASS_TOKEN) &&
00767       memcmp(sock->udp.his_ethaddr, _eth_brdcast, sizeof(_eth_brdcast)))
00768   {
00769     const eth_address *eth = (const eth_address*) sock->udp.his_ethaddr;
00770     _arp_add_cache (dhcp_server, eth, TRUE);
00771   }
00772 }
00773
00778 static void DHCP_state_BOUND (int event)
00779 {
00780   if (event == EVENT_T1_TIMEOUT) /* renewal timeout */
00781   {
00782     old_ip_addr = my_ip_addr;    /* remember current address */
00783     got_offer   = FALSE;
00784
00785     TRACE (("Sending DHCP request\n"));
00786     DHCP_request (1);
00787     DHCP_state = DHCP_state_RENEWING;
00788   }
00789 }
00790
00797 static void DHCP_state_REQUESTING (int event)
00798 {
00799   if (event == EVENT_SEND_TIMEOUT)
00800   {
00801     TRACE (("Sending DHCP request\n"));
00802     DHCP_request (0);
00803   }
00804   else if (event == EVENT_ACK)
00805   {
00806     TRACE (("Got DHCP ack\n"));
00807
00808     if (!DHCP_arp_check(my_ip_addr))
00809     {
00810       my_ip_addr = 0;     /* decline from 0.0.0.0 */
00811       DHCP_release_decline (DHCP_DECLINE, "IP is not free");
00812       send_timeout = set_timeout (Random(4000,6000));
00813       DHCP_state   = DHCP_state_INIT;
00814     }
00815     else
00816     {
00817       configured = 1;     /* we are (re)configured */
00818       if (dhcp_server)
00819          arp_add_server();
00820       dhcp_set_timers();
00821       send_timeout = 0UL;
00822       DHCP_state   = DHCP_state_BOUND;
00823     }
00824   }
00825   else if (event == EVENT_NAK)
00826   {
00827     send_timeout = set_timeout (Random(4000,6000));
00828     my_ip_addr = 0UL;
00829     DHCP_state = DHCP_state_INIT;
00830   }
00831 }
00832
00838 static void DHCP_state_REBINDING (int event)
00839 {
00840   if (event == EVENT_ACK)
00841   {
00842     TRACE (("Got DHCP ack\n"));
00843     dhcp_set_timers();
00844     change_ip_addr();
00845     DHCP_state = DHCP_state_BOUND;
00846   }
00847   else if (event == EVENT_NAK)
00848   {
00849     send_timeout = set_timeout (Random(4000,6000));
00850     my_ip_addr = 0UL;
00851     DHCP_state = DHCP_state_INIT;
00852   }
00853 }
00854
00862 static void DHCP_state_RENEWING (int event)
00863 {
00864   if (event == EVENT_SEND_TIMEOUT)
00865   {
00866     TRACE (("Sending DHCP request\n"));
00867     DHCP_request (1);
00868   }
00869   else if (event == EVENT_T2_TIMEOUT)
00870   {
00871     TRACE (("Sending DHCP request\n"));
00872     bcast_flag = TRUE;
00873     DHCP_request (1);
00874     DHCP_state = DHCP_state_REBINDING;
00875   }
00876   else if (event == EVENT_ACK)
00877   {
00878     TRACE (("Got DHCP ack\n"));
00879     dhcp_set_timers();
00880     change_ip_addr();
00881     DHCP_state = DHCP_state_BOUND;
00882   }
00883   else if (event == EVENT_NAK)
00884   {
00885     TRACE (("Got DHCP nack\n"));
00886     send_timeout = set_timeout (Random(4000,6000));
00887     my_ip_addr = 0;
00888     DHCP_state = DHCP_state_INIT;
00889   }
00890 }
00891
00897 static void DHCP_state_SELECTING (int event)
00898 {
00899   if (event == EVENT_OFFER && !got_offer && DHCP_offer(&dhcp_in))
00900   {
00901     TRACE (("Got DHCP offer\n"));
00902     send_timeout = set_timeout (Random(100,500));
00903
00904     if (dhcp_renewal == 0L)
00905         dhcp_renewal = dhcp_iplease / 2;     /* default T1 time */
00906     if (dhcp_rebind == 0)
00907         dhcp_rebind = dhcp_iplease * 7 / 8;  /* default T2 time */
00908
00909     /* Remember my_ip_addr from OFFER because WinNT server
00910      * doesn't include it in ACK message.
00911      */
00912     my_ip_addr = ((_udp_Socket*)sock)->myaddr = intel (dhcp_in.dh_yiaddr);
00913     TRACE (("my_ip_addr = %s\n", INET_NTOA(my_ip_addr)));
00914     send_timeout = set_timeout (100);
00915     DHCP_state = DHCP_state_REQUESTING;
00916   }
00917   else if (event == EVENT_SEND_TIMEOUT)  /* retransmit timeout */
00918   {
00919     DHCP_state = DHCP_state_INIT;
00920     (*DHCP_state) (event);
00921   }
00922 }
00923
00928 static void DHCP_state_INIT (int event)
00929 {
00930   if (event == EVENT_SEND_TIMEOUT)
00931   {
00932     discover_loops++;
00933     exchange_id = set_timeout (0);       /* random exchange ID */
00934
00935     TRACE (("Sending DHCP discover (%d)\n", discover_loops));
00936
00937     send_timeout = set_timeout (1000 * dhcp_timeout);
00938     DHCP_discover();
00939     DHCP_state = DHCP_state_SELECTING;
00940   }
00941 }
00942
00943 #ifdef NOT_USED
00944
00947 static void DHCP_state_REBOOTING (int event)
00948 {
00949   if (event == EVENT_ACK)
00950   {
00951     DHCP_state = DHCP_state_BOUND;
00952   }
00953   else if (event == EVENT_NAK)
00954   {
00955     send_timeout = set_timeout (Random(4000,6000));
00956     DHCP_state = DHCP_state_INIT;
00957   }
00958 }
00959 #endif
00960
00964 static void dhcp_fsm (void)
00965 {
00966   if (sock_dataready(sock))
00967   {
00968     int len = sock_fastread (sock, (BYTE*)&dhcp_in, sizeof(dhcp_in));
00969
00970     if (len >= DHCP_MIN_SIZE &&                 /* packet large enough */
00971         dhcp_in.dh_op  == BOOTP_REPLY &&        /* got a BOOTP reply */
00972         dhcp_in.dh_xid == dhcp_out.dh_xid &&    /* got our exchange ID */
00973         !memcmp(dhcp_in.dh_chaddr, _eth_addr,   /* correct hardware addr */
00974                 sizeof(eth_address)))
00975     {
00976       if (DHCP_is_ack())
00977       {
00978         TRACE (("%s/ACK: ", state_name()));
00979         (*DHCP_state) (EVENT_ACK);
00980       }
00981       else if (DHCP_is_nack())
00982       {
00983         TRACE (("%s/NAK: ", state_name()));
00984         (*DHCP_state) (EVENT_NAK);
00985       }
00986       else
00987       {
00988         TRACE (("%s/OFFER: ", state_name()));
00989         (*DHCP_state) (EVENT_OFFER);
00990       }
00991     }
00992   }
00993
00994   if (chk_timeout(send_timeout))
00995   {
00996     send_timeout = 0UL;
00997     TRACE (("%s/SEND_TIMEOUT: ", state_name()));
00998     (*DHCP_state) (EVENT_SEND_TIMEOUT);
00999   }
01000
01001   if (renewal_timeout && time(NULL) >= renewal_timeout)
01002   {
01003     renewal_timeout = 0UL;
01004     TRACE (("%s/T1_TIMEOUT: ", state_name()));
01005     (*DHCP_state) (EVENT_T1_TIMEOUT);
01006   }
01007
01008   if (rebind_timeout && time(NULL) >= rebind_timeout)
01009   {
01010     rebind_timeout = 0UL;
01011     TRACE (("%s/T2_TIMEOUT: ", state_name()));
01012     (*DHCP_state) (EVENT_T2_TIMEOUT);
01013   }
01014 }
01015
01025 int DHCP_do_boot (void)
01026 {
01027   int save_mtu = _mtu;
01028
01029   if (cfg_read)    /* DHCP_read_config() okay */
01030      return (1);
01031
01032   outs (_LANG("Configuring through DHCP.."));
01033   if (!sock)
01034      sock = dhcp_open (NULL, bcast_flag);
01035   if (!sock)
01036      return (0);
01037
01038   _mtu = ETH_MAX_DATA;
01039   my_ip_addr = 0;
01040   sin_mask   = 0;
01041   discover_loops = 0;
01042
01043   erase_config();         /* delete old configuration */
01044   addwattcpd (dhcp_fsm);  /* add "background" daemon */
01045
01046   /* kick start DISCOVER message
01047    */
01048   send_timeout = set_timeout (100);
01049   DHCP_state = DHCP_state_INIT;
01050
01051   while (DHCP_state != DHCP_state_BOUND)
01052   {
01053     tcp_tick (NULL);
01054     if (discover_loops >= max_retries)  /* retries exhaused */
01055        break;
01056   }
01057
01058   got_offer = FALSE;   /* ready for next cycle */
01059   _mtu = save_mtu;
01060
01061   if (my_ip_addr)
01062   {
01063     cfg_saved = write_config() > 0;
01064     return (1);
01065   }
01066   return (0);
01067 }
01068
01072 static void dhcp_options_add (const BYTE *opt, unsigned max)
01073 {
01074   int   len = 0;
01075   char *add;
01076   const BYTE *end = opt + max;
01077
01078   extra_options.data = (BYTE*) realloc (extra_options.data, max);
01079   if (!extra_options.data)
01080      return;
01081
01082   add = (char*)&extra_options.data + extra_options.size;
01083
01084   /* Loop over `opt' and append to `add'. Strip away DHCP_OPT_END
01085    * and DHCP_OPT_PAD options.
01086    */
01087   while (opt < end)
01088   {
01089     if (*opt == DHCP_OPT_PAD)
01090        continue;
01091     if (*opt == DHCP_OPT_END)
01092        return;
01093
01094     len = opt[1];
01095     memcpy (add, opt, len+2);
01096     add += len + 2;
01097     opt += len + 2;
01098     extra_options.size += len + 2;
01099   }
01100 }
01101
01105 static void dhcp_set_timers (void)
01106 {
01107   time_t now = time (NULL);
01108
01109   if (dhcp_iplease == 0UL)
01110        lease_timeout = (time_t)-1;
01111   else lease_timeout = now + dhcp_iplease;
01112
01113   if (dhcp_renewal == 0UL)
01114        renewal_timeout = (time_t)-1;
01115   else renewal_timeout = now + dhcp_renewal;
01116
01117   if (dhcp_rebind == 0UL)
01118      rebind_timeout = (time_t)-1;
01119   else
01120   {
01121     rebind_timeout = now + dhcp_rebind;
01122     if (rebind_timeout == renewal_timeout)
01123         rebind_timeout += 10;             /* add 10 seconds */
01124   }
01125   if (dhcp_iplease == 0UL)
01126      TRACE (("Infinite lease!!\n"));
01127 }
01128
01132 static void change_ip_addr (void)
01133 {
01134   _tcp_Socket *tcp;
01135   _udp_Socket *udp;
01136
01137   if (my_ip_addr == old_ip_addr)
01138      return;
01139
01140   for (tcp = _tcp_allsocs; tcp; tcp = tcp->next)
01141   {
01142     if (tcp->myaddr)
01143         tcp->myaddr = my_ip_addr;
01144   }
01145   for (udp = _udp_allsocs; udp; udp = udp->next)
01146   {
01147     if (udp->myaddr)
01148         udp->myaddr = my_ip_addr;
01149   }
01150 }
01151
01156 static int set_request_list (char *options)
01157 {
01158   static BOOL init = FALSE;
01159   int    num       = 0;
01160   int    maxreq    = 312 - 27; /* sizeof(dh_opt) - min size of rest */
01161   BYTE  *list, *start, *tok, *end;
01162
01163   if (init || (list = (BYTE*)calloc(maxreq,1)) == NULL)
01164      return (0);
01165
01166   init  = 1;
01167   start = list;
01168   end   = start + maxreq - 1;
01169   tok   = (BYTE*) strtok (options, ", \t");
01170
01171   while (tok && list < end)
01172   {
01173     *list = ATOI ((const char*)tok);
01174     tok   = (BYTE*) strtok (NULL, ", \t");
01175
01176     /* If request list start with Pad option ("DHCP.REQ_LIST=0"),
01177      * disable options all-together.
01178      */
01179     if (num == 0 && *list == '0')
01180        break;
01181     num++;
01182     list++;
01183   }
01184
01185   request_list.data = start;
01186   request_list.size = num;
01187
01188 #if 0  /* test */
01189   {
01190     int i;
01191     for (i = 0; i < request_list.size; i++)
01192         printf ("%2d, ", request_list.data[i]);
01193     puts ("");
01194   }
01195 #endif
01196   return (1);
01197 }
01198
01202 static BYTE *put_request_list (BYTE *opt, int filled)
01203 {
01204   size_t size = min (request_list.size, sizeof(dhcp_out.dh_opt)-filled-1);
01205                                               /* room for DHCP_OPT_END ^ */
01206   if (size > 0 && request_list.data)
01207   {
01208     size = min (size, 255);
01209     *opt++ = DHCP_OPT_PARAM_REQUEST;
01210     *opt++ = size;
01211     memcpy (opt, request_list.data, size);
01212     opt += size;
01213   }
01214   return (opt);
01215 }
01216
01222 static int set_user_class (const char *value)
01223 {
01224   static BOOL init = FALSE;
01225   int    total     = 0;
01226   int    maxreq    = sizeof(dhcp_out.dh_opt) - 27; /* adjust for rest */
01227   char  *list, *list_start;
01228   char  *list_end;
01229   const char *value_end;
01230
01231   if (init || (list = (char*)calloc(maxreq,1)) == NULL)
01232      return (0);
01233
01234   init = TRUE;
01235   list_start = list;
01236   list_end   = list + maxreq - 1;
01237   value_end  = value + strlen (value);
01238
01239   while (list < list_end && value < value_end)
01240   {
01241     const char *comma = strchr (value, ',');
01242     int   size;
01243
01244     if (comma)
01245          size = comma - value;    /* "xxx,xxx" */
01246     else size = strlen (value);   /* "xxxx" */
01247     *list++ = size;
01248     memcpy (list, value, size);
01249     list  += size;
01250     value += size + 1;
01251     total += size + 1;
01252   }
01253
01254   user_class.data = (BYTE*) list_start;
01255   user_class.size = total;
01256
01257 #if 0  /* test */
01258   {
01259     size_t i;
01260     for (i = 0; i < user_class.size; i++)
01261     {
01262       int ch = user_class.data[i];
01263
01264       if (isprint(ch))
01265            printf ("%c", ch);
01266       else printf ("\\x%02X", ch);
01267     }
01268     puts ("");
01269   }
01270 #endif
01271   return (1);
01272 }
01273
01277 static int set_vend_class (const char *value)
01278 {
01280   ARGSUSED (value);
01281   return (0);
01282 }
01283
01284 /*-------------------------------------------------------------------*/
01285
01286 static void (*prev_hook) (const char*, const char*) = NULL;
01287
01288 /* Absolute times for expiry of lease, renewal and rebind
01289  * read from user (config_func) or transient config file.
01290  */
01291 static time_t cfg_dhcp_iplease;
01292 static time_t cfg_dhcp_renewal;
01293 static time_t cfg_dhcp_rebind;
01294
01300 static void DHCP_cfg_hook (const char *name, const char *value)
01301 {
01302   static const struct config_table dhcp_cfg[] = {
01303              { "REQ_LIST", ARG_FUNC,   (void*)set_request_list },
01304              { "TRACE",    ARG_ATOI,   (void*)&trace_on        },
01305              { "BCAST",    ARG_ATOI,   (void*)&bcast_flag      },
01306              { "TIMEOUT",  ARG_ATOI,   (void*)&dhcp_timeout    },
01307              { "RETRIES",  ARG_ATOI,   (void*)&max_retries     },
01308              { "ARPCHECK", ARG_ATOI,   (void*)&arp_check_ip    },
01309              { "HOST",     ARG_RESOLVE,(void*)&dhcp_server     },
01310              { "USERCLASS",ARG_FUNC,   (void*)set_user_class   },
01311              { "VENDCLASS",ARG_FUNC,   (void*)set_vend_class   },
01312              { "CONFIG",   ARG_STRCPY, (void*)&config_file     },
01313              { NULL,       0,          NULL                    }
01314            };
01315
01316   if (!parse_config_table(&dhcp_cfg[0], "DHCP.", name, value) && prev_hook)
01317      (*prev_hook) (name, value);
01318 }
01319
01323 static void DHCP_exit (void)
01324 {
01325   if (_watt_fatal_error)
01326      return;
01327
01328   DO_FREE (user_class.data);
01329   DO_FREE (extra_options.data);
01330   DO_FREE (sock);
01331   if (request_list.data != (BYTE*)&default_request_list)
01332      DO_FREE (request_list.data);
01333
01334 #if defined(USE_BSD_API)
01335   syslog_hostName[0] = '\0';
01336 #endif
01337 }
01338
01342 void DHCP_init (void)
01343 {
01344   prev_hook = usr_init;
01345   usr_init  = DHCP_cfg_hook;
01346   RUNDOWN_ADD (DHCP_exit, 259);
01347 }
01348
01352 static void set_my_ip (const char *value)
01353 {
01354   TRACE (("DHCP: using previous address  %s\n", value));
01355   my_ip_addr = aton (value);
01356 }
01357
01358 static void set_netmask (const char *value)
01359 {
01360   TRACE (("DHCP: using previous netmask  %s\n", value));
01361   sin_mask = aton (value);
01362 }
01363
01364 static void set_gateway (const char *value)
01365 {
01366   router = aton (value);
01367   if (router)
01368   {
01369     _arp_kill_gateways();   /* delete gateways from cfg-file */
01370     TRACE (("DHCP: using previous gateway  %s\n", value));
01371     _arp_add_gateway (NULL, router);
01372   }
01373   else
01374     TRACE (("DHCP: previous gateway is 0.0.0.0!\n"));
01375 }
01376
01377 static void set_nameserv (const char *value)
01378 {
01379   TRACE (("DHCP: using previous nameserv %s\n", value));
01380   nameserver = aton (value);
01381   _add_server (&last_nameserver, MAX_NAMESERVERS, def_nameservers, nameserver);
01382 }
01383
01384 static void set_server (const char *value)
01385 {
01386   TRACE (("DHCP: using previous server   %s\n", value));
01387   dhcp_server = aton (value);
01388 }
01389
01390 static void set_domain (const char *value)
01391 {
01392   TRACE (("DHCP: using previous domain   %s\n", value));
01393   setdomainname (value, strlen(value)+1);
01394 }
01395
01396 static void set_lease (const char *value)
01397 {
01398   cfg_dhcp_iplease = ATOL (value);
01399 }
01400
01401 static void set_renew (const char *value)
01402 {
01403   cfg_dhcp_renewal = ATOL (value);
01404 }
01405
01406 static void set_rebind (const char *value)
01407 {
01408   cfg_dhcp_rebind = ATOL (value);
01409 }
01410
01422 static BOOL eval_timers (void)
01423 {
01424   time_t now = time (NULL);
01425
01426   TRACE (("DHCP: IP-lease expires at  %s", ctime(&cfg_dhcp_iplease)));
01427   TRACE (("DHCP: rebinding expires at %s", ctime(&cfg_dhcp_rebind)));
01428   TRACE (("DHCP: renewal expires at   %s", ctime(&cfg_dhcp_renewal)));
01429
01430   if (cfg_dhcp_iplease < now)
01431        dhcp_iplease = DHCP_MIN_LEASE;
01432   else dhcp_iplease = cfg_dhcp_iplease - now;
01433
01434   if (cfg_dhcp_renewal < now)
01435        dhcp_renewal = dhcp_iplease / 2;
01436   else dhcp_renewal = cfg_dhcp_renewal - now;
01437
01438   if (cfg_dhcp_rebind < now)
01439        dhcp_rebind = dhcp_iplease * 7 / 8;
01440   else dhcp_rebind = cfg_dhcp_rebind  - now;
01441
01442   discover_loops = 0;
01443
01444   if (now < cfg_dhcp_renewal)
01445   {
01446     TRACE (("DHCP: BOUND\n"));
01447     DHCP_state = DHCP_state_BOUND;          /* no action, goto BOUND */
01448     return (TRUE);
01449   }
01450
01451   if (now >= cfg_dhcp_renewal && now < cfg_dhcp_rebind)
01452   {
01453     TRACE (("DHCP: RENEWING\n"));
01454     DHCP_state_BOUND (EVENT_T1_TIMEOUT);    /* goto RENEWING */
01455     return (TRUE);
01456   }
01457
01458   if (now >= cfg_dhcp_rebind && now < cfg_dhcp_iplease)
01459   {
01460     TRACE (("DHCP: REBINDING\n"));
01461     DHCP_state_RENEWING (EVENT_T2_TIMEOUT); /* goto REBINDING */
01462     return (TRUE);
01463   }
01464   return (FALSE);
01465 }
01466
01473 static const struct config_table transient_cfg[] = {
01474            { "DHCP.LEASE",    ARG_FUNC,   (void*)set_lease        },
01475            { "DHCP.RENEW",    ARG_FUNC,   (void*)set_renew        },
01476            { "DHCP.REBIND",   ARG_FUNC,   (void*)set_rebind       },
01477            { "DHCP.MY_IP",    ARG_FUNC,   (void*)set_my_ip        },
01478            { "DHCP.NETMASK",  ARG_FUNC,   (void*)set_netmask      },
01479            { "DHCP.GATEWAY",  ARG_FUNC,   (void*)set_gateway      },
01480            { "DHCP.NAMESERV", ARG_FUNC,   (void*)set_nameserv     },
01481            { "DHCP.SERVER",   ARG_FUNC,   (void*)set_server       },
01482            { "DHCP.DOMAIN",   ARG_FUNC,   (void*)set_domain       },
01483            { "DHCP.HOSTNAME", ARG_STRCPY, (void*)hostname         },
01484 #if defined(USE_BSD_API)
01485            { "DHCP.LOGHOST",  ARG_STRCPY, (void*)&syslog_hostName },
01486 #endif
01487            { "DHCP.DEF_TTL",  ARG_ATOI,   (void*)&_default_ttl    },
01488            { "DHCP.TCP_KEEP", ARG_ATOI,   (void*)&tcp_keep_intvl  },
01489            { NULL,            0,          NULL                    }
01490          };
01491
01492 /*
01493  * Return name of transient config-file.
01494  */
01495 static const char *get_config_file (void)
01496 {
01497   if (config_file[0])
01498      return (config_file);
01499   return ExpandVarStr ("$(TEMP)\\W32DHCP.TMP");
01500 }
01501
01502 /*
01503  * The standard DHCP config eraser.
01504  */
01505 static void std_erase_config (void)
01506 {
01507   unlink (get_config_file());
01508 }
01509
01510 /*
01511  * The standard DHCP config reader.
01512  */
01513 static int std_read_config (void)
01514 {
01515   WFILE file;
01516   const char *fname = get_config_file();
01517
01518   if (!FOPEN(file, fname))
01519   {
01520     TRACE (("`%s' not found\n", fname));
01521     return (0);
01522   }
01523
01524   prev_hook = usr_init;
01525   usr_init  = NULL;     /* don't chain to other parsers */
01526   tcp_parse_file (file, &transient_cfg[0]);
01527   usr_init = prev_hook;
01528
01529   FCLOSE (file);
01530   return (1);
01531 }
01532
01538 static int std_write_config (void)
01539 {
01540   char   buf[20];
01541   FILE  *file;
01542   time_t tim, now = time (NULL);
01543   int    rc  = 0;
01544   const  char *fname = get_config_file();
01545
01546   if (access(fname,0))  /* file not found, create */
01547   {
01548     file = fopen (fname, "w+t");
01549     if (!file)
01550        goto fail;
01551
01552     rc = fprintf (file,
01553                   "#\n"
01554                   "# GENERATED FILE. DO NOT EDIT!\n"
01555                   "#\n"
01556                   "# DHCP transient configuration; values that must\n"
01557                   "# be known between consecutive runs of applications.\n"
01558                   "# Version: %s\n"
01559                   "#\n", wattcpVersion());
01560   }
01561   else
01562   {
01563 #if defined(WIN32)
01564     SetFileAttributes (fname, FILE_ATTRIBUTE_NORMAL);
01565 #else
01566     _dos_setfileattr (fname, _A_NORMAL);
01567 #endif
01568     file = fopen (fname, "at");  /* append to file */
01569     if (!file)
01570        goto fail;
01571   }
01572
01573   rc += fprintf (file, "# This file saved at %s#\n", ctime(&now));
01574
01575   tim = dhcp_iplease + now;
01576   rc += fprintf (file, "DHCP.LEASE    = %-20lu # lease expires at  %s",
01577                  (DWORD)tim, ctime(&tim));
01578
01579   tim = dhcp_renewal + now;
01580   rc += fprintf (file, "DHCP.RENEW    = %-20lu # renew expires at  %s",
01581                  (DWORD)tim, ctime(&tim));
01582
01583   tim = dhcp_rebind + now;
01584   rc += fprintf (file,
01585                  "DHCP.REBIND   = %-20lu # rebind expires at %s"
01586                  "DHCP.MY_IP    = %-20s # assigned ip-address\n",
01587                  (DWORD)tim, ctime(&tim), _inet_ntoa(buf,my_ip_addr));
01588
01589   rc += fprintf (file, "DHCP.NETMASK  = %-20s # assigned netmask\n",
01590                  _inet_ntoa(buf,sin_mask));
01591
01592   rc += fprintf (file, "DHCP.GATEWAY  = %-20s # assigned gateway\n",
01593                  _inet_ntoa(buf,router));
01594
01595   rc += fprintf (file, "DHCP.NAMESERV = %-20s # assigned nameserver\n",
01596                  _inet_ntoa(buf,nameserver));
01597
01598   rc += fprintf (file, "DHCP.SERVER   = %-20s # DHCP server\n",
01599                  _inet_ntoa(buf,dhcp_server));
01600
01601   rc += fprintf (file, "DHCP.HOSTNAME = %-20s # assigned hostname\n",
01602                  hostname);
01603
01604   rc += fprintf (file, "DHCP.DOMAIN   = %-20s # assigned domain\n",
01605                  def_domain);
01606
01607 #if defined(USE_BSD_API)
01608   if (syslog_hostName[0])
01609      rc += fprintf (file, "DHCP.LOGHOST  = %-20s # assigned syslog host\n",
01610                     syslog_hostName);
01611 #endif
01612
01613   rc += fprintf (file, "DHCP.DEF_TTL  = %-20d # default TTL\n",
01614                  _default_ttl);
01615
01616   rc += fprintf (file, "DHCP.TCP_KEEP = %-20d # TCP keepalive interval\n",
01617                  tcp_keep_intvl);
01618
01619   fclose (file);
01620   return (rc);
01621
01622 fail:
01623   TCP_CONSOLE_MSG (0, ("Writing %s failed; %s\n", fname, strerror(errno)));
01624   return (0);
01625 }
01626
01627 /*
01628  * The user-defined DHCP config eraser.
01629  */
01630 static void usr_erase_config (void)
01631 {
01632   (*config_func) (DHCP_OP_ERASE, NULL);
01633 }
01634
01635 static int usr_read_config (void)
01636 {
01637   struct DHCP_config cfg;
01638
01639   memset (&cfg, 0, sizeof(cfg));
01640
01641   if (!(*config_func)(DHCP_OP_READ, &cfg))
01642      return (0);
01643
01644   TRACE (("DHCP: using previous address  %s\n", INET_NTOA(cfg.my_ip)));
01645   my_ip_addr = cfg.my_ip;
01646
01647   TRACE (("DHCP: using previous netmask  %s\n", INET_NTOA(cfg.netmask)));
01648   sin_mask = cfg.netmask;
01649
01650   if (!_arp_have_default_gw())
01651   {
01652     TRACE (("DHCP: using previous gateway  %s\n", INET_NTOA(cfg.gateway)));
01653     router = cfg.gateway;
01654     _arp_add_gateway (NULL, router);
01655   }
01656   else
01657     TRACE (("DHCP: already have default gateway\n"));
01658
01659   TRACE (("DHCP: using previous nameserv %s\n", INET_NTOA(cfg.nameserver)));
01660   nameserver = cfg.nameserver;
01661   _add_server (&last_nameserver, MAX_NAMESERVERS, def_nameservers, nameserver);
01662
01663   TRACE (("DHCP: using previous server   %s\n", INET_NTOA(cfg.server)));
01664   dhcp_server = cfg.server;
01665
01666   cfg_dhcp_iplease = cfg.iplease;
01667   cfg_dhcp_renewal = cfg.renewal;
01668   cfg_dhcp_rebind  = cfg.rebind;
01669
01670   _default_ttl   = cfg.default_ttl;
01671   tcp_keep_intvl = cfg.tcp_keep_intvl;
01672
01673   StrLcpy (hostname, cfg.hostname, sizeof(hostname));
01674
01675   TRACE (("DHCP: using previous domain   %s\n", cfg.domain));
01676   setdomainname (cfg.domain, strlen(cfg.domain)+1);
01677
01678 #if defined(USE_BSD_API)
01679   if (cfg.loghost[0])
01680      StrLcpy (syslog_hostName, cfg.loghost, sizeof(syslog_hostName));
01681 #endif
01682
01683   return (1);
01684 }
01685
01686 static int usr_write_config (void)
01687 {
01688   struct DHCP_config cfg;
01689   time_t             now = time (NULL);
01690
01691   memset (&cfg, 0, sizeof(cfg));
01692   cfg.my_ip          = my_ip_addr;
01693   cfg.netmask        = sin_mask;
01694   cfg.gateway        = router;
01695   cfg.nameserver     = nameserver;
01696   cfg.server         = dhcp_server;
01697   cfg.iplease        = now + dhcp_iplease;
01698   cfg.renewal        = now + dhcp_renewal;
01699   cfg.rebind         = now + dhcp_rebind;
01700   cfg.default_ttl    = _default_ttl;
01701   cfg.tcp_keep_intvl = tcp_keep_intvl;
01702
01703   StrLcpy (cfg.hostname, hostname, sizeof(cfg.hostname));
01704   StrLcpy (cfg.domain, def_domain, sizeof(cfg.domain));
01705
01706 #if defined(USE_BSD_API)
01707   if (syslog_hostName[0])
01708      StrLcpy (cfg.loghost, syslog_hostName, sizeof(cfg.loghost));
01709 #endif
01710
01711   return (*config_func) (DHCP_OP_WRITE, &cfg);
01712 }
01713
01717 static void erase_config (void)
01718 {
01719   config_func ? usr_erase_config() : std_erase_config();
01720 }
01721
01727 int DHCP_read_config (void)
01728 {
01729   cfg_read = FALSE;
01730
01731   if (config_func ? usr_read_config() : std_read_config() > 0)
01732   {
01733     sock = dhcp_open (NULL, bcast_flag);
01734     if (!sock)
01735        return (0);
01736
01737     if (eval_timers())
01738     {
01739       cfg_read = TRUE;
01740       dhcp_set_timers();
01741       return (1);
01742     }
01743     TRACE (("DHCP: config too old.\n"));
01744     sock->udp.myaddr = 0;
01745     sock->udp.hisaddr = IP_BCAST_ADDR;
01746   }
01747
01748   /* Reading config failed or timers expired; must do the whole
01749    * DHCP configuration when sock_init.c calls DHCP_do_boot().
01750    */
01751   return (0);
01752 }
01753
01758 static int write_config (void)
01759 {
01760   return (config_func ? usr_write_config() : std_write_config());
01761 }
01762
01766 WattDHCPConfigFunc dhcp_set_config_func (WattDHCPConfigFunc fn)
01767 {
01768   WattDHCPConfigFunc old_fn = config_func;
01769   config_func = fn;
01770   return (old_fn);
01771 }
01772 #endif /* USE_DHCP */
Generated on Wed Jan 25 15:42:37 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/PCDHCP.H Source File

SRC/PCDHCP.H

Go to the documentation of this file.
00001
00003 #ifndef _w32_PCDHCP_H
00004 #define _w32_PCDHCP_H
00005
00006 #define DHCP_MAGIC_COOKIE  0x63538263   /* magic cookie */
00007 #define DHCP_MIN_LEASE     10           /* 10s min. lease */
00008
00009
00010 enum DHCP_MsgTypes {
00011      DHCP_DISCOVER = 1,
00012      DHCP_OFFER,
00013      DHCP_REQUEST,
00014      DHCP_DECLINE,
00015      DHCP_ACK,
00016      DHCP_NAK ,
00017      DHCP_RELEASE,
00018      DHCP_INFORM
00019    };
00020
00021 enum DHCP_Events {
00022      EVENT_OFFER = 1,
00023      EVENT_SEND_TIMEOUT,
00024      EVENT_T1_TIMEOUT,
00025      EVENT_T2_TIMEOUT,
00026      EVENT_ACK,
00027      EVENT_NAK,
00028    };
00029
00030 /*
00031  * DHCP options and values (ref. RFC1533/RFC2132).
00032  * Many are also BOOTP options.
00033  */
00034 enum DHCP_Options {
00035      DHCP_OPT_PAD                      =  0,
00036      DHCP_OPT_SUBNET_MASK              =  1,
00037      DHCP_OPT_TIME_OFFSET              =  2,
00038      DHCP_OPT_ROUTERS_ON_SNET          =  3,
00039      DHCP_OPT_TIME_SRV                 =  4,
00040      DHCP_OPT_NAME_SRV                 =  5,
00041      DHCP_OPT_DNS_SRV                  =  6,
00042      DHCP_OPT_LOG_SRV                  =  7,
00043      DHCP_OPT_COOKIE_SRV               =  8,
00044      DHCP_OPT_LPR_SRV                  =  9,
00045      DHCP_OPT_IMPRESS_SRV              = 10,
00046      DHCP_OPT_RES_LOCATION_SRV         = 11,
00047      DHCP_OPT_HOST_NAME                = 12,
00048      DHCP_OPT_BOOT_FSIZE               = 13,
00049      DHCP_OPT_MERIT_DUMPFILE           = 14,
00050      DHCP_OPT_DOMAIN_NAME              = 15,
00051      DHCP_OPT_SWAP_SRV                 = 16,
00052      DHCP_OPT_ROOT_PATH                = 17,
00053      DHCP_OPT_EXTENTIONS_PATH          = 18,
00054      DHCP_OPT_IP_FORWARDING            = 19,
00055      DHCP_OPT_NON_LOCAL_SRC_ROUTE      = 20,
00056      DHCP_OPT_POLICY_FILTER            = 21,
00057      DHCP_OPT_MAX_DGRAM_REASM_SIZE     = 22,
00058      DHCP_OPT_IP_DEFAULT_TTL           = 23,
00059      DHCP_OPT_PATH_MTU_AGING_TIMEOUT   = 24,
00060      DHCP_OPT_PATH_MTU_PLATEAU_TABLE   = 25,
00061      DHCP_OPT_IF_MTU                   = 26,
00062      DHCP_OPT_ALL_SUBNETS_LOCAL        = 27,
00063      DHCP_OPT_BROADCAST_ADDR           = 28,
00064      DHCP_OPT_PERFORM_MASK_DISCOVERY   = 29,
00065      DHCP_OPT_MASK_SUPPLIER            = 30,
00066      DHCP_OPT_PERFORM_ROUTER_DISCOVERY = 31,
00067      DHCP_OPT_ROUTER_SOLICITATION_ADDR = 32,
00068      DHCP_OPT_STATIC_ROUTE             = 33,
00069      DHCP_OPT_TRAILER_ENCAPSULATION    = 34,
00070      DHCP_OPT_ARP_CACHE_TIMEOUT        = 35,
00071      DHCP_OPT_ETHERNET_ENCAPSULATION   = 36,
00072      DHCP_OPT_TCP_DEFAULT_TTL          = 37,
00073      DHCP_OPT_TCP_KEEPALIVE_INTERVAL   = 38,
00074      DHCP_OPT_TCP_KEEPALIVE_GARBAGE    = 39,
00075      DHCP_OPT_NIS_DOMAIN_NAME          = 40,
00076      DHCP_OPT_NIS_SRVS                 = 41,
00077      DHCP_OPT_NTP_SRVS                 = 42,
00078      DHCP_OPT_VENDOR_SPECIFIC_INFO     = 43,
00079      DHCP_OPT_NBIOS_NAME_SRV           = 44,
00080      DHCP_OPT_NBIOS_DGRAM_DIST_SRV     = 45,
00081      DHCP_OPT_NBIOS_NODE_TYPE          = 46,
00082      DHCP_OPT_NBIOS_SCOPE              = 47,
00083      DHCP_OPT_XFONT_SRV                = 48,
00084      DHCP_OPT_XDISPLAY_MANAGER         = 49,
00085      DHCP_OPT_REQUESTED_IP_ADDR        = 50,
00086      DHCP_OPT_IP_ADDR_LEASE_TIME       = 51,
00087      DHCP_OPT_OVERLOAD                 = 52,
00088      DHCP_OPT_MSG_TYPE                 = 53,
00089      DHCP_OPT_SRV_IDENTIFIER           = 54,
00090      DHCP_OPT_PARAM_REQUEST            = 55,
00091      DHCP_OPT_MSG                      = 56,
00092      DHCP_OPT_MAX_MSG_SIZE             = 57,
00093      DHCP_OPT_T1_VALUE                 = 58,
00094      DHCP_OPT_T2_VALUE                 = 59,
00095      DHCP_OPT_CLASS_ID                 = 60,
00096      DHCP_OPT_CLIENT_ID                = 61,
00097      DHCP_OPT_NIS_DOMAIN               = 64,
00098      DHCP_OPT_NIS_SRV_OPT              = 65,
00099      DHCP_OPT_TFTP_SERVER              = 66,
00100      DHCP_OPT_BOOT_FILENAME            = 67,
00101      DHCP_OPT_MOBIP_HOME_AGENTS        = 68,
00102      DHCP_OPT_SMTP_SRVS                = 69,
00103      DHCP_OPT_POP3_SRVS                = 70,
00104      DHCP_OPT_NNTP_SRVS                = 71,
00105      DHCP_OPT_WWW_SRVS                 = 72,
00106      DHCP_OPT_FINGER_SRVS              = 73,
00107      DHCP_OPT_IRC_SRVS                 = 74,
00108      DHCP_OPT_STREET_TALK_SRVS         = 75,
00109      DHCP_OPT_STDA_SRVS                = 76,
00110      DHCP_OPT_USER_CLASS               = 77,
00111      DHCP_OPT_GRUB_MENU                = 150,
00112      DHCP_OPT_END                      = 255
00113    };
00114
00117 struct DHCP_list {
00118        BYTE     *data;
00119        unsigned  size;
00120      };
00121
00122 #include <sys/packon.h>
00123
00128 struct dhcp  {
00129        BYTE  dh_op;         /* packet op code / message type.             */
00130        BYTE  dh_htype;      /* hardware address type, 1 = 10 mb ethernet  */
00131        BYTE  dh_hlen;       /* hardware address len, eg '6' for ethernet  */
00132        BYTE  dh_hops;       /* client sets to zero, optionally used by    */
00133                             /* gateways in cross-gateway booting.         */
00134        DWORD dh_xid;        /* transaction ID, a random number            */
00135        WORD  dh_secs;       /* filled in by client, seconds elapsed       */
00136                             /* since client started trying to boot.       */
00137        WORD  dh_flags;      /* Flag (0x8000 for broadcast, else 0)        */
00138        DWORD dh_ciaddr;     /* client IP address filled in by client if known */
00139        DWORD dh_yiaddr;     /* 'your' (client) IP address                 */
00140                             /* filled by server if client doesn't know    */
00141        DWORD dh_siaddr;     /* server IP address returned in bootreply    */
00142        DWORD dh_giaddr;     /* gateway IP address,                        */
00143                             /* used in optional cross-gateway booting.    */
00144        BYTE  dh_chaddr[16]; /* client hardware address, filled by client  */
00145        BYTE  dh_sname[64];  /* optional server host name, null terminated */
00146
00147        BYTE  dh_file[128];  /* boot file name, null terminated string     */
00148                             /* 'generic' name or null in bootrequest,     */
00149                             /* fully qualified directory-path             */
00150                             /* name in bootreply.                         */
00151        BYTE  dh_opt[312];   /* DHCP options area (minimum 308 bytes)      */
00152      };
00153
00154
00155 /* This was 284, but D-Link 614+ router ACKs are too small
00156  */
00157 #define DHCP_MIN_SIZE  280
00158
00159 /* Structure passed to an application hook set by
00160  * dhcp_set_config_func()
00161  */
00162 struct DHCP_config {
00163        DWORD  my_ip;
00164        DWORD  netmask;
00165        DWORD  gateway;
00166        DWORD  nameserver;
00167        DWORD  server;
00168        DWORD  iplease;
00169        DWORD  renewal;
00170        DWORD  rebind;
00171        DWORD  tcp_keep_intvl;
00172        BYTE   default_ttl;
00173        char   hostname [MAX_HOSTLEN+1];
00174        char   domain [MAX_HOSTLEN+1];
00175        char   loghost [MAX_HOSTLEN+1];  /* Only used if USE_BSD_API */
00176      };
00177
00178 #include <sys/packoff.h>
00179
00180 enum DHCP_config_op {
00181      DHCP_OP_READ  = 0,
00182      DHCP_OP_WRITE = 1,
00183      DHCP_OP_ERASE = 2
00184    };
00185
00186 extern
00187 #ifndef DHCP_IMPLEMENTATION
00188 const
00189 #endif
00190 BOOL dhcp_did_gratuitous_arp;  /* the only public variable in pcdhcp.c */
00191
00192 typedef int (*WattDHCPConfigFunc) (enum DHCP_config_op op,
00193                                    struct DHCP_config *cfg);
00194
00195 extern WattDHCPConfigFunc dhcp_set_config_func (WattDHCPConfigFunc fn);
00196
00197 extern   int   DHCP_do_boot (void);
00198 extern   void  DHCP_init (void);
00199
00200 W32_FUNC void  DHCP_release (BOOL force);
00201 W32_FUNC int   DHCP_read_config (void);
00202 W32_FUNC DWORD DHCP_get_server (void);
00203
00204 #endif
Generated on Wed Jan 25 15:42:37 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/PCICMP.C Source File

SRC/PCICMP.C

Go to the documentation of this file.
00001
00005 #include <stdio.h>
00006 #include <stdlib.h>
00007 #include <string.h>
00008
00009 #include "copyrigh.h"
00010 #include "wattcp.h"
00011 #include "strings.h"
00012 #include "language.h"
00013 #include "misc.h"
00014 #include "timer.h"
00015 #include "chksum.h"
00016 #include "ip4_in.h"
00017 #include "pctcp.h"
00018 #include "pcsed.h"
00019 #include "pcarp.h"
00020 #include "pcstat.h"
00021 #include "pcdbug.h"
00022 #include "pcqueue.h"
00023 #include "pcconfig.h"
00024 #include "pcpkt.h"
00025 #include "pcping.h"
00026 #include "sock_ini.h"
00027 #include "netaddr.h"
00028 #include "ip4_out.h"
00029 #include "pcicmp.h"
00030
00031 const char *icmp_type_str [ICMP_MAXTYPE+1] = {
00032       __LANG("Echo Reply"),  "1", "2",
00033       __LANG("Destination Unreachable"),
00034       __LANG("Source Quench"),
00035       __LANG("Redirect"),    "6", "7",
00036       __LANG("Echo Request"),
00037       __LANG("Router Advert"),
00038       __LANG("Router Solic"),
00039       __LANG("TTL exceeded"),
00040       __LANG("Param Problem"),
00041       __LANG("Timestamp Message"),
00042       __LANG("Timestamp Reply"),
00043       __LANG("Info Request"),
00044       __LANG("Info Reply"),
00045       __LANG("Mask Request"),
00046       __LANG("Mask Reply")
00047     };
00048
00049 /* code-strings for type ICMP_UNREACH
00050  */
00051 const char *icmp_unreach_str [16] = {
00052       __LANG("Network Unreachable"),              /* 0 */
00053       __LANG("Host Unreachable"),
00054       __LANG("Protocol Unreachable"),             /* 2 */
00055       __LANG("Port Unreachable"),
00056       __LANG("Fragmentation needed and DF set"),  /* 4 */
00057       __LANG("Source Route Failed"),
00058       __LANG("Network unknown"),                  /* 6 */
00059       __LANG("Host unknown"),
00060       __LANG("Source host isolated"),             /* 8 */
00061       __LANG("Net-access denied"),
00062       __LANG("Host-access denied"),               /* 10 */
00063       __LANG("Bad TOS for net"),
00064       __LANG("Bad TOS for host"),                 /* 12 */
00065       __LANG("Admin prohibited"),
00066       __LANG("Host precedence violation"),        /* 14 */
00067       __LANG("Precedence cutoff")
00068     };
00069
00070 /* code-strings for type ICMP_REDIRECT
00071  */
00072 const char *icmp_redirect_str [4] = {
00073       __LANG("Redirect for Network"),
00074       __LANG("Redirect for Host"),
00075       __LANG("Redirect for TOS and Network"),
00076       __LANG("Redirect for TOS and Host")
00077     };
00078
00079 /* code-strings for type ICMP_TIMXCEED
00080  */
00081 const char *icmp_exceed_str [2] = {
00082       __LANG("TTL exceeded in transit"),
00083       __LANG("Frag ReAsm time exceeded")
00084     };
00085
00086 #include <sys/packon.h>
00087
00090 struct _pkt {
00091        in_Header  ip;
00092        ICMP_PKT   icmp;
00093        in_Header  data;
00094      };
00095
00096 #include <sys/packoff.h>
00097
00100 static struct {
00101        char  icmp;
00102        char  igmp;
00103        char  udp;
00104        char  tcp;
00105      } do_redirect = { 1,1,1,1 };
00106
00107
00108 static void icmp_print (int dbg_lvl, const char *msg, DWORD src)
00109 {
00110   if (debug_on < dbg_lvl)
00111      return;
00112
00113   outs ("\nICMP: ");
00114   if (src)
00115   {
00116     outs ("(");
00117     outs (_inet_ntoa(NULL,intel(src)));
00118     outs ("): ");
00119   }
00120   outsnl (_LANG(msg));
00121 }
00122
00127 static void icmp_bogus (const in_Header *ip, int type, const char *msg)
00128 {
00129   char buf[100];
00130
00131   strcpy (buf, _LANG("Bogus "));
00132   strcat (buf, _LANG(icmp_type_str[type]));
00133   if (msg)
00134      strcat (buf, msg);
00135   icmp_print (1, buf, ip->source);
00136 }
00137
00144 static BOOL icmp_check (const in_Header *ip, int type)
00145 {
00146   DWORD src, dst;
00147   BOOL  bcast;
00148
00149   src   = intel (ip->source);
00150   dst   = intel (ip->destination);
00151   bcast = (~src & ~sin_mask) == 0;
00152
00153   if (bcast)
00154   {
00155     icmp_bogus (ip, type, _LANG(" (broadcast)"));
00156     return (FALSE);
00157   }
00158   if (ip->source == 0UL)
00159   {
00160     icmp_bogus (ip, type, _LANG(" (network)"));
00161     return (FALSE);
00162   }
00163   if (IN_MULTICAST(dst))
00164   {
00165     icmp_bogus (ip, type, _LANG(" (multicast)"));
00166     return (FALSE);
00167   }
00168   if (IN_EXPERIMENTAL(dst))
00169   {
00170     icmp_bogus (ip, type, _LANG(" (experimental)"));
00171     return (FALSE);
00172   }
00173   return (TRUE);
00174 }
00175
00180 static int icmp_send (struct _pkt *pkt, DWORD src, DWORD dest, int length)
00181 {
00182   in_Header *ip   = &pkt->ip;
00183   ICMP_PKT  *icmp = &pkt->icmp;
00184
00185   icmp->unused.checksum = 0;
00186   icmp->unused.checksum = ~CHECKSUM (icmp, length);
00187
00188   return IP4_OUTPUT (ip, src, dest, ICMP_PROTO, 0, 0, 0, length, NULL);
00189 }
00190
00195 int icmp_send_unreach (const in_Header *ip, int code)
00196 {
00197   static DWORD next_time = 0UL;
00198   struct _pkt    *pkt;
00199   union ICMP_PKT *unr;
00200   unsigned        len;
00201
00202   if (!icmp_check(ip,ICMP_UNREACH))
00203      return (0);
00204
00205   if (next_time && !chk_timeout(next_time))
00206      return (0);
00207
00208   next_time = set_timeout (50);
00209
00210   pkt = (struct _pkt*) _eth_formatpacket (MAC_SRC(ip), IP4_TYPE);
00211   unr = &pkt->icmp;
00212   len = intel16 (ip->length) - in_GetHdrLen (ip);
00213   len = min (len, sizeof(*ip)+sizeof(unr->unused.spares));
00214
00215   icmp_print (1, _LANG(icmp_unreach_str[code]), ip->destination);
00216   memcpy (&unr->unused.ip, ip, len);
00217   unr->unused.type = ICMP_UNREACH;
00218   unr->unused.code = (BYTE) code;
00219
00220   return icmp_send (pkt, ip->destination, ip->source, sizeof(unr->unused));
00221 }
00222
00226 int icmp_send_timexceed (const in_Header *ip, const void *mac_dest)
00227 {
00228   struct _pkt    *pkt;
00229   union ICMP_PKT *icmp;
00230
00231   if (!icmp_check(ip,ICMP_TIMXCEED))
00232      return (0);
00233
00234   pkt  = (struct _pkt*) _eth_formatpacket (mac_dest, IP4_TYPE);
00235   icmp = &pkt->icmp;
00236
00237   icmp_print (1, icmp_exceed_str[1], ip->destination);
00238
00239   memset (&icmp->unused, 0, sizeof(icmp->unused));
00240
00241   icmp->unused.type = ICMP_TIMXCEED;
00242   icmp->unused.code = 1;
00243
00244   icmp->unused.ip.hdrlen         = sizeof(in_Header) / 4;
00245   icmp->unused.ip.ver            = 4;
00246   icmp->unused.ip.ttl            = _default_ttl;
00247   icmp->unused.ip.identification = ip->identification;
00248   icmp->unused.ip.length         = intel16 (sizeof(in_Header));
00249   icmp->unused.ip.proto          = ip->proto;
00250   icmp->unused.ip.checksum       = ~CHECKSUM (&icmp->unused.ip, sizeof(in_Header));
00251
00252   return icmp_send (pkt, ip->destination, ip->source, sizeof(icmp->unused));
00253 }
00254
00259 static WORD addr_mask_id  = 0;
00260 static WORD addr_mask_seq = 0;
00261
00262 int icmp_send_mask_req (void)
00263 {
00264   mac_address    *dst  = (_pktserial ? NULL : &_eth_brdcast);
00265   struct _pkt    *pkt  = (struct _pkt*) _eth_formatpacket (dst, IP4_TYPE);
00266   union ICMP_PKT *icmp = &pkt->icmp;
00267
00268   addr_mask_id = (WORD) set_timeout (0);   /* get a random ID */
00269   icmp->mask.type       = ICMP_MASKREQ;
00270   icmp->mask.code       = 0;
00271   icmp->mask.identifier = addr_mask_id;
00272   icmp->mask.sequence   = addr_mask_seq++;
00273   icmp->mask.mask       = 0;
00274   return icmp_send (pkt, 0, (DWORD)INADDR_BROADCAST, sizeof(icmp->mask));
00275 }
00276
00277 static int icmp_echo_reply (const in_Header *ip, const union ICMP_PKT *req,
00278                             unsigned len)
00279 {
00280   struct _pkt     *pkt;
00281   union  ICMP_PKT *icmp;
00282
00283   if (!icmp_check(ip,ICMP_ECHO))
00284      return (0);
00285
00286   icmp_print (2, _LANG("PING reply sent"), 0);
00287
00288 #if defined(USE_FRAGMENTS)
00289   if (len > _mtu - sizeof(*ip))
00290   {
00291     icmp = (union ICMP_PKT*) req;        /* reuse input for output */
00292     icmp->echo.type     = ICMP_ECHOREPLY;
00293     icmp->echo.checksum = 0;
00294     icmp->echo.checksum = ~CHECKSUM (icmp, len);
00295     return _IP4_SEND_FRAGMENTS (NULL, ICMP_PROTO, ip->source, icmp, len);
00296   }
00297 #endif
00298
00299   pkt  = (struct _pkt*) _eth_formatpacket (MAC_SRC(ip), IP4_TYPE);
00300   icmp = &pkt->icmp;
00301
00302   len = min (len, _mtu - sizeof(*ip));
00303   memcpy (icmp, req, len);
00304   icmp->echo.type = ICMP_ECHOREPLY;
00305   icmp->echo.code = req->echo.code; /* Win uses 0, Unix !0 */
00306
00307   /* Use supplied ip values in case we ever multi-home.
00308    * Note that ip values are still in network order.
00309    */
00310   return icmp_send (pkt, ip->destination, ip->source, len);
00311 }
00312
00316 static void icmp_redirect (const union ICMP_PKT *icmp, const in_Header *ip,
00317                            const in_Header *orig_ip, int code)
00318 {
00319   DWORD new_ip = intel (icmp->ip.ipaddr);
00320   DWORD old_ip = intel (orig_ip->destination);
00321   const char *msg;
00322
00323   if (new_ip == old_ip)
00324   {
00325     /* Possibly because we and router use different netmasks
00326      */
00327   }
00328   else if ((new_ip ^ my_ip_addr) & sin_mask) /* new host not on subnet */
00329   {
00330     char buf[100];
00331
00332     strcpy (buf, ", GW = ");
00333     strcat (buf, _inet_ntoa(NULL,new_ip));
00334     icmp_bogus (ip, ICMP_REDIRECT, buf);
00335     return;
00336   }
00337
00338   msg = icmp_redirect_str[code];
00339   icmp_print (1, msg, ip->source);
00340
00341   switch (orig_ip->proto)
00342   {
00343 #if !defined(USE_UDP_ONLY)
00344     case TCP_PROTO:
00345          if (do_redirect.tcp)  /* do it to some socket */
00346             _tcp_cancel (orig_ip, ICMP_REDIRECT, code, msg, &new_ip);
00347          break;
00348 #endif
00349     case UDP_PROTO:
00350          if (do_redirect.udp)
00351             _udp_cancel (orig_ip, ICMP_REDIRECT, code, msg, &new_ip);
00352          break;
00353
00354     case ICMP_PROTO:
00355          if (do_redirect.icmp)
00356          {
00357         /* _ip_recursion = TRUE; !! */
00358            _arp_register (new_ip, old_ip);
00359         /* _ip_recursion = FALSE; !! */
00360          }
00361          break;
00362
00363     case IGMP_PROTO:
00364          if (do_redirect.igmp)
00365          {
00366         /* _ip_recursion = TRUE; !! */
00367            _arp_register (new_ip, old_ip);
00368         /* _ip_recursion = FALSE; !! */
00369          }
00370          break;
00371   }
00372 }
00373
00377 void icmp_handler (const in_Header *ip, BOOL broadcast)
00378 {
00379   union ICMP_PKT  *icmp;
00380   const in_Header *orig_ip;
00381   int              type, code;
00382   unsigned         len;
00383   DWORD            delta_time;
00384   BOOL             for_me, i_orig;  /* is it for me, did I originate it */
00385   const char      *msg;
00386
00387   DEBUG_RX (NULL, ip);
00388
00389   if (block_icmp)   /* application is handling ICMP; not needed */
00390      return;
00391
00392   len    = in_GetHdrLen (ip);
00393   icmp   = (union ICMP_PKT*) ((BYTE*)ip + len);
00394   len    = intel16 (ip->length) - len;
00395   for_me = _ip4_is_multihome_addr (intel(ip->destination));
00396
00397   if (!for_me || broadcast)  /* drop broadcast pings.. */
00398      return;
00399
00400   if (len < sizeof(icmp->info))
00401   {
00402     STAT (icmpstats.icps_tooshort++);
00403     return;
00404   }
00405
00406   if (CHECKSUM(icmp,len) != 0xFFFF)
00407   {
00408     STAT (icmpstats.icps_checksum++);
00409     icmp_print (1, _LANG("bad checksum"), ip->source);
00410     return;
00411   }
00412
00413   type    = icmp->unused.type;
00414   code    = icmp->unused.code;
00415   orig_ip = &icmp->ip.ip;
00416   i_orig  = _ip4_is_local_addr (intel(orig_ip->source));
00417
00418   if (type == ICMP_MASKREPLY)
00419   {
00420     if (!_do_mask_req)
00421        return;
00422     i_orig = TRUE;
00423   }
00424
00425   /* !! this needs work
00426    */
00427   if (!i_orig &&
00428       (type != ICMP_ECHOREPLY && type != ICMP_ECHO &&
00429        type != ICMP_IREQREPLY && type != ICMP_TSTAMP))
00430   {
00431     icmp_bogus (ip, type, NULL);
00432     return;
00433   }
00434
00435   switch (type)
00436   {
00437     case ICMP_ECHOREPLY:  /* check if we were waiting for it */
00438          delta_time = set_timeout(0) - icmp->echo.identifier;
00439          add_ping (intel(ip->source), delta_time, icmp->echo.index);
00440          return;
00441
00442     case ICMP_UNREACH:
00443          if (code < DIM(icmp_unreach_str))
00444          {
00445            UINT len_needed = 8 + in_GetHdrLen (orig_ip);
00446            WORD next_mtu   = 0;
00447
00448            msg = _LANG (icmp_unreach_str[code]);
00449            icmp_print (1, msg, ip->source);
00450
00451            if (orig_ip->proto == TCP_PROTO ||
00452                orig_ip->proto == UDP_PROTO)
00453               len_needed += 4;  /* Need the src/dest port numbers */
00454
00455            if (len >= len_needed)
00456            {
00457              if (code == ICMP_UNREACH_NEEDFRAG)
00458                 next_mtu = intel16 (icmp->needfrag.next_mtu);
00459
00460 #if !defined(USE_UDP_ONLY)
00461              if (orig_ip->proto == TCP_PROTO)
00462                 _tcp_cancel (orig_ip, ICMP_UNREACH, code, msg, &next_mtu);
00463              else
00464 #endif
00465              if (orig_ip->proto == UDP_PROTO)
00466                 _udp_cancel (orig_ip, ICMP_UNREACH, code, msg, &next_mtu);
00467
00469 #if defined(USE_BSD_API) && 0
00470              else
00471               _raw_cancel (orig_ip, ICMP_UNREACH, code, msg);
00472 #endif
00473            }
00474            else
00475              STAT (icmpstats.icps_tooshort++);
00476          }
00477          else
00478            STAT (icmpstats.icps_badcode++);
00479          return;
00480
00481     case ICMP_SOURCEQUENCH:
00482 #if !defined(USE_UDP_ONLY)
00483          if (orig_ip->proto == TCP_PROTO)
00484          {
00485            msg = _LANG (icmp_type_str[type]);
00486            icmp_print (1, msg, ip->source);
00487            _tcp_cancel (orig_ip, ICMP_SOURCEQUENCH, code, msg, NULL);
00488          }
00489 #endif
00490          return;
00491
00492     case ICMP_REDIRECT:
00493          if (code < DIM(icmp_redirect_str))
00494               icmp_redirect (icmp, ip, orig_ip, code);
00495          else STAT (icmpstats.icps_badcode++);
00496          return;
00497
00498     case ICMP_ECHO:
00499          icmp_print (2, _LANG("PING requested of us"), ip->source);
00500          icmp_echo_reply (ip, icmp, len);
00501          return;
00502
00503     case ICMP_TIMXCEED:
00504          if (code >= DIM(icmp_exceed_str))
00505          {
00506            STAT (icmpstats.icps_badcode++);
00507            return;
00508          }
00509          if (code == 0)  /* "TTL exceeded in transit" */
00510             switch (orig_ip->proto)
00511             {
00512 #if !defined(USE_UDP_ONLY)
00513               case TCP_PROTO:
00514                    msg = _LANG (icmp_exceed_str[0]);
00515                    icmp_print (1, msg, ip->source);
00516                    _tcp_cancel (orig_ip, ICMP_TIMXCEED, code, msg, NULL);
00517                    break;
00518 #endif
00519               case UDP_PROTO:
00520                    msg = _LANG (icmp_exceed_str[0]);
00521                    icmp_print (1, msg, ip->source);
00522                    _udp_cancel (orig_ip, ICMP_TIMXCEED, code, msg, NULL);
00523                    break;
00524             }
00525          return;
00526
00527     case ICMP_PARAMPROB:
00528          msg = _LANG (icmp_type_str[ICMP_PARAMPROB]);
00529          switch (orig_ip->proto)
00530          {
00531 #if !defined(USE_UDP_ONLY)
00532            case TCP_PROTO:
00533                 icmp_print (0, msg, ip->source);
00534                 _tcp_cancel (orig_ip, ICMP_PARAMPROB, code, msg, NULL);
00535                 break;
00536 #endif
00537            case UDP_PROTO:
00538                 icmp_print (0, msg, ip->source);
00539                 _udp_cancel (orig_ip, ICMP_PARAMPROB, code, msg, NULL);
00540                 break;
00541          }
00542          return;
00543
00544     case ICMP_ROUTERADVERT:  /* todo !! */
00545          msg = _LANG (icmp_type_str[ICMP_ROUTERADVERT]);
00546          icmp_print (1, msg, ip->source);
00547          return;
00548
00549     case ICMP_ROUTERSOLICIT: /* todo !! */
00550          msg = _LANG (icmp_type_str[ICMP_ROUTERSOLICIT]);
00551          icmp_print (1, msg, ip->source);
00552          return;
00553
00554     case ICMP_TSTAMP:
00555          msg = _LANG (icmp_type_str[ICMP_TSTAMP]);
00556          icmp_print (1, msg, ip->source);
00558          return;
00559
00560     case ICMP_TSTAMPREPLY:
00561          msg = _LANG (icmp_type_str[ICMP_TSTAMPREPLY]);
00562          icmp_print (1, msg, ip->source);
00564          return;
00565
00566     case ICMP_IREQ:
00567          msg = _LANG (icmp_type_str[ICMP_IREQ]);
00568          icmp_print (1, msg, ip->source);
00570          return;
00571
00572     case ICMP_IREQREPLY:
00573          msg = _LANG (icmp_type_str[ICMP_IREQREPLY]);
00574          icmp_print (1, msg, ip->source);
00576          return;
00577
00578     case ICMP_MASKREQ:
00579          /* might be sent by us, never answer */
00580          break;
00581
00582     case ICMP_MASKREPLY:
00583          msg = _LANG (icmp_type_str[ICMP_MASKREPLY]);
00584          icmp_print (0, msg, ip->source);
00585          if ((icmp->mask.identifier == addr_mask_id)    &&
00586              (icmp->mask.sequence   == addr_mask_seq-1) &&
00587              sin_mask != intel(icmp->mask.mask))
00588             outsnl ("Conflicting net-mask from \"ICMP Addr Mask Reply\"\7");
00589          addr_mask_id = 0;
00590          return;
00591   }
00592 }
00593
00598 void icmp_doredirect (const char *value)
00599 {
00600   char *val = strdup (value);
00601
00602   if (val)
00603   {
00604     strupr (val);
00605     do_redirect.icmp = (strstr(val,"ICMP") != NULL);
00606     do_redirect.igmp = (strstr(val,"IGMP") != NULL);
00607     do_redirect.udp  = (strstr(val,"UDP")  != NULL);
00608     do_redirect.tcp  = (strstr(val,"TCP")  != NULL);
00609     free (val);
00610   }
00611 }
Generated on Wed Jan 25 15:42:37 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/PCICMP.H Source File

SRC/PCICMP.H

Go to the documentation of this file.
00001
00003 #ifndef _w32_PCICMP_H
00004 #define _w32_PCICMP_H
00005
00006 #include <sys/packon.h>
00007
00010 struct ICMP_unused {
00011        BYTE      type;
00012        BYTE      code;
00013        WORD      checksum;
00014        DWORD     unused;
00015        in_Header ip;
00016        BYTE      spares [8];
00017      };
00018
00021 struct ICMP_pointer {
00022        BYTE      type;
00023        BYTE      code;
00024        WORD      checksum;
00025        BYTE      pointer;
00026        BYTE      unused [3];
00027        in_Header ip;
00028      };
00029
00032 struct ICMP_ip {
00033        BYTE      type;
00034        BYTE      code;
00035        WORD      checksum;
00036        DWORD     ipaddr;         /* redirect gateway */
00037        in_Header ip;             /* original ip-header */
00038      };
00039
00042 struct ICMP_echo {
00043        BYTE      type;
00044        BYTE      code;
00045        WORD      checksum;
00046        WORD      identifier;
00047        WORD      sequence;
00048        DWORD     index;
00049      };
00050
00053 struct ICMP_timestamp {
00054        BYTE      type;
00055        BYTE      code;
00056        WORD      checksum;
00057        WORD      identifier;
00058        WORD      sequence;
00059        DWORD     original;       /* original timestamp */
00060        DWORD     receive;        /* receive timestamp  */
00061        DWORD     transmit;       /* transmit timestamp */
00062      };
00063
00066 struct ICMP_info {
00067        BYTE      type;
00068        BYTE      code;
00069        WORD      checksum;
00070        WORD      identifier;
00071        WORD      sequence;
00072      };
00073
00076 struct ICMP_addr_mask {
00077        BYTE      type;
00078        BYTE      code;
00079        WORD      checksum;
00080        WORD      identifier;
00081        WORD      sequence;
00082        DWORD     mask;
00083      };
00084
00087 struct ICMP_traceroute {
00088        BYTE      type;
00089        BYTE      code;
00090        WORD      checksum;
00091        WORD      identifier;
00092        WORD      unused;
00093        WORD      outbound_hop;
00094        WORD      return_hop;
00095        DWORD     link_speed;
00096        DWORD     link_mtu;
00097      };
00098
00099
00102 struct ICMP_needfrag {
00103        BYTE      type;
00104        BYTE      code;
00105        WORD      checksum;
00106        WORD      unused;   /* 32-bit 0 here for router that doesn't support RFC-1191 */
00107        WORD      next_mtu;
00108      };
00109
00112 typedef union ICMP_PKT {
00113         struct ICMP_unused     unused;
00114         struct ICMP_pointer    pointer;
00115         struct ICMP_ip         ip;
00116         struct ICMP_echo       echo;
00117         struct ICMP_timestamp  timestamp;
00118         struct ICMP_info       info;
00119         struct ICMP_addr_mask  mask;
00120         struct ICMP_traceroute tracert;
00121         struct ICMP_needfrag   needfrag;
00122       } ICMP_PKT;
00123
00127 struct ping_pkt {
00128        in_Header        in;
00129        struct ICMP_echo icmp;
00130     /* BYTE             data[]; */
00131      };
00132
00133 #include <sys/packoff.h>
00134
00135
00139 #define ICMP_ECHOREPLY     0
00140 #define ICMP_UNREACH       3
00141 #define ICMP_SOURCEQUENCH  4
00142 #define ICMP_REDIRECT      5
00143 #define ICMP_ECHO          8
00144 #define ICMP_ROUTERADVERT  9
00145 #define ICMP_ROUTERSOLICIT 10
00146 #define ICMP_TIMXCEED      11
00147 #define ICMP_PARAMPROB     12
00148 #define ICMP_TSTAMP        13
00149 #define ICMP_TSTAMPREPLY   14
00150 #define ICMP_IREQ          15
00151 #define ICMP_IREQREPLY     16
00152 #define ICMP_MASKREQ       17
00153 #define ICMP_MASKREPLY     18
00155 #ifndef ICMP_MAXTYPE
00156 #define ICMP_MAXTYPE 18
00157 #endif
00158
00159
00160 /*
00161  * ICMP_UNREACH codes. E.g. 'struct ICMP_unused::code'.
00162  */
00163 #define ICMP_UNREACH_NET                0
00164 #define ICMP_UNREACH_HOST               1
00165 #define ICMP_UNREACH_PROTOCOL           2
00166 #define ICMP_UNREACH_PORT               3
00167 #define ICMP_UNREACH_NEEDFRAG           4
00168 #define ICMP_UNREACH_SRCFAIL            5
00169 #define ICMP_UNREACH_NET_UNKNOWN        6
00170 #define ICMP_UNREACH_HOST_UNKNOWN       7
00171 #define ICMP_UNREACH_ISOLATED           8
00172 #define ICMP_UNREACH_NET_PROHIB         9
00173 #define ICMP_UNREACH_HOST_PROHIB        10
00174 #define ICMP_UNREACH_TOSNET             11
00175 #define ICMP_UNREACH_TOSHOST            12
00176 #define ICMP_UNREACH_FILTER_PROHIB      13
00177 #define ICMP_UNREACH_HOST_PRECEDENCE    14
00178 #define ICMP_UNREACH_PRECEDENCE_CUTOFF  15
00179
00180 W32_FUNC DWORD _chk_ping (DWORD host, DWORD *ping_num);
00181
00182 extern const char *icmp_type_str [ICMP_MAXTYPE+1];
00183 extern const char *icmp_unreach_str [16];
00184 extern const char *icmp_redirect_str [4];
00185 extern const char *icmp_exceed_str [2];
00186
00187 extern void  icmp_handler (const in_Header *ip, BOOL broadcast);
00188 extern void  icmp_doredirect (const char *value);
00189 extern int   icmp_send_timexceed (const in_Header *ip, const void *mac_dest);
00190 extern int   icmp_send_unreach (const in_Header *ip, int code);
00191 extern int   icmp_send_mask_req (void);
00192
00193 #endif
Generated on Wed Jan 25 15:42:37 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/PCICMP6.C Source File

SRC/PCICMP6.C

Go to the documentation of this file.
00001
00038 #include <stdio.h>
00039 #include <stdlib.h>
00040 #include <arpa/inet.h>
00041
00042 #include "wattcp.h"
00043 #include "misc.h"
00044 #include "timer.h"
00045 #include "chksum.h"
00046 #include "strings.h"
00047 #include "netaddr.h"
00048 #include "language.h"
00049 #include "ip6_in.h"
00050 #include "ip6_out.h"
00051 #include "ip4_out.h"
00052 #include "split.h"
00053 #include "pctcp.h"
00054 #include "pcsed.h"
00055 #include "pcstat.h"
00056 #include "pcdbug.h"
00057 #include "pcpkt.h"
00058 #include "pcarp.h"
00059 #include "pcconfig.h"
00060 #include "pcicmp6.h"
00061
00063 #if defined(USE_IPV6)
00064
00065 struct prefix_table {
00066        size_t      len;
00067        ip6_address prefix;
00068      };
00069
00070 struct prefix_table prefix_list [10];
00071 struct icmp6_cache  neighbor_cache [ND_CACHE_SIZE];
00072 struct icmp6_cache  destin_cache   [ND_CACHE_SIZE];
00073
00074 int         icmp6_prefix_len;
00075 ip6_address icmp6_prefix;
00076 DWORD       icmp6_6to4_gateway = 0;  /* host order */
00077
00078 #include <sys/packon.h>
00079
00080 struct _pkt {
00081        in6_Header  in;
00082        ICMP6_PKT   icmp;
00083        BYTE        options[1];
00084      };
00085
00086 #include <sys/packoff.h>
00087
00088 #if 0
00089 static const char *icmp6_options_str [] = {
00090                   "",
00091                   __LANG ("source link-layer addr"),
00092                   __LANG ("target link-layer addr"),
00093                   __LANG ("prefix information"),
00094                   __LANG ("redirected header"),
00095                   __LANG ("MTU")
00096           };
00097 #endif
00098
00099 static WORD route_lifetime;
00100
00101 static void icmp6_print (int dbg_lvl, const char *msg, const void *src);
00102 static int  icmp6_send  (in6_Header *ip, ICMP6_PKT *icmp, UINT len);
00103 static void router_advert (const union ICMP6_PKT *icmp, unsigned len);
00104 static int  neighbor_advert (const eth_address *eth);
00105 static void echo_reply (const in6_Header *ip, const union ICMP6_PKT *icmp);
00106
00107 /*
00108  * Make a Ethernet destination address from a (solicited node) ip-address.
00109  * From /etc/manuf: 33:33:0:0:0:0/16, IPv6 neighbor discovery.
00110  */
00111 static const void *icmp6_mac_addr (const void *ip_addr)
00112 {
00113   static mac_address mac;
00114   const  BYTE       *addr = (const BYTE*)ip_addr;
00115
00116   mac[0] = 0x33;
00117   mac[1] = 0x33;
00118   mac[2] = 0xFF;
00119   mac[3] = addr[13];
00120   mac[4] = addr[14];
00121   mac[5] = addr[15];
00122   return (&mac[0]);
00123 }
00124
00125 int icmp6_router_solicitation (void)
00126 {
00127   struct _pkt            *pkt;
00128   struct in6_Header      *ip;
00129   struct ICMP6_route_sol *icmp;
00130
00131   pkt  = (struct _pkt*) _eth_formatpacket (_eth_brdcast, IP6_TYPE);
00132   ip   = &pkt->in;
00133   icmp = &pkt->icmp.rsolic;
00134   icmp->type     = ND_ROUTER_SOLICIT;
00135   icmp->code     = 0;
00136   icmp->reserved = 0;
00137
00138   memcpy (&ip->source, &in6addr_my_ip, sizeof(ip->source));
00139   memcpy (&ip->destination, &in6addr_allr_mc, sizeof(ip->destination));
00140   return icmp6_send (ip, (ICMP6_PKT*)icmp, sizeof(*icmp));
00141 }
00142
00143 /*
00144  * Add the IPv4 'icmp6_6to4_gateway' address to the ND cache
00145  */
00146 BOOL icmp6_add_gateway4 (void)
00147 {
00148   struct icmp6_cache *ce = NULL;
00149   ip6_address         ip;
00150   mac_address         eth;
00151   BOOL                arp_ok;
00152
00153   arp_ok = _arp_resolve (icmp6_6to4_gateway, &eth);
00154   if (arp_ok)
00155   {
00156     memcpy (&ip, in6addr_mapped, sizeof(in6addr_mapped));
00157     *(DWORD*) &ip [12] = intel (icmp6_6to4_gateway);
00158     ce = icmp6_ncache_insert_fix (&ip, eth);
00159   }
00160   TCP_CONSOLE_MSG (1, ("Adding %s as 6-to-4 gateway, ARP %s, Insert %s\n",
00161                    _inet_ntoa(NULL,intel(icmp6_6to4_gateway)),
00162                    arp_ok ? "OK" : "failed",
00163                    ce     ? "OK" : "failed"));
00164   return (arp_ok && ce);
00165 }
00166
00167 /*
00168  * Perform an "ICMPv6 Neighbor Solicitation" on 'addr' to resolve it's
00169  * MAC address (the role of ARP in IPv4).
00170  */
00171 int icmp6_neigh_solic (const void *addr, eth_address *eth)
00172 {
00173   struct _pkt         *pkt;
00174   struct in6_Header   *ip;
00175   struct ICMP6_nd_sol *icmp;
00176   struct icmp6_cache  *cache;
00177   struct in6_addr      dest;
00178   BYTE  *options;
00179
00180   if (_ip6_is_local_addr(addr))
00181   {
00182     if (eth)
00183        memcpy (eth, _eth_addr, sizeof(*eth));
00184     return (1);
00185   }
00186
00187   cache = icmp6_ncache_lookup (addr);
00188   if (cache)
00189   {
00190     if (eth)
00191        memcpy (eth, &cache->eth, sizeof(*eth));
00192     return (1);
00193   }
00194
00195   pkt  = (struct _pkt*) _eth_formatpacket (icmp6_mac_addr(addr), IP6_TYPE);
00196   ip   = &pkt->in;
00197   icmp = &pkt->icmp.nd_solic;
00198   icmp->type     = ND_NEIGHBOR_SOLICIT;
00199   icmp->code     = 0;
00200   icmp->reserved = 0;
00201
00202   memcpy (&dest, &in6addr_alln_mc, sizeof(dest)); /* All nodes MC address */
00203   dest.s6_addr[11] ^= 1;             /* toggle G-bit */
00204   dest.s6_addr[12]  = 0xFF;
00205   dest.s6_addr[13]  = ((BYTE*)addr)[13];
00206   dest.s6_addr[14]  = ((BYTE*)addr)[14];
00207   dest.s6_addr[15]  = ((BYTE*)addr)[15];
00208
00209   memcpy (&icmp->target, addr, sizeof(icmp->target));
00210   memcpy (&ip->source, &in6addr_my_ip, sizeof(ip->source));
00211   memcpy (&ip->destination, &dest, sizeof(ip->destination));
00212
00213   /* Insert "src-mac address" option
00214    */
00215   options = (BYTE*) (icmp + 1);
00216   *options++ = ND_OPT_SOURCE_LINKADDR;
00217   *options++ = 1;   /* multiple of 8 bytes */
00218   memcpy (options, _eth_addr, sizeof(_eth_addr));
00219   options += sizeof(_eth_addr);
00220   *options++ = 0;   /* End option */
00221   *options++ = 0;
00222
00223   icmp6_send (ip, (ICMP6_PKT*)icmp, options - (BYTE*)icmp);
00224
00225 #if 0
00226   while (1)
00227   {
00228     eth = ..
00229   }
00230 #endif
00231
00232   icmp6_ncache_insert (addr, eth);
00233
00235   return (0);
00236 }
00237
00238 void icmp6_handler (const in6_Header *ip)
00239 {
00240   const struct pkt_split *pkt;
00241   const union  ICMP6_PKT *icmp;
00242   int          type, code;
00243   unsigned     len;
00244   BOOL         for_me;
00245
00246   DEBUG_RX (NULL, ip);
00247
00248   pkt    = pkt_get_type_in (TYPE_IP6_ICMP);
00249   icmp   = (const union ICMP6_PKT*) pkt->data;
00250   len    = pkt->len;
00251   for_me = !memcmp (ip->destination, &in6addr_my_ip, sizeof(ip->destination));
00252
00253   if (len < sizeof(icmp->unused))
00254   {
00255     STAT (icmp6stats.icp6s_tooshort++);
00256     return;
00257   }
00258
00259   if (!_ip6_icmp_checksum(ip,icmp,intel16(ip->len)))
00260   {
00261     STAT (icmp6stats.icp6s_checksum++);
00262     icmp6_print (1, _LANG("bad checksum"), ip->source);
00263     return;
00264   }
00265
00266   type = icmp->unused.type;
00267   code = icmp->unused.code;
00268
00269   switch (type)
00270   {
00271     case ICMP6_DST_UNREACH:
00272          break;
00273
00274     case ICMP6_PACKET_TOO_BIG:
00275          break;
00276
00277     case ICMP6_TIME_EXCEEDED:
00278          break;
00279
00280     case ICMP6_PARAM_PROB:
00281          break;
00282
00283     case ICMP6_ECHO_REQUEST:
00284          if (for_me)
00285          {
00286            icmp6_print (2, _LANG("PING6 requested of us"), ip->source);
00287            echo_reply (ip, icmp);
00288          }
00289          break;
00290
00291     case ICMP6_ECHO_REPLY:
00292          break;
00293
00294     case ICMP6_MEMBERSHIP_QUERY:
00295          break;
00296
00297     case ICMP6_MEMBERSHIP_REPORT:
00298          break;
00299
00300     case ICMP6_MEMBERSHIP_REDUCTION:
00301          break;
00302
00303     case ICMP6_ROUTER_RENUMBERING:
00304          break;
00305
00306     case ICMP6_WRUREQUEST:
00307          break;
00308
00309     case ICMP6_WRUREPLY:
00310          break;
00311
00312     case ND_ROUTER_SOLICIT:   /* silently discard */
00313          break;
00314
00315     case ND_ROUTER_ADVERT:
00316          if (IN6_IS_ADDR_LINKLOCAL(ip->source) && ip->hop_limit == 255)
00317             router_advert (icmp, len);
00318          break;
00319
00320     case ND_NEIGHBOR_SOLICIT:
00321          if (IN6_ARE_ADDR_EQUAL(icmp->nd_solic.target, &in6addr_my_ip))
00322             neighbor_advert ((const eth_address*)MAC_SRC(ip));
00323          break;
00324
00325     case ND_NEIGHBOR_ADVERT:
00326          break;
00327
00328     case ND_REDIRECT:
00329          break;
00330   }
00331 }
00332
00333 void icmp6_unreach (const in6_Header *ip, int code)
00334 {
00335   ARGSUSED (ip);
00336   ARGSUSED (code);
00337 }
00338
00339 struct icmp6_cache *icmp6_ncache_lookup (const void *ip)
00340 {
00341   struct icmp6_cache *entry = &neighbor_cache[0];
00342   time_t now = time (NULL);
00343   int    i;
00344
00345   for (i = 0; i < DIM(neighbor_cache); i++, entry++)
00346   {
00347 #if 0  /* !! test */
00348     printf ("%2d: ip '%s', entry '%s'\n",
00349             i, _inet6_ntoa(ip), _inet6_ntoa(entry->ip));
00350 #endif
00351
00352     if (entry->state != ND_CACHE_REACHABLE)
00353        continue;
00354
00355     if (entry->expiry && now >= entry->expiry)
00356     {
00357       entry->state  = ND_CACHE_UNUSED;
00358       entry->expiry = 0;
00359       continue;
00360     }
00361
00362 #if 0  /* test !! */
00363     if (*(DWORD*)&entry->ip[12] == intel(icmp6_6to4_gateway))
00364        return (entry);
00365 #endif
00366
00367     if (IN6_IS_ADDR_V4MAPPED(ip) &&
00368         *(DWORD*)&entry->ip[12] == intel(icmp6_6to4_gateway))
00369        return (entry);
00370
00371     if (IN6_ARE_ADDR_EQUAL(ip,entry->ip))
00372        return (entry);
00373   }
00374   return (NULL);
00375 }
00376
00377 struct icmp6_cache *icmp6_ncache_insert (const void *ip, const void *eth)
00378 {
00379   struct icmp6_cache *found = NULL;
00380   struct icmp6_cache *entry = &neighbor_cache[0];
00381   static WORD         index = 0;       /* rotates round-robin */
00382   int    i;
00383
00384   for (i = 0; i < DIM(neighbor_cache); i++, entry++)
00385   {
00386     if (entry->state == ND_CACHE_PROBE || IN6_IS_ADDR_UNSPECIFIED(entry->ip))
00387     {
00388       found = entry;
00389       break;
00390     }
00391   }
00392
00393   if (!found)   /* not found, grab a "random" slot */
00394   {
00395     index++;
00396     index %= DIM (neighbor_cache);
00397     found = &neighbor_cache [index];
00398   }
00399   memcpy (found->ip, ip, sizeof(found->ip));
00400   memcpy (found->eth, eth, sizeof(found->eth));
00401   found->state  = ND_CACHE_INCOMPLETE;
00402   found->expiry = time (NULL);
00403   return (found);
00404 }
00405
00406 struct icmp6_cache *icmp6_ncache_insert_fix (const void *ip, const void *eth)
00407 {
00408   struct icmp6_cache *ce = icmp6_ncache_insert (ip, eth);
00409
00410   if (ce)
00411   {
00412     ce->state  = ND_CACHE_REACHABLE; /* always reachable */
00413     ce->expiry = 0;                  /* never expire */
00414   }
00415   return (ce);
00416 }
00417
00418 static void icmp6_print (int dbg_lvl, const char *msg, const void *src)
00419 {
00420   if (debug_on < dbg_lvl)
00421      return;
00422
00423   outs ("\nICMP6: ");
00424   if (src)
00425   {
00426     const char *addr = _inet6_ntoa (src);
00427     outs ("(");
00428     outs (addr ? addr : "(null?)");
00429     outs ("): ");
00430   }
00431   outsnl (_LANG(msg));
00432 }
00433
00434 static int icmp6_send (in6_Header *ip, ICMP6_PKT *icmp, UINT len)
00435 {
00436   icmp->unused.checksum = 0;
00437   icmp->unused.checksum = _ip6_checksum (ip, IP6_NEXT_ICMP, icmp, len);
00438   return IP6_OUTPUT (ip, &ip->source, &ip->destination, IP6_NEXT_ICMP,
00439                      len, 0, NULL);
00440 }
00441
00442 static void parse_options (const BYTE *opt, unsigned max)
00443 {
00444   const BYTE *start = opt;
00445
00446   while (opt < start + max)
00447   {
00448     const struct nd_opt_prefix_info *pi = (const struct nd_opt_prefix_info*) opt;
00449     BYTE  type = opt[0];
00450     int   len  = opt[1] << 3;
00451
00452     switch (type)
00453     {
00454       case ND_OPT_PREFIX_INFORMATION:
00455            if (pi->nd_opt_pi_len == 4)
00456            {
00457              icmp6_prefix_len = pi->nd_opt_pi_prefix_len;
00458              memcpy (&icmp6_prefix, &pi->nd_opt_pi_prefix, sizeof(icmp6_prefix));
00459            }
00460            break;
00461       case ND_OPT_SOURCE_LINKADDR:
00462       case ND_OPT_TARGET_LINKADDR:
00463       case ND_OPT_REDIRECTED_HEADER:
00464       case ND_OPT_MTU:
00465       case 0:          /* EOL */
00466            break;
00467       default:
00468            icmp6_print (1, _LANG("Illegal option"), NULL);
00469            break;
00470     }
00471     opt += len;
00472   }
00473 }
00474
00475 static void router_advert (const union ICMP6_PKT *icmp, unsigned len)
00476 {
00477   if (icmp->radvert.hop_limit)
00478      _default6_ttl = icmp->radvert.hop_limit;
00479   if (icmp->radvert.lifetime)
00480      route_lifetime = intel16 (icmp->radvert.lifetime);
00481   if (len > sizeof(icmp->radvert))
00482      parse_options ((const BYTE*)icmp + sizeof(icmp->radvert),
00483                     len - sizeof(icmp->radvert));
00484 }
00485
00486 static int neighbor_advert (const eth_address *eth)
00487 {
00488   struct _pkt         *pkt;
00489   struct in6_Header   *ip;
00490   struct ICMP6_nd_adv *icmp;
00491
00492   pkt  = (struct _pkt*) _eth_formatpacket (eth, IP6_TYPE);
00493   ip   = &pkt->in;
00494   icmp = &pkt->icmp.nd_adv;
00495   icmp->type      = ND_NEIGHBOR_ADVERT;
00496   icmp->code      = 0;
00497   icmp->reserved1 = 0;
00498   icmp->reserved2 = 0;
00499   icmp->reserved3 = 0;
00500   icmp->router    = 0;
00501   icmp->solicited = 1;
00502   icmp->override  = 1;
00503
00504   memcpy (&icmp->target, &in6addr_my_ip, sizeof(icmp->target));
00505   memcpy (&ip->source, &in6addr_my_ip, sizeof(ip->source));
00506   memcpy (&ip->destination, &in6addr_allr_mc, sizeof(ip->destination));
00507   return icmp6_send (ip, (ICMP6_PKT*)icmp, sizeof(*icmp));
00508 }
00509
00510 static void echo_reply (const in6_Header      *orig_ip,
00511                         const union ICMP6_PKT *orig_icmp)
00512 {
00513   struct _pkt       *pkt;
00514   struct in6_Header *ip;
00515   union  ICMP6_PKT  *icmp;
00516   WORD   len = intel16 (orig_ip->len);
00517
00518   pkt  = (struct _pkt*) _eth_formatpacket (MAC_SRC(orig_ip), IP6_TYPE);
00519   ip   = &pkt->in;
00520   icmp = &pkt->icmp;
00521
00522   /* Don't let a huge reassembled ICMP-packet kill us.
00523    */
00524   len = min (len, _mtu - sizeof(*ip));
00525   memcpy (icmp, orig_icmp, len);
00526   icmp->echo.type = ICMP6_ECHO_REPLY;
00527   icmp->echo.code = orig_icmp->echo.code;
00528
00529   /* Use supplied ip values in case we ever multi-home.
00530    * Note that ip values are still in network order.
00531    */
00532   memcpy (&ip->source, &in6addr_my_ip, sizeof(ip->source));
00533   memcpy (&ip->destination, &orig_ip->source, sizeof(ip->destination));
00534   ip->hop_limit = orig_ip->hop_limit;
00535
00536   icmp6_print (2, _LANG("PING reply sent"), NULL);
00537   icmp6_send (ip, (ICMP6_PKT*)icmp, len);
00538 }
00539 #endif   /* USE_IPV6 */
00540
Generated on Wed Jan 25 15:42:37 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/PCICMP6.H Source File

SRC/PCICMP6.H

Go to the documentation of this file.
00001
00003 #ifndef _w32_PCICMP6_H
00004 #define _w32_PCICMP6_H
00005
00006 #include <sys/packon.h>
00007
00010 struct ICMP6_unused {
00011        BYTE        type;
00012        BYTE        code;
00013        WORD        checksum;
00014        DWORD       unused;
00015      };
00016
00019 struct ICMP6_route_sol {
00020        BYTE        type;
00021        BYTE        code;
00022        WORD        checksum;
00023        DWORD       reserved;
00024      };
00025
00028 struct ICMP6_route_adv {
00029        BYTE        type;
00030        BYTE        code;
00031        WORD        checksum;
00032        BYTE        hop_limit;
00033        BYTE        reserved : 6;
00034        BYTE        other    : 1;
00035        BYTE        managed  : 1;
00036        WORD        lifetime;
00037        DWORD       reach_time;
00038        DWORD       retrans_time;
00039      };
00040
00043 struct ICMP6_pointer {
00044        BYTE        type;
00045        BYTE        code;
00046        WORD        checksum;
00047        DWORD       pointer;
00048      };
00049
00052 struct ICMP6_MTU {
00053        BYTE        type;
00054        BYTE        code;
00055        WORD        checksum;
00056        DWORD       MTU;
00057      };
00058
00061 struct ICMP6_echo {
00062        BYTE        type;
00063        BYTE        code;
00064        WORD        checksum;
00065        WORD        identifier;
00066        WORD        sequence;
00067      };
00068
00071 struct ICMP6_nd_adv {
00072        BYTE        type;
00073        BYTE        code;
00074        WORD        checksum;
00075        BYTE        reserved1 : 5;
00076        BYTE        override  : 1;
00077        BYTE        solicited : 1;
00078        BYTE        router    : 1;
00079        BYTE        reserved2;
00080        WORD        reserved3;
00081        ip6_address target;
00082      };
00083
00086 struct ICMP6_nd_ra {
00087        BYTE        type;
00088        BYTE        code;
00089        WORD        checksum;
00090        BYTE        hop_limit;
00091        BYTE        reserved : 6;
00092        BYTE        other    : 1;
00093        BYTE        managed  : 1;
00094        WORD        lifetime;
00095      };
00096
00099 struct ICMP6_nd_sol {
00100        BYTE        type;
00101        BYTE        code;
00102        WORD        checksum;
00103        DWORD       reserved;
00104        ip6_address target;
00105      };
00106
00109 typedef union ICMP6_PKT {
00110         struct ICMP6_unused    unused;
00111         struct ICMP6_route_sol rsolic;
00112         struct ICMP6_route_adv radvert;
00113         struct ICMP6_pointer   pointer;
00114         struct ICMP6_MTU       MTU;
00115         struct ICMP6_echo      echo;
00116         struct ICMP6_nd_adv    nd_adv;
00117         struct ICMP6_nd_ra     nd_ra;
00118         struct ICMP6_nd_sol    nd_solic;
00119       } ICMP6_PKT;
00120
00121 #include <sys/packoff.h>
00122
00123 enum ND_cacheState {
00124      ND_CACHE_UNUSED,      /* entry not used */
00125      ND_CACHE_INCOMPLETE,  /* lookup incomplete */
00126      ND_CACHE_REACHABLE,   /* responds to ND solitations */
00127      ND_CACHE_PROBE,       /* ?? */
00128      ND_CACHE_MAX
00129    };
00130
00131 struct icmp6_cache {
00132        ip6_address        ip;
00133        eth_address        eth;
00134        WORD               flags;
00135        enum ND_cacheState state;
00136        time_t             expiry;
00137      };
00138
00139 #define ND_CACHE_SIZE 10
00140
00141 W32_DATA DWORD icmp6_6to4_gateway;
00142
00143 extern void icmp6_handler (const in6_Header *ip);
00144 extern void icmp6_unreach (const in6_Header *ip, int code);
00145
00146 extern int  icmp6_neigh_solic (const void *addr, eth_address *eth);
00147 extern int  icmp6_neighbor_advert (const eth_address *eth);
00148 extern int  icmp6_router_solicitation (void);
00149 extern BOOL icmp6_add_gateway4 (void);
00150
00151 struct icmp6_cache *icmp6_ncache_lookup (const void *ip);
00152 struct icmp6_cache *icmp6_ncache_insert (const void *ip, const void *eth);
00153 struct icmp6_cache *icmp6_ncache_insert_fix (const void *ip, const void *eth);
00154
00155 #endif
00156
Generated on Wed Jan 25 15:42:37 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/PCINTR.C Source File

SRC/PCINTR.C

Go to the documentation of this file.
00001
00015 #include <stdio.h>
00016 #include <stdlib.h>
00017 #include <signal.h>
00018
00019 #include "wattcp.h"
00020 #include "strings.h"
00021 #include "language.h"
00022 #include "misc.h"
00023 #include "pctcp.h"
00024 #include "wdpmi.h"
00025 #include "x32vm.h"
00026 #include "powerpak.h"
00027
00028 #if (DOSX & DJGPP)
00029   #include <sys/time.h>
00030 #elif (DOSX & PHARLAP)
00031   #include <mw/exc.h>  /* _dx_alloc_rmode_wrapper_iret() */
00032 #endif
00033
00034 #if !defined(WIN32)
00035
00036 #define TIMER_INTR  0x08
00037 #define STK_SIZE    1024
00038
00039 void (*wintr_chain)(void) = NULL;
00040
00041 static BOOL on_isr8;
00042
00043 #if !(DOSX & POWERPAK)
00044   static BOOL inside_isr8 = FALSE;
00045   static WORD indos_flag_seg, indos_flag_ofs;
00046   static WORD crit_err_seg, crit_err_ofs;   /* only for DOS 3.1+ */
00047
00048   static void find_DOS_flags (void);
00049   static BOOL DOS_is_idle (void);
00050 #endif
00051
00052 #if (DOSX & DJGPP)
00053   static void (*old_sigalrm) (int);
00054
00055 #elif !(DOSX & (PHARLAP|X32VM|POWERPAK))
00056   static UINT locstack [STK_SIZE];
00057
00058   static void stack_probe (void)
00059   {
00060 #if defined(USE_DEBUG)
00061     int   used;
00062     UINT *p;
00063
00064     for (p = locstack, used = 0; *p && used < DIM(locstack); p++)
00065         used++;
00066     if (used >= DIM(locstack))
00067     {
00068       (*_printf) ("pcintr.c: Stack overflow. Increase STK_SIZE\n");
00069       fflush (stdout);
00070       exit (-1);
00071     }
00072 #endif
00073   }
00074 #endif
00075
00076 BOOL wintr_enable (void)
00077 {
00078   BOOL old = on_isr8;
00079   on_isr8 = TRUE;
00080   return (old);
00081 }
00082
00083 void wintr_disable (void)
00084 {
00085   on_isr8 = FALSE;
00086 }
00087
00088 #if (DOSX & (PHARLAP|X32VM))
00089   static REALPTR oldint, timer_cb;
00090   static RMC_BLK rmRegs;
00091
00092   static void NewTimer (void)
00093   {
00094     _dx_call_real (oldint, &rmRegs, 1);
00095
00096     if (!inside_isr8)
00097     {
00098       inside_isr8 = TRUE;
00099       if (on_isr8 && DOS_is_idle())
00100       {
00101         if (wintr_chain)
00102           (*wintr_chain)();
00103         tcp_tick (NULL);
00104       }
00105       inside_isr8 = FALSE;
00106     }
00107   }
00108
00109   void wintr_shutdown (void)
00110   {
00111     if (oldint)
00112     {
00113       _dx_rmiv_set (TIMER_INTR, oldint);
00114       _dx_free_rmode_wrapper (timer_cb);
00115       oldint = 0;
00116     }
00117   }
00118
00119   void wintr_init (void)
00120   {
00121     timer_cb = _dx_alloc_rmode_wrapper_iret ((pmodeHook)NewTimer, 80000);
00122     if (!timer_cb)
00123     {
00124       outsnl (_LANG("Cannot allocate real-mode timer callback"));
00125       exit (1);
00126     }
00127     find_DOS_flags();
00128     _dx_rmiv_get (TIMER_INTR, &oldint);
00129     _dx_rmiv_set (TIMER_INTR, timer_cb);
00130     RUNDOWN_ADD (wintr_shutdown, -1); /* call it very early */
00131   }
00132
00133 #elif (DOSX & DJGPP)
00134   static void NewTimer (int sig)
00135   {
00136     if (!inside_isr8)
00137     {
00138       inside_isr8 = TRUE;
00139       if (old_sigalrm)
00140         (*old_sigalrm) (sig);
00141       if (on_isr8 && DOS_is_idle())
00142       {
00143         if (wintr_chain)
00144           (*wintr_chain)();
00145         tcp_tick (NULL);
00146       }
00147       inside_isr8 = FALSE;
00148     }
00149   }
00150
00151   void wintr_shutdown (void)
00152   {
00153     struct itimerval tim;
00154
00155     tim.it_interval.tv_sec  = 0;
00156     tim.it_interval.tv_usec = 0;
00157     signal (SIGALRM, old_sigalrm);
00158     setitimer (ITIMER_REAL, &tim, NULL);
00159   }
00160
00161   void wintr_init (void)
00162   {
00163     struct itimerval tim;
00164
00165     find_DOS_flags();
00166     tim.it_interval.tv_usec = 54945;  /* 1000000/18.2 */
00167     tim.it_interval.tv_sec  = 0;
00168     tim.it_value = tim.it_interval;
00169     old_sigalrm = signal (SIGALRM, NewTimer);
00170     setitimer (ITIMER_REAL, &tim, NULL);
00171   }
00172
00173 #elif defined (WATCOM386) && (DOSX & DOS4GW)
00174   static void (__interrupt __far *oldint)();
00175
00176   static void __interrupt __far NewTimer (void)
00177   {
00178     if (!inside_isr8)
00179     {
00180       inside_isr8 = TRUE;
00181       if (on_isr8 && DOS_is_idle())
00182       {
00183         DISABLE();
00184         STACK_SET (&locstack[STK_SIZE-1]);
00185
00186         if (wintr_chain)
00187           (*wintr_chain)();
00188         tcp_tick (NULL);
00189
00190         STACK_RESTORE();
00191         ENABLE();
00192         stack_probe();
00193       }
00194       inside_isr8 = FALSE;
00195     }
00196     _chain_intr (oldint);
00197   }
00198
00199   void wintr_shutdown (void)
00200   {
00201     if (oldint)
00202     {
00203       _dos_setvect (TIMER_INTR, oldint);
00204       oldint = NULL;
00205     }
00206   }
00207
00208   void wintr_init (void)
00209   {
00210     find_DOS_flags();
00211     oldint = _dos_getvect (TIMER_INTR);
00212     _dos_setvect (TIMER_INTR, NewTimer);
00213     memset (&locstack, 0, sizeof(locstack));
00214     RUNDOWN_ADD (wintr_shutdown, -1);
00215   }
00216
00217 #elif (DOSX & POWERPAK) && defined(NOT_YET)
00218   static struct {
00219          DWORD  offset;
00220          WORD   selector;
00221        } oldint;
00222
00223   static WORD our_ds;
00224
00225   void NewTimerPre (void);
00226
00227   static void NewTimer (void)
00228   {
00229     __asm {
00230       push es
00231       push ds
00232       mov  ds, cs:[our_ds]
00233       mov  es, cs:[our_ds]
00234     }
00235
00236     if (!inside_isr8)
00237     {
00238       inside_isr8 = TRUE;
00239       if (on_isr8 && DOS_is_idle())
00240       {
00241         DISABLE();
00242         STACK_SET (offset locstack[STK_SIZE-1]);
00243
00244         if (wintr_chain)
00245           (*wintr_chain)();
00246         tcp_tick (NULL);
00247
00248         STACK_RESTORE();
00249         ENABLE();
00250         stack_probe();
00251       }
00252       inside_isr8 = FALSE;
00253     }
00254     dpmi_chain_intr (oldint.selector, oldint.offset);
00255   }
00256
00257   void wintr_shutdown (void)
00258   {
00259     if (oldint.selector)
00260     {
00261       dpmi_setvect (TIMER_INTR, oldint.selector, oldint.offset);
00262       oldint.selector = NULL;
00263     }
00264   }
00265
00266   void wintr_init (void)
00267   {
00268     find_DOS_flags();
00269     our_ds = _DS;
00270     dpmi_getvect (TIMER_INTR, &oldint.selector, &oldint.offset);
00271     dpmi_setvect (TIMER_INTR, _CS, (DWORD)NewTimer);
00272     memset (&locstack, 0, sizeof(locstack));
00273     RUNDOWN_ADD (wintr_shutdown, -1);
00274   }
00275
00276 #elif (DOSX == 0) && !defined(NO_INLINE_ASM)
00277
00278   static W32_IntrHandler oldint;
00279
00280   static INTR_PROTOTYPE NewTimer (void)
00281   {
00282     (*oldint)();    /* chain now */
00283
00284     if (!inside_isr8)
00285     {
00286       inside_isr8 = TRUE;
00287
00288       if (on_isr8 && DOS_is_idle())
00289       {
00290   #ifdef __WATCOMC__
00291         DISABLE();
00292         STACK_SET (&locstack[STK_SIZE-1]);
00293   #else
00294         static UINT old_SP;
00295         static WORD old_SS;
00296         asm  pushf
00297         asm  cli
00298         asm  mov ax, ss
00299         asm  mov old_SS, ax
00300         asm  mov ax, sp
00301         asm  mov old_SP, ax
00302         asm  mov ax, ds
00303         asm  mov ss, ax
00304         asm  lea sp, locstack[STK_SIZE-1]
00305   #endif
00306         ENABLE();
00307
00308         if (wintr_chain)
00309           (*wintr_chain)();
00310         tcp_tick (NULL);
00311
00312         DISABLE();
00313   #ifdef __WATCOMC__
00314         STACK_RESTORE();
00315   #else
00316         asm  mov ax,old_SS
00317         asm  mov ss,ax
00318         asm  mov ax,old_SP
00319         asm  mov sp,ax
00320   #endif
00321         ENABLE();
00322         stack_probe();
00323       }
00324       inside_isr8 = FALSE;
00325     }
00326   }
00327
00328   void wintr_shutdown (void)
00329   {
00330     if (oldint)
00331     {
00332       setvect (TIMER_INTR, oldint);
00333       oldint = NULL;
00334     }
00335   }
00336
00337   void wintr_init (void)
00338   {
00339     find_DOS_flags();
00340     oldint = getvect (TIMER_INTR);
00341     setvect (TIMER_INTR, NewTimer);
00342     memset (&locstack, 0, sizeof(locstack));
00343     RUNDOWN_ADD (wintr_shutdown, -1);
00344   }
00345 #endif
00346
00347 #if !(DOSX & POWERPAK)
00348 static void find_DOS_flags (void)
00349 {
00350   IREGS regs;
00351
00352   memset (&regs, 0, sizeof(regs));
00353   regs.r_ax = 0x3400;
00354
00355   GEN_INTERRUPT (0x21, &regs);
00356   indos_flag_seg = regs.r_es;
00357   indos_flag_ofs = regs.r_bx;
00358   if (_watt_os_ver >= 0x0301)
00359   {
00360     crit_err_seg = regs.r_es;
00361     crit_err_ofs = regs.r_bx - 1;
00362   }
00363 }
00364
00365 static BOOL DOS_is_idle (void)
00366 {
00367   BYTE indos, crit = 0;
00368
00369   indos = PEEKB (indos_flag_seg, indos_flag_ofs);
00370   if (_watt_os_ver >= 0x0301)
00371      crit = PEEKB (crit_err_seg, crit_err_ofs);
00372   return (crit == 0 && indos == 0);
00373 }
00374 #endif
00375 #endif
00376
Generated on Wed Jan 25 15:42:37 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/PCMULTI.C Source File

SRC/PCMULTI.C

Go to the documentation of this file.
00001
00017 #include <stdio.h>
00018
00019 #include "copyrigh.h"
00020 #include "wattcp.h"
00021 #include "misc.h"
00022 #include "timer.h"
00023 #include "chksum.h"
00024 #include "strings.h"
00025 #include "ip4_in.h"
00026 #include "ip4_out.h"
00027 #include "netaddr.h"
00028 #include "pcconfig.h"
00029 #include "pcpkt.h"
00030 #include "pcsed.h"
00031 #include "pctcp.h"
00032 #include "pcdbug.h"
00033 #include "pcstat.h"
00034 #include "pcmulti.h"
00035
00036 /*
00037  * Application must set this to non-zero before calling watt_sock_init().
00038  * Not needed if using the BSD-socket API. Set for mcast options in
00039  * setsockopt().
00040  */
00041 int _multicast_on = 0;
00042 int _multicast_intvl = 0;   /* Report every x sec when idling */
00043
00044 #if defined(USE_MULTICAST)
00045
00046 #include <sys/packon.h>
00047
00048 struct IGMP_PKT {
00049        in_Header   in;
00050        IGMP_packet igmp;
00051      };
00052
00053 #include <sys/packoff.h>
00054
00055 #define ETH_MULTI     0x01005EUL
00056 #define CLASS_D_MASK  0xE0000000UL
00057 #define IPMULTI_MASK  0x007FFFFFUL
00059 static struct MultiCast mcast_list [IPMULTI_SIZE];
00060 static BOOL             daemon_on = FALSE;
00061
00062 static void check_mcast_reports (void);
00063
00064 /*
00065  * Check the LSB bit 0 of ether destination address.
00066  */
00067 static __inline BOOL is_eth_multicast (const in_Header *ip)
00068 {
00069   const BYTE *eth_dst;
00070
00071   /* How could this happen? Assume yes anyway
00072    */
00073   if (_pktdevclass != PDCLASS_ETHER)
00074      return (TRUE);
00075   eth_dst = (const BYTE*) MAC_DST (ip);
00076   return (eth_dst[0] & 1);  /* LSB=1 is mcast */
00077 }
00078
00079 /*
00080  * Calculates the proper ethernet address for a given
00081  * IP Multicast address.
00082  *
00083  * Where:
00084  *   ip:  IP address to be converted
00085  *   eth: pointer to ethernet MAC address
00086  */
00087 int multi_to_eth (DWORD ip, eth_address *mac)
00088 {
00089   DWORD top = ETH_MULTI;
00090   BYTE *eth = (BYTE*)mac;
00091
00092   ip &= IPMULTI_MASK;
00093   eth[0] = (BYTE) (top >> 16);
00094   eth[1] = (BYTE) ((top >> 8) & 0xFF);
00095   eth[2] = (BYTE) (top & 0xFF);
00096   eth[3] = (BYTE) (ip >> 16);
00097   eth[4] = (BYTE) ((ip >> 8) & 0xFF);
00098   eth[5] = (BYTE) (ip & 0xFF);
00099   return (1);
00100 }
00101
00102 /*
00103  * Joins a multicast group
00104  *
00105  * Where:
00106  *   ip - address of the group to be joined (host order)
00107  * Returns:
00108  *   1 - if the group was joined successfully
00109  *   0 - if attempt failed
00110  */
00111 int join_mcast_group (DWORD ip)
00112 {
00113   struct MultiCast *mc;
00114   int    i;
00115
00116   if (!_multicast_on)
00117      return (0);
00118
00119   /* first verify that it's a valid mcast address
00120    */
00121   if (!_ip4_is_multicast(ip))
00122   {
00123     TCP_CONSOLE_MSG (1, ("%s isn't a multicast address\n",
00124                      _inet_ntoa(NULL,ip)));
00125     return (0);
00126   }
00127
00128   if (!daemon_on)
00129      addwattcpd (check_mcast_reports);
00130   daemon_on = TRUE;
00131
00132   /* Determine if the group has already been joined.
00133    * As well as what the first free slot is.
00134    */
00135   for (i = 0, mc = mcast_list; i < DIM(mcast_list); i++, mc++)
00136   {
00137     if (mc->active && mc->ip == ip)
00138     {
00139       if (mc->processes < 255)
00140           mc->processes++;
00141       return (1);
00142     }
00143     if (!mc->active)
00144        break;
00145   }
00146
00147   /* alas, no...we need to join it
00148    */
00149   if (i >= DIM(mcast_list))     /* out of slots! */
00150      return (0);
00151
00152   /* Fill in the hardware address
00153    */
00154   multi_to_eth (ip, &mc->ethaddr);
00155
00156   if (!_eth_join_mcast_group(mc))
00157      return (0);
00158
00159   mc->active      = TRUE;
00160   mc->ip          = ip;
00161   mc->reply_timer = set_timeout (0); /* report ASAP */
00162   mc->processes   = 1;
00163   return (1);
00164 }
00165
00166 /*
00167  * Leaves a multicast group
00168  *
00169  * Where:
00170  *   ip - address of the group to be joined
00171  * Returns:
00172  *   1 - if the group was left successfully
00173  *   0 - if attempt failed
00174  */
00175 int leave_mcast_group (DWORD ip)
00176 {
00177   struct MultiCast *mc;
00178   int    i, rc, num_total = 0;
00179
00180   if (!_multicast_on)
00181      return (0);
00182
00183   /* first verify that it's a valid mcast address
00184    */
00185   if (!_ip4_is_multicast(ip))
00186   {
00187     TCP_CONSOLE_MSG (1, ("%s isn't a multicast address\n",
00188                      _inet_ntoa(NULL,ip)));
00189     return (0);
00190   }
00191
00192   /* Determine if the group has more than one interested
00193    * process. If so, then just decrement ref-count and return
00194    */
00195   for (i = 0, mc = mcast_list; i < DIM(mcast_list); i++, mc++)
00196   {
00197     if (!mc->active)
00198        continue;
00199
00200     num_total++;
00201     if (mc->ip != ip)
00202        continue;
00203
00204     if (mc->processes > 1)
00205     {
00206       mc->processes--;
00207       return (1);
00208     }
00209     break;
00210   }
00211
00212   /* did the IP-addr they gave match anything in mcast_list ??
00213    */
00214   if (i >= DIM(mcast_list))
00215      return (0);
00216
00217   /* alas...we need to physically leave it
00218    */
00219   rc = _eth_leave_mcast_group (mc);
00220   mc->active = FALSE;
00221
00222   /* Remove daemon if no longer needed
00223    */
00224   if (num_total <= 1)
00225   {
00226     daemon_on = FALSE;
00227     delwattcpd (check_mcast_reports);
00228   }
00229   return (rc);
00230 }
00231
00232 /*
00233  * Count number of active multicast groups
00234  */
00235 int num_multicast_active (void)
00236 {
00237   int i, num = 0;
00238
00239   for (i = 0; i < DIM(mcast_list); i++)
00240       if (mcast_list[i].active)
00241          num++;
00242   return (num);
00243 }
00244
00245 /*
00246  * Handles the incoming IGMP packets
00247  *
00248  * Where:
00249  *   ip - the IP packet in question
00250  */
00251 void igmp_handler (const in_Header *ip, BOOL broadcast)
00252 {
00253   BYTE  i;
00254   DWORD src_ip, host;
00255   BOOL  found = FALSE;
00256   WORD  len   = in_GetHdrLen (ip);
00257   const IGMP_packet *igmp = (const IGMP_packet*) ((BYTE*)ip + len);
00258   struct MultiCast  *mc;
00259
00260   DEBUG_RX (NULL, ip);
00261
00262   len = intel16 (ip->length) - len;
00263   if (len < sizeof(*igmp))
00264   {
00265     STAT (igmpstats.igps_rcv_tooshort++);
00266     return;
00267   }
00268
00269   if (CHECKSUM(igmp,sizeof(*igmp)) != 0xFFFF)
00270   {
00271     STAT (igmpstats.igps_rcv_badsum++);
00272     return;
00273   }
00274
00275   if (igmp->version != IGMP_VERSION)  /* We only speak v1 */
00276      return;
00277
00278   host   = intel (igmp->address);
00279   src_ip = intel (ip->source);
00280
00281   /* drop our own looped packets
00282    */
00283   if (_ip4_is_local_addr(src_ip))
00284      return;
00285
00286   /* Determine whether this is a report or a query
00287    */
00288   switch (igmp->type)
00289   {
00290     case IGMPv1_QUERY:
00291          STAT (igmpstats.igps_rcv_queries++);
00292          for (i = 0, mc = mcast_list; i < DIM(mcast_list); i++, mc++)
00293              if (mc->active && mc->reply_timer == 0UL &&
00294                  mc->ip != MCAST_ALL_SYST)
00295              {
00296                mc->reply_timer = set_timeout (Random(500,1000));
00297                found = TRUE;
00298              }
00299          if (!found && !broadcast && !is_eth_multicast(ip))
00300             STAT (igmpstats.igps_rcv_badqueries++);
00301          break;
00302
00303     case IGMPv1_REPORT:
00304          STAT (igmpstats.igps_rcv_reports++);
00305          for (i = 0, mc = mcast_list; i < DIM(mcast_list); i++, mc++)
00306              if (mc->active && mc->ip == host &&
00307                  host != MCAST_ALL_SYST)
00308              {
00309                mc->reply_timer = 0UL;
00310                found = TRUE;
00311                STAT (igmpstats.igps_rcv_ourreports++);
00312                break;
00313              }
00314          if (!found && !broadcast && !is_eth_multicast(ip))
00315             STAT (igmpstats.igps_rcv_badreports++);
00316          break;
00317   }
00318 }
00319
00320 /*
00321  * Send a IGMP Report packet
00322  *
00323  * Where:
00324  *   ip is the IP address to report (on host order).
00325  *
00326  * Returns:
00327  *   0 - if unable to send report
00328  *   1 - report was sent successfully
00329  */
00330 static int igmp_report (DWORD ip)
00331 {
00332   struct IGMP_PKT *pkt;
00333   IGMP_packet     *igmp;
00334   eth_address      eth;
00335
00336   /* get the ethernet addr of the destination
00337    */
00338   multi_to_eth (MCAST_ALL_SYST, &eth);
00339
00340   /* format the packet with the request's hardware address
00341    */
00342   pkt  = (struct IGMP_PKT*) _eth_formatpacket (eth, IP4_TYPE);
00343   igmp = &pkt->igmp;
00344   ip   = intel (ip);
00345
00346   /* fill in the igmp packet
00347    */
00348   igmp->type     = IGMPv1_REPORT;
00349   igmp->version  = IGMP_VERSION;
00350   igmp->mbz      = 0;
00351   igmp->address  = ip;
00352   igmp->checksum = 0;
00353   igmp->checksum = ~CHECKSUM (igmp, sizeof(*igmp));
00354
00355   return IP4_OUTPUT (&pkt->in, 0, ip, IGMP_PROTO,
00356                      0, 0, 0, sizeof(*igmp), NULL);
00357 }
00358
00359 /*
00360  * Check to see if we owe any IGMP Reports
00361  * Called as a daemon from tcp_tick()
00362  */
00363 static void check_mcast_reports (void)
00364 {
00365   struct MultiCast *mc;
00366   int    i;
00367
00368   if (!_multicast_on)
00369      return;
00370
00371   for (i = 0, mc = mcast_list; i < DIM(mcast_list); i++, mc++)
00372   {
00373     if (!mc->active || mc->ip == MCAST_ALL_SYST)
00374        continue;
00375     if (chk_timeout(mc->reply_timer))
00376     {
00377       mc->reply_timer = _multicast_intvl > 0 ?
00378                         set_timeout (1000 * _multicast_intvl) : 0UL;
00379       igmp_report (mc->ip);
00380     }
00381   }
00382 }
00383 #endif /* USE_MULTICAST */
00384
Generated on Wed Jan 25 15:42:37 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/PCMULTI.H Source File

SRC/PCMULTI.H

Go to the documentation of this file.
00001
00003 #ifndef _w32_PCMULTI_H
00004 #define _w32_PCMULTI_H
00005
00006 extern int _multicast_on, _multicast_intvl;
00007
00008 #if defined(USE_MULTICAST)
00009
00013   #define IPMULTI_SIZE    20
00014   #define MCAST_ALL_SYST  0xE0000001UL
00020   struct MultiCast {
00021          DWORD       ip;
00022          eth_address ethaddr;
00023          BYTE        processes;
00024          DWORD       reply_timer;
00025          BOOL        active;
00026        };
00027
00028   extern int  join_mcast_group     (DWORD ip);
00029   extern int  leave_mcast_group    (DWORD ip);
00030   extern int  multi_to_eth         (DWORD ip, eth_address *eth);
00031   extern int  num_multicast_active (void);
00032
00033   extern void igmp_handler (const in_Header *ip, BOOL brdcast);
00034 #endif
00035 #endif
Generated on Wed Jan 25 15:42:37 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/PCPING.C Source File

SRC/PCPING.C

Go to the documentation of this file.
00001
00005 #include <stdio.h>
00006 #include <stdlib.h>
00007 #include <limits.h>
00008
00009 #include "copyrigh.h"
00010 #include "wattcp.h"
00011 #include "misc.h"
00012 #include "timer.h"
00013 #include "chksum.h"
00014 #include "strings.h"
00015 #include "language.h"
00016 #include "ip4_in.h"
00017 #include "ip4_out.h"
00018 #include "pcsed.h"
00019 #include "pcarp.h"
00020 #include "pcconfig.h"
00021 #include "pctcp.h"
00022 #include "pcicmp.h"
00023 #include "pcping.h"
00024
00025 #undef time
00026
00030 static struct ping_cache {
00031        DWORD  host;
00032        DWORD  time;
00033        DWORD  number;
00034      } pcache [10];
00035
00036 typedef int (MS_CDECL *CmpFunc) (const void *, const void *);
00037
00048 int _ping (DWORD host, DWORD countnum, const BYTE *pattern, size_t len)
00049 {
00050   struct ping_pkt  *pkt;
00051   struct ICMP_echo *icmp;
00052   struct in_Header *ip;
00053   eth_address       dest;
00054
00055   if (sin_mask != 0xFFFFFFFF && !_ip4_is_loopback_addr(host) &&
00056       !(~host & ~sin_mask))
00057   {
00058     outsnl (_LANG("Cannot ping a network!"));
00059     return (0);
00060   }
00061
00062   if (!_arp_resolve(host,&dest))
00063   {
00064     outsnl (_LANG("Cannot resolve host's hardware address"));
00065     return (0);
00066   }
00067
00068   if (debug_on >= 2)
00069   {
00070     outs (_LANG("\nDEBUG: destination hardware :"));
00071     outhexes ((char*)&dest, sizeof(dest));
00072     outs ("\n");
00073   }
00074
00075   host = intel (host);
00076
00077   /* Jumbo packets must be sent as IP fragments
00078    */
00079 #if defined(USE_FRAGMENTS)
00080   if (len > (size_t)(_mtu - sizeof(*ip) - sizeof(*icmp)))
00081   {
00082     int rc = 0;
00083
00084     len  = min (len, USHRT_MAX - sizeof(*ip) - sizeof(*icmp));
00085     icmp = (struct ICMP_echo*) malloc (len + sizeof(*icmp));
00086     if (!icmp)
00087     {
00088       if (debug_on)
00089          outsnl (_LANG("_ping(): malloc failed"));
00090       return (0);
00091     }
00092
00093     if (pattern)
00094        memcpy (icmp+1, pattern, len);
00095     len += sizeof(*icmp);
00096     icmp->type       = ICMP_ECHO;
00097     icmp->code       = 0;
00098     icmp->index      = countnum;
00099     icmp->identifier = (WORD) set_timeout (0);  /* "random" id */
00100     icmp->sequence   = 0;
00101     icmp->checksum   = 0;
00102     icmp->checksum   = ~CHECKSUM (icmp, len);
00103     rc = _IP4_SEND_FRAGMENTS (NULL, ICMP_PROTO, host, icmp, len);
00104     free (icmp);
00105     return (rc < 0 ? 0 : rc);
00106   }
00107 #else
00108   len = min (len, _mtu - sizeof(*ip) - sizeof(*icmp)); /* truncate */
00109 #endif
00110
00111   /* Ordinary small pings; format an Ethernet packet with IPv4 type
00112    */
00113   pkt  = (struct ping_pkt*) _eth_formatpacket (&dest, IP4_TYPE);
00114   ip   = &pkt->in;
00115   icmp = &pkt->icmp;
00116
00117   if (pattern && len > 0)
00118   {
00119     len = min (len, _mtu-sizeof(struct ping_pkt));
00120     memcpy (icmp+1, pattern, len);   /* pattern after echo header */
00121     len += sizeof (*icmp);
00122   }
00123   else
00124     len = sizeof (*icmp);
00125
00126   icmp->type       = ICMP_ECHO;
00127   icmp->code       = 0;
00128   icmp->index      = countnum;
00129   icmp->identifier = (WORD) set_timeout (0);  /* "random" id */
00130   icmp->sequence   = 0;
00131   icmp->checksum   = 0;
00132   icmp->checksum   = ~CHECKSUM (icmp, len);
00133
00134   return IP4_OUTPUT (ip, 0, host, ICMP_PROTO, 0, (BYTE)_default_tos,
00135                      0, len, NULL);
00136 }
00137
00141 static int MS_CDECL compare (const struct ping_cache *a,
00142                              const struct ping_cache *b)
00143 {
00144   return ((long)a->number - (long)b->number);
00145 }
00146
00150 void add_ping (DWORD host, DWORD time, DWORD number)
00151 {
00152   int i;
00153
00154   for (i = 0; i < DIM(pcache); i++)
00155       if (host && pcache[i].host == 0)   /* vacant entry */
00156       {
00157         if (time > 0x7FFFFFFFL)
00158             time += 0x1800B0L;
00159         pcache[i].host   = host;
00160         pcache[i].time   = time;
00161         pcache[i].number = number;
00162         qsort ((void*)pcache, DIM(pcache), sizeof(pcache[0]), (CmpFunc)compare);
00163         break;
00164       }
00165 }
00166
00172 DWORD _chk_ping (DWORD host, DWORD *number)
00173 {
00174   int i;
00175
00176   WATT_YIELD();
00177
00178   for (i = 0; i < DIM(pcache); i++)
00179       if (host && pcache[i].host == host)
00180       {
00181         pcache[i].host = 0;    /* clear entry */
00182         if (number)
00183            *number = pcache[i].number;
00184         return (pcache[i].time);
00185       }
00186   return (0xFFFFFFFFUL);
00187 }
00188
00189
Generated on Wed Jan 25 15:42:37 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/PCPING.H Source File

SRC/PCPING.H

Go to the documentation of this file.
00001
00003 #ifndef _w32_PCPING_H
00004 #define _w32_PCPING_H
00005
00006 W32_FUNC int   _ping     (DWORD host, DWORD count, const BYTE *patt, size_t len);
00007 W32_FUNC DWORD _chk_ping (DWORD host, DWORD *number);
00008 W32_FUNC void  add_ping  (DWORD host, DWORD tim, DWORD number);
00009
00010 #endif
Generated on Wed Jan 25 15:42:37 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/PCPKT.C Source File

SRC/PCPKT.C

Go to the documentation of this file.
00001
00009 #include <stdio.h>
00010 #include <stdlib.h>
00011 #include <stddef.h>
00012 #include <string.h>
00013 #include <limits.h>
00014
00015 /* Nothing of this is needed for Win32.
00016  * Refer winpcap.c instead.
00017  */
00018 #if !defined(WIN32) && !defined(_WIN32)
00019
00020 #if defined(__DJGPP__)
00021   #include <sys/exceptn.h>
00022   #include <sys/nearptr.h>
00023   #include <crt0.h>
00024 #endif
00025
00026 #include "copyrigh.h"
00027 #include "wattcp.h"
00028 #include "wdpmi.h"
00029 #include "x32vm.h"
00030 #include "powerpak.h"
00031 #include "asmpkt.h"
00032 #include "strings.h"
00033 #include "language.h"
00034 #include "sock_ini.h"
00035 #include "cpumodel.h"
00036 #include "misc.h"
00037 #include "timer.h"
00038 #include "pcsed.h"
00039 #include "pcstat.h"
00040 #include "pcconfig.h"
00041 #include "pcdbug.h"
00042 #include "pcmulti.h"
00043 #include "pcqueue.h"
00044 #include "pcpkt.h"
00045 #include "pcpkt32.h"
00046
00047
00048 /*@-usedef@*/
00049
00050 WORD _pktdevclass  = PDCLASS_UNKNOWN;
00051 WORD _pkt_ip_ofs   = 0;
00052 WORD _pkt_type_ofs = 0;
00053 BOOL _pktserial    = FALSE;
00054 BYTE _pktdevlevel  = 1;
00055 int  _pkt_rxmode   = RXMODE_BROADCAST;
00056 int  _pkt_rxmode0  = -1;
00057 int  _pkt_errno    = 0;
00058 char *pkt_error    = NULL;             /* Last pkt error string */
00059
00060 int  _pkt_forced_rxmode = -1;
00061 char _pktdrvrname[20]   = "unknown";
00062
00063 struct pkt_info *_pkt_inf = NULL;
00065 static char  pkt_sign[]      = "PKT DRVR";
00066 static WORD  pkt_interrupt   = 0;
00067 static DWORD pkt_drop_cnt    = 0;
00068 static BYTE  pkt_txretries   = 2;
00069 static int   pkt_txwait      = 0;       /* # msec to wait if Tx fails */
00070 static BOOL  pkt_use_near    = FALSE;   /* Use near-ptr if enabled */
00071 static BOOL  pkt_do_reset    = FALSE;   /* reset handle at exit */
00072 static int   pkt_drvr_ver    = 0;       /* Driver internal version */
00073 static int   pkt_num_rx_bufs = RX_BUFS;
00074
00075 #if defined(USE_STATISTICS)
00076   static struct PktStats init_stats;
00077   static void get_init_stats (void);
00078 #endif
00079
00080 static struct PktParameters pkt_params;
00081 static BOOL   got_params   = FALSE;
00082 static BOOL   async_txmode = FALSE;
00083 static int    async_txtime = -1;
00084
00089 #define PKT_FIRST_VEC    0x60
00090 #define PKT_LAST_VEC     0x80
00091 #define PKT_FIRST_VEC_11 0x20
00092 #define PKT_LAST_VEC_11  0xFF
00093
00094
00095 #if (DOSX & PHARLAP)
00096   #include <mw/exc.h>
00097
00098   REALPTR rm_base;
00099
00100   /*
00101    * real-data is organised as follows: PKT_TMP at rm_base + 0x40
00102    *                                    TX_BUF  at PKT_TMP + PKT_TMP_SIZE
00103    *                                    RX_BUF  at TX_BUF + RX_SIZE
00104    */
00105   #define PKT_TMP()     (WORD) 0x40
00106   #define TX_BUF()      (PKT_TMP() + PKT_TMP_SIZE)  /* DWORD boundary */
00107   #define RX_BUF()      (TX_BUF() + RX_SIZE)
00108   #define RDATA_SIZE    (RX_BUF() + RX_SIZE)
00109   #define RP_SEGM()     RP_SEG (rm_base)
00110
00111 #elif (DOSX & X32VM)    /* X32VM is very similar to Pharlap except that it */
00112   REALPTR rm_base;      /* automatically maps DOS memory into our DS */
00113
00114   #define PKT_TMP()     (WORD) 0x40
00115   #define TX_BUF()      (PKT_TMP() + PKT_TMP_SIZE)
00116   #define RX_BUF()      (TX_BUF() + RX_SIZE)
00117   #define RDATA_SIZE    (RX_BUF() + RX_SIZE)
00118   #define RP_SEGM()     RP_SEG (rm_base)
00119
00120 #elif (DOSX & DJGPP)
00121   #if !defined(USE_FAST_PKT)
00122   static _go32_dpmi_seginfo rm_cb;
00123   #endif
00124
00125   static DWORD rm_base;
00126
00127   /*
00128    * real-data is organised as follows: PKT_TMP at rm_base + 0
00129    *                                    TX_BUF  at PKT_TMP + PKT_TMP_SIZE
00130    *                                    RX_BUF  at TX_BUF  + RX_SIZE
00131    */
00132   #define PKT_TMP()     0
00133   #define TX_BUF()      (PKT_TMP() + PKT_TMP_SIZE)
00134   #define RX_BUF()      (TX_BUF() + RX_SIZE)
00135   #define RDATA_SIZE    (RX_BUF() + RX_SIZE)
00136   #define RP_SEGM()     _pkt_inf->rm_seg
00137
00138 #elif (DOSX & DOS4GW)         /* All DOS4GW type extenders */
00139
00140   static DWORD rm_base;       /* Linear address (in DOS) for allocated area */
00141   #if !defined(USE_FAST_PKT)
00142   static WORD  pkt_inf_sel;   /* selector returned from `_pkt_inf' allocation */
00143   #endif
00144
00145   /*
00146    * The DOS-area (0-1MB) is automagically mapped into application
00147    * data.  This eases communication with packet-driver, but clean
00148    * crashes can not be expected. i.e. bugs (dereferencing null-ptr)
00149    * in application will most likely hang the machine.
00150    *
00151    * Real-mode code/data is organised like this:
00152    *   pkt_receiver4_start() copied to allocated area at rm_base
00153    *   PKT_TMP   at rm_base + (pkt_receiver4_end() - pkt_receiver4_start())
00154    *   TX_BUF    at PKT_TMP + PKT_TMP_SIZE
00155    *   end area  at TX_BUF + RX_SIZE
00156    *   RX_BUF is in DOS-allocated `_pkt_inf' structure.
00157    */
00158   #define PKT_TMP()     ((DWORD)pkt_receiver4_end -  \
00159                          (DWORD)pkt_receiver4_start)
00160   #define TX_BUF()      (PKT_TMP() + PKT_TMP_SIZE)
00161   #define RCV_OFS()     ((DWORD)pkt_receiver4_rm - \
00162                          (DWORD)pkt_receiver4_start)
00163   #define RP_SEGM()     _pkt_inf->rm_seg
00164
00165 #elif (DOSX & POWERPAK)
00166   static REALPTR        rm_base;
00167   #if !defined(USE_FAST_PKT)
00168   static DPMI_callback  rm_cb;
00169   #endif
00170
00171   #define PKT_TMP()     0
00172   #define TX_BUF()      (PKT_TMP() + PKT_TMP_SIZE)
00173   #define RX_BUF()      (TX_BUF() + RX_SIZE)
00174   #define RDATA_SIZE    (RX_BUF() + RX_SIZE)
00175   #define RP_SEGM()     _pkt_inf->rm_seg
00176
00177 #elif (DOSX == 0)
00178   void (__cdecl _far * pkt_enque_ptr) (BYTE _far *buf, WORD len);
00179   void (__cdecl _far *_pkt_enque_ptr) (BYTE _far *buf, WORD len);
00180
00181 #else
00182   #error Help me!
00183 #endif
00184
00185
00186 #if defined(USE_FAST_PKT)
00187   #include "pcpkt2.c"
00188
00189 #elif (DOSX)
00190   static int setup_rmode_callback (void);
00191   static int lock_code_and_data   (void);
00192   static int unlock_code_and_data (void);
00193 #endif
00194
00195 static int  find_vector    (int first, int num);
00196 static int  setup_pkt_inf  (void);
00197 static void get_rmode_data (void *dest, unsigned size, WORD seg, WORD ofs);
00198 static BOOL pkt_api_entry  (IREGS *reg, unsigned called_from_line);
00199
00200 #define PKT_API(reg)       pkt_api_entry (reg, __LINE__)
00201 #define CARRY_BIT          1   /* carry bit in (e)flags register */
00202
00203 #define PKT_ERR(str,code)  do {                                     \
00204                              const char *err = pkt_strerror (code); \
00205                              outs (_LANG(str));                     \
00206                              outsnl (err);                          \
00207                            } while (0)
00208
00212 const char *pkt_strerror (int code)
00213 {
00214   static char  buf[50];
00215   static const char *errors[] = {
00216               __LANG("Unknown driver error (0x--)"),
00217     /* 1 */   __LANG("Invalid handle number"),
00218               __LANG("No interfaces of specified class found"),
00219     /* 3 */   __LANG("No interfaces of specified type found"),
00220               __LANG("No interfaces of specified number found"),
00221     /* 5 */   __LANG("Bad packet type specified"),
00222               __LANG("This interface does not support multicast"),
00223     /* 7 */   __LANG("This packet driver cannot terminate"),
00224               __LANG("An invalid receiver mode was specified"),
00225     /* 9 */   __LANG("Operation failed because of insufficient space"),
00226               __LANG("Type previously accessed, and not released"),
00227     /* 11 */  __LANG("The command was out of range, or not implemented"),
00228               __LANG("Cannot send packet (hardware error)"),
00229     /* 13 */  __LANG("Cannot change hardware address"),
00230               __LANG("Hardware address has bad length/format"),
00231     /* 15 */  __LANG("Could not reset interface"),
00232               __LANG("Extended driver needed")
00233             };
00234   const char *rc;
00235   char       *p;
00236
00237   if (code > 0 && code < DIM(errors))
00238      return (_LANG(errors[code]));
00239
00240   rc = StrLcpy (buf, _LANG(errors[0]), sizeof(buf));
00241   p  = strchr (rc, '(');
00242   if (p && strlen(p) >= 5)
00243   {
00244     code &= 0xFF;
00245     p[3] = hex_chars_upper [code >> 4];
00246     p[4] = hex_chars_upper [code & 15];
00247   }
00248   return (buf);
00249 }
00250
00251 /*
00252  * Only for testing asmpkt4.asm
00253  */
00254 #if (DOSX & DOS4GW) && 0
00255 static void dump_asm4 (void)
00256 {
00257   const BYTE *p = (const BYTE*) rm_base;
00258   int   i;
00259
00260   printf ("PKT_INF %08lX, HEAD %08lX, QUEUE %08lX, INDEX %04X, XYPOS %d\n",
00261           *(DWORD*)p, *(DWORD*)(p+4), *(DWORD*)(p+8), *(WORD*)(p+12),
00262           *(WORD*)(p+14));
00263
00264   printf ("rm_base %08lX, handle %04X, is_serial %d\n",
00265           rm_base, _pkt_inf->handle, _pkt_inf->is_serial);
00266
00267   printf ("VAR_1-14: ");
00268   for (i = 16; i <= 42; i += 2)
00269       printf ("%04X ", *(WORD*)(p+i));
00270
00271 #if 0
00272   printf ("PKT_RECV: ");
00273   for (i = RCV_OFS(); i < RCV_OFS()+10; i++)
00274       printf ("%02X ", p[i]);
00275
00276   printf ("\nPKT_TMP:  ");
00277   for (i = PKT_TMP(); i < PKT_TMP()+PKT_TMP_SIZE; i++)
00278       printf ("%02X ", p[i]);
00279 #endif
00280   fflush (stdout);
00281 }
00282 #endif
00283
00284
00290 #if (DOSX & DOS4GW)
00291 void *pkt_tx_buf (void)
00292 {
00293   return (void*)(rm_base + TX_BUF());
00294 }
00295
00296 #elif (DOSX & DJGPP)
00297 void *pkt_tx_buf (void)
00298 {
00299   if (_pkt_inf && _pkt_inf->use_near_ptr)
00300      return (void*)(rm_base + TX_BUF() + __djgpp_conventional_base);
00301   fprintf (stderr, "%s (%d): wrong usage of pkt_tx_buf()\n",
00302            __FILE__, __LINE__);
00303   exit (-1);
00304   /*@-unreachable-*/
00305   return (NULL);
00306 }
00307
00308 #elif (DOSX & X32VM)
00309 void *pkt_tx_buf (void)
00310 {
00311   return (void*) ((RP_SEG(rm_base) << 4) + RP_OFF(rm_base) +
00312                   (DWORD)_x386_zero_base_ptr + TX_BUF());
00313 }
00314 #endif
00315
00321 static int pkt_set_access (void)
00322 {
00323   IREGS regs;
00324
00325   ASSERT_PKT_INF (0);
00326
00327   memset (&regs, 0, sizeof(regs));
00328
00329   regs.r_ax  = PD_ACCESS | _pktdevclass;
00330   regs.r_bx  = 0xFFFF;        /* any type          */
00331   regs.r_dx  = 0;             /* generic interface */
00332   regs.r_cx  = 0;             /* receive any proto */
00333
00334 #if defined(USE_FAST_PKT)
00335   regs.r_es = _pkt_inf->rm_seg;
00336   regs.r_di = PktReceiver;
00337
00338 #elif (DOSX & DJGPP)
00339   regs.r_es = rm_cb.rm_segment;
00340   regs.r_di = rm_cb.rm_offset;
00341
00342 #elif (DOSX & (PHARLAP|X32VM))
00343   regs.r_es = RP_SEGM();
00344   regs.r_di = 0;              /* RMCB aligned at para address */
00345
00346 #elif (DOSX & POWERPAK)
00347   regs.r_es = RP_SEG (rm_cb.rm_addr);
00348   regs.r_di = RP_OFF (rm_cb.rm_addr);
00349
00350 #elif (DOSX & DOS4GW)
00351   regs.r_es = RP_SEGM();
00352   regs.r_di = RCV_OFS();
00353
00354 #else /* real-mode targets */
00355   regs.r_es = FP_SEG (pkt_receiver_rm);  /* = this CS */
00356   regs.r_di = FP_OFF (pkt_receiver_rm);
00357 #endif
00358
00359   if (!PKT_API(&regs))
00360   {
00361     PKT_ERR ("Error allocating handle: ", _pkt_errno);
00362     return (0);
00363   }
00364   _pkt_inf->handle = (WORD) regs.r_ax;
00365   return (1);
00366 }
00367
00371 static int pkt_drvr_info (void)
00372 {
00373   IREGS regs;
00374   int   rc = 1;  /* assume okay */
00375
00376   ASSERT_PKT_INF (0);
00377
00378   /* Lets find out about the driver
00379    */
00380   memset (&regs, 0, sizeof(regs));
00381   regs.r_ax = PD_DRIVER_INFO;
00382
00383   if (!PKT_API(&regs))
00384   {
00385     TCP_CONSOLE_MSG (0, ("Warning: old-type PKTDRVR\n"));
00386     _pktdevclass  = PDCLASS_ETHER;      /* assume Ethernet */
00387     _pkt_ip_ofs   = sizeof(eth_Header);
00388     _pkt_type_ofs = offsetof (struct eth_Header, type);
00389     _pkt_errno    = 0;
00390   }
00391   else          /* new Packet-Driver (1.09+) */
00392   {
00393     _pktdevlevel = loBYTE (regs.r_ax);
00394     _pktdevclass = hiBYTE (regs.r_cx);
00395     pkt_drvr_ver = regs.r_bx & 0xFFFF;
00396
00397     switch (_pktdevclass)
00398     {
00399       case PDCLASS_TOKEN:
00400       case PDCLASS_TOKEN_RIF:  /* !! fix me */
00401            _pkt_ip_ofs   = sizeof(tok_Header);
00402            _pkt_type_ofs = offsetof (struct tok_Header, type);
00403            break;
00404
00405       case PDCLASS_ETHER:
00406            _pkt_ip_ofs   = sizeof(eth_Header);
00407            _pkt_type_ofs = offsetof (struct eth_Header, type);
00408            break;
00409
00410       case PDCLASS_FDDI:
00411            _pkt_ip_ofs   = sizeof(fddi_Header);
00412            _pkt_type_ofs = offsetof (struct fddi_Header, type);
00413            break;
00414
00415       case PDCLASS_ARCNET:
00416            _pkt_ip_ofs   = ARC_HDRLEN;
00417            _pkt_type_ofs = ARC_TYPE_OFS;
00418            break;
00419
00420       case PDCLASS_SLIP:
00421       case PDCLASS_PPP:
00422       case PDCLASS_AX25:    /* !! for now */
00423            _pkt_ip_ofs   = 0;
00424            _pkt_type_ofs = 0;
00425            break;
00426
00427       default:
00428            outs (_LANG("PKT-ERROR: Unsupported driver class "));
00429            outhex ((char)_pktdevclass);
00430            outsnl ("h");
00431            _pkt_errno = PDERR_NO_CLASS;
00432            rc = 0;
00433     }
00434     get_rmode_data (_pktdrvrname, sizeof(_pktdrvrname), regs.r_ds, regs.r_si);
00435     _pktdrvrname [sizeof(_pktdrvrname)-1] = '\0';
00436
00437    if (pkt_txwait == 0 &&
00438        !strcmp(_pktdrvrname,"NDIS3PKT"))
00439       pkt_txwait = 1;    /* This helps when using NDIS3PKT */
00440   }
00441
00442   _pktserial = (_pktdevclass == PDCLASS_SLIP ||
00443                 _pktdevclass == PDCLASS_PPP  ||
00444                 _pktdevclass == PDCLASS_AX25);
00445
00446   _pkt_inf->is_serial    = _pktserial;
00447   _pkt_inf->pkt_ip_ofs   = _pkt_ip_ofs;
00448   _pkt_inf->pkt_type_ofs = _pkt_type_ofs;
00449   return (rc);
00450 }
00451
00455 int pkt_get_params (struct PktParameters *params)
00456 {
00457   IREGS regs;
00458   int   rc = 0;
00459
00460   memset (&regs, 0, sizeof(regs));
00461   regs.r_ax = PD_GET_PARAM;  /* get driver parameters */
00462
00463   DISABLE();
00464   if (PKT_API(&regs))
00465   {
00466     get_rmode_data (params, sizeof(*params), regs.r_es, regs.r_di);
00467     got_params = TRUE;
00468     rc = 1;
00469   }
00470   ENABLE();
00471   return (rc);
00472 }
00473
00478 int pkt_get_mtu (void)
00479 {
00480   if (_pktdevclass == PDCLASS_ARCNET)
00481      return (ARCNET_MAX_DATA - 8);
00482
00483   if (got_params)
00484      return (pkt_params.mtu);
00485   return (-1);
00486 }
00487
00488 #ifdef NOT_USED
00489
00493 int pkt_get_mac_len (void)
00494 {
00495   if (_pktdevclass == PDCLASS_ARCNET)
00496      return (sizeof(arcnet_address));
00497   if (got_params)
00498      return (pkt_params.addr_len);
00499   return (-1);
00500 }
00501 #endif
00502
00508 int pkt_get_api_ver (DWORD *ver)
00509 {
00510   if (got_params)
00511   {
00512     *ver = ((pkt_params.major_rev << 8) + pkt_params.minor_rev);
00513     return (1);
00514   }
00515   return (0);
00516 }
00517
00521 int pkt_get_drvr_ver (DWORD *ver)
00522 {
00523   if (!pkt_drvr_ver)
00524      return (0);
00525   *ver = pkt_drvr_ver;
00526   return (1);
00527 }
00528
00532 int pkt_get_vector (void)
00533 {
00534   return (pkt_interrupt);
00535 }
00536
00548 static int pkt16_drvr_init (mac_address *mac_addr)
00549 {
00550   /* If interrupt specified in config-file ("PKT.VECTOR = 0xNN"),
00551    * check a single vector. Else, search for the 1st driver in range
00552    * 0x60-0x80.
00553    */
00554   if (pkt_interrupt)
00555        pkt_interrupt = find_vector (pkt_interrupt, 1);
00556   else pkt_interrupt = find_vector (PKT_FIRST_VEC,
00557                                     PKT_LAST_VEC - PKT_FIRST_VEC + 1);
00558
00559   if (pkt_interrupt == 0)
00560   {
00561     outsnl (_LANG("NO PACKET DRIVER FOUND."));
00562     return (WERR_NO_DRIVER);
00563   }
00564
00565   if (!setup_pkt_inf())
00566   {
00567     outsnl (_LANG("Failed to allocate PACKET DRIVER data."));
00568     return (WERR_NO_MEM);
00569   }
00570
00571 #if defined(USE_FAST_PKT)
00572   switch (setup_rmode_receiver())
00573   {
00574     case -1:
00575          outsnl (_LANG("Error in PACKET DRIVER stub code."));
00576          return (WERR_PKT_ERROR);
00577   }
00578 #elif (DOSX)
00579   switch (setup_rmode_callback())
00580   {
00581     case -1:
00582          outsnl (_LANG("Failed to allocate callback for PACKET DRIVER."));
00583          return (WERR_NO_MEM);
00584     case -2:
00585          outsnl (_LANG("Failed to allocate DOS-mem for PACKET DRIVER."));
00586     case -3:    /* msg already printed */
00587          return (WERR_NO_MEM);
00588   }
00589
00590   if (lock_code_and_data() < 0)
00591   {
00592     outsnl (_LANG("Failed to lock code/data for PACKET DRIVER."));
00593     return (WERR_PKT_ERROR);
00594   }
00595 #endif   /* USE_FAST_PKT */
00596
00597   if (!pkt_drvr_info())         /* get device class etc. of driver */
00598      return (WERR_PKT_ERROR);
00599
00600   if (!pkt_set_access())        /* set upcall receive handler */
00601   {
00602     pkt_release();
00603     return (WERR_PKT_ERROR);
00604   }
00605
00606   if (!pkt_get_addr(mac_addr))  /* get our MAC address */
00607   {
00608     pkt_release();
00609     return (WERR_PKT_ERROR);
00610   }
00611
00612   memset (&pkt_params, 0, sizeof(pkt_params));
00613   got_params = FALSE;
00614
00615   if (_pktdevlevel >= 5 && _pktdevlevel < 255) /* high-performance driver */
00616   {
00617     if (!pkt_get_params(&pkt_params))
00618        TCP_CONSOLE_MSG (1, ("Failed to get PKTDRVR params; %s\n",
00619                         pkt_strerror(_pkt_errno)));
00620   }
00621
00622 #if defined(USE_STATISTICS)
00623   if (_pktdevlevel >= 2 && _pktdevlevel < 255) /* extended driver */
00624      get_init_stats();
00625 #endif
00626
00627   if (_pktserial)
00628      return (0);  /* success */
00629
00630   /* Set Rx-mode forced via config.
00631    */
00632   if (_pkt_forced_rxmode != -1 &&
00633       (_pkt_forced_rxmode < -1 ||
00634        _pkt_forced_rxmode > RXMODE_PROMISCOUS))
00635   {
00636     TCP_CONSOLE_MSG (0, ("Illegal Rx-mode (%d) specified\n",
00637                      _pkt_forced_rxmode));
00638     _pkt_forced_rxmode = -1;
00639   }
00640
00641   if (pkt_get_rcv_mode())
00642      _pkt_rxmode0 = _pkt_rxmode;   /* remember startup mode */
00643
00644   if (_pkt_forced_rxmode != -1 &&
00645       _pkt_forced_rxmode != _pkt_rxmode0)
00646      pkt_set_rcv_mode (_pkt_forced_rxmode);
00647
00648   /* else hope _pkt_rxmode0 is >= RXMODE_BROADCAST */
00649
00650   return (0);  /* success */
00651 }
00652
00653 /*
00654  * The following functions (ending at '_pkt_end()') are called
00655  * at interrupt time (or asynchronously). 'pkt_release()' may be
00656  * called from SIGSEGV handler. Therefore don't assume anything
00657  * about the state of our stack (except hope it's large enough).
00658  * And don't use large local variables here. Hope we will not be
00659  * reentered since not all functions below are reentrant.
00660  */
00661
00662 /* Disable stack-checking here
00663  */
00664 #if defined(__HIGHC__)
00665   #pragma off(Call_trace)
00666   #pragma off(Prolog_trace)
00667   #pragma off(Epilog_trace)
00668 #endif
00669
00670 #if defined(WATCOM386)
00671  /* #pragma option -zu */                    /* assume SS != DS (doesn't work) */
00672  /* #pragma aux pkt_release __modify[ss] */  /* !! fix-me (doesn't work) */
00673 #endif
00674
00675 #include "nochkstk.h"
00676
00677
00681 int pkt_release_handle (WORD handle)
00682 {
00683   static IREGS regs;  /* `static' because the stack could be too small */
00684
00685   memset (&regs, 0, sizeof(regs));
00686   regs.r_ax = PD_RELEASE;
00687   regs.r_bx = handle;
00688
00689   if (!PKT_API(&regs) && !_watt_fatal_error)
00690      PKT_ERR ("Error releasing handle: ", _pkt_errno);
00691   return (1);
00692 }
00693
00697 int pkt_reset_handle (WORD handle)
00698 {
00699   static IREGS regs;  /* `static' because the stack could be too small */
00700
00701   memset (&regs, 0, sizeof(regs));
00702   regs.r_ax = PD_RESET;
00703   regs.r_bx = handle;
00704
00705   if (!PKT_API(&regs))
00706      PKT_ERR ("Error resetting handle: ", _pkt_errno);
00707   return (1);
00708 }
00709
00710 #if (DOSX) && !defined(USE_FAST_PKT)
00711 static void release_callback (void)
00712 {
00713 #if (DOSX & (PHARLAP|X32VM))
00714   if (rm_base)
00715      _dx_free_rmode_wrapper (rm_base);
00716   rm_base = 0;
00717
00718 #elif (DOSX & POWERPAK)
00719   if (rm_cb.pm_func)
00720      dpmi_free_callback_retf (&rm_cb);
00721   rm_cb.pm_func = 0;
00722
00723 #elif (DOSX & DJGPP)
00724   if (rm_cb.pm_offset)
00725      _pkt_dpmi_free_real_mode_callback (&rm_cb);
00726   rm_cb.pm_offset = 0;
00727 #endif
00728 }
00729 #endif  /* DOSX && !USE_FAST_PKT */
00730
00731
00735 #if (DOSX) && defined(USE_FAST_PKT)
00736 static void release_real_mem (void)
00737 {
00738 #if (DOSX & PHARLAP)
00739   if (_pkt_inf && _pkt_inf->rm_seg)
00740      _dx_real_free (_pkt_inf->rm_seg);
00741   rm_base = 0;
00742
00743 #elif (DOSX & X32VM)
00744   if (rm_base)
00745      _x32_real_free (rm_base);
00746   rm_base = 0;
00747
00748 #elif (DOSX & POWERPAK)
00749   if (_pkt_inf && _pkt_inf->rm_sel)
00750      dpmi_real_free (_pkt_inf->rm_sel);
00751
00752 #elif (DOSX & DJGPP)
00753   if (_pkt_inf && _pkt_inf->rm_sel)
00754   {
00755     __dpmi_error = 0;
00756     __dpmi_free_dos_memory (_pkt_inf->rm_sel);  /* DPMI fn 101h */
00757     if (__dpmi_error)
00758     {
00759       (*_printf) ("%s (%u): DPMI/DOS error %04Xh\n",
00760                   __FILE__, __LINE__, __dpmi_error);
00761       TCP_TRACE_MSG (("release_real_mem: dpmi_error %u\n", __dpmi_error));
00762     }
00763   }
00764   rm_base = (DWORD)-1;  /* crash if used after freed */
00765
00766 #elif (DOSX & DOS4GW)
00767   if (!_watt_fatal_error && _pkt_inf)
00768   {
00769     if (_pkt_inf->rm_sel)
00770        dpmi_real_free (_pkt_inf->rm_sel);
00771
00772 #if !defined(USE_FAST_PKT)
00773     if (pkt_inf_sel)
00774        dpmi_real_free (pkt_inf_sel);
00775     pkt_inf_sel = 0;
00776 #endif
00777   }
00778 #endif
00779
00780   if (_pkt_inf)
00781      _pkt_inf->rm_sel = _pkt_inf->rm_seg = 0;
00782
00783 #if !defined(USE_FAST_PKT)
00784   _pkt_inf = NULL;  /* don't free this ptr below */
00785 #endif
00786 }
00787 #endif  /* DOSX && USE_FAST_PKT */
00788
00789
00798 #ifdef __WATCOMC__
00799 #pragma aux pkt_release loadds;
00800 #endif
00801
00802 #ifdef __GNUC__
00803 #define DTOR __attribute__((destructor))
00804 #else
00805 #define DTOR
00806 #endif
00807
00808 int DTOR pkt_release (void)
00809 {
00810   DISABLE();
00811
00812   if (_pkt_inf)
00813   {
00814     /* Don't do this by default. It may cause some (RealTek)
00815      * packet-drivers to fail all further upcalls.
00816      */
00817     if (pkt_do_reset)
00818        pkt_reset_handle (_pkt_inf->handle);
00819     pkt_release_handle (_pkt_inf->handle);
00820   }
00821
00822 /* !! pkt_interrupt = 0; */
00823
00831 #if (DOSX) && !defined(USE_FAST_PKT)
00832   unlock_code_and_data(); /* unlock before freeing */
00833   release_callback();
00834 #endif
00835
00836 #if (DOSX) && defined(USE_FAST_PKT)
00837   release_real_mem();
00838 #endif
00839
00840   if (_pkt_inf && !_watt_fatal_error)
00841      free (_pkt_inf);
00842
00843   _pkt_inf = NULL;  /* drop anything still in the queue */
00844
00845   ENABLE();
00846   return (1);
00847 }
00848
00849 #if defined(__BORLANDC__)
00850   #pragma exit pkt_release 100
00851 #elif defined(__CCDL__)
00852   #pragma rundown pkt_release 110
00853 #endif
00854
00855
00856 #if !defined(USE_FAST_PKT) && !(DOSX & DOS4GW)
00857
00885 #if (DOSX)
00886 static void pkt_enqueue (unsigned rxBuf, WORD rxLen)
00887 #else
00888 static void __cdecl _far pkt_enqueue (BYTE _far *rxBuf, WORD rxLen)
00889 #endif
00890 {
00891   struct pkt_ringbuf *q = &_pkt_inf->pkt_queue;
00892   int    index;
00893
00894   /* don't use pktq_in_index() and pktq_in_buf() because they
00895    * are not in locked code area.
00896    */
00897   index = q->in_index + 1;
00898   if (index >= q->num_buf)
00899       index = 0;
00900
00901   if (index != q->out_index)
00902   {
00903     char *head   = (char*)q->buf_start + (q->buf_size * q->in_index);
00904     int   padLen = q->buf_size - 4 - rxLen;
00905
00906     if (rxLen > q->buf_size - 4)  /* don't overwrite marker */
00907     {
00908       rxLen  = q->buf_size - 4;
00909       padLen = 0;
00910     }
00911
00912 #if (DOSX & (PHARLAP|X32VM|POWERPAK))
00913     ReadRealMem (head, rm_base + rxBuf, rxLen);
00914
00915 #elif (DOSX & DJGPP)
00916     if (_pkt_inf->use_near_ptr)
00917          memcpy (head, (void*)(rm_base+rxBuf+__djgpp_conventional_base), rxLen);
00918     else DOSMEMGETL (rm_base + rxBuf, (rxLen+3)/4, head);
00919
00920 #else  /* real-mode targets */
00921     _fmemcpy (head, rxBuf, rxLen);
00922 #endif
00923
00924     /* Zero-fill remaining old data in this buffer.
00925      */
00926     head += rxLen;
00927     while (padLen--)
00928        *head++ = '\0';
00929     q->in_index = index;   /* update buffer tail-index */
00930   }
00931   else
00932     q->num_drop++;         /* no room, increment drop count */
00933 }
00934
00935
00936 /*
00937  * We have allocated a real-mode callback (RMCB) to gain control
00938  * here when the packet-driver makes an upcall.
00939  *
00940  * Entry AL = 0; driver requests a buffer. We return ES:DI of real-mode buffer
00941  *       BX = handle (IP, ARP or RARP)
00942  *       CX = length of packet
00943  *
00944  * Entry AL = 1; driver has put the data in buffer, we then enqueues the buffer
00945  *       BX = handle (IP, ARP or RARP)
00946  *       CX = length of packet (same as CX above)
00947  *       DS:SI = *must* be same as ES:DI returned above.
00948  *       ES:DI = should be same as ES:DI returned above (but don't count on it).
00949  *
00950  * Interrupts are disabled on entry.
00951  * Note: This function MUST be declared cdecl (not register called).
00952  */
00953 #if (DOSX & (PHARLAP|X32VM))
00954   static void cdecl pkt_receiver_pm (SWI_REGS *r)
00955   {
00956     PUSHF_CLI();
00957
00958     if ((BYTE)r->r_ax == 0)         /* AL == 0; rx-buffer request */
00959     {
00960       if (!_pkt_inf || (WORD)r->r_cx > ETH_MAX)
00961       {
00962         r->r_es = 0;
00963         r->r_di = 0;
00964       }
00965       else
00966       {
00967         r->r_es = RP_SEGM();
00968         r->r_di = RX_BUF();
00969       }
00970     }
00971     else if ((WORD)r->r_si && _pkt_inf)   /* AL != 0; rx-buffer filled */
00972     {
00973       pkt_enqueue (RX_BUF(), (WORD)r->r_cx);
00974     }
00975     POPF();
00976   }
00977
00978 #elif (DOSX & DJGPP)
00979   static void cdecl pkt_receiver_pm (__dpmi_regs *r)
00980   {
00981     WORD fs, gs;
00982
00983     PUSHF_CLI();      /* "cld" already done in RMCB wrapper */
00984
00985     fs = get_fs_reg();
00986     gs = get_gs_reg();
00987
00988     if (r->h.al == 0)
00989     {
00990       if (!_pkt_inf || r->x.cx > ETH_MAX)
00991       {
00992         r->x.es = 0;
00993         r->x.di = 0;
00994       }
00995       else
00996       {
00997         r->x.es = RP_SEGM();
00998         r->x.di = RX_BUF();
00999       }
01000     }
01001     else if (r->x.si && _pkt_inf)
01002     {
01003       pkt_enqueue (RX_BUF(), r->x.cx);
01004     }
01005
01006     set_fs_reg (fs);
01007     set_gs_reg (gs);
01008
01009     POPF();
01010   }
01011
01012 #elif (DOSX & POWERPAK)
01013   static void cdecl pkt_receiver_pm (void)
01014   {
01015     REAL_regs *r;
01016
01017     PUSHF_CLI();
01018     r = &rm_cb.rm_regs;
01019
01020     if ((BYTE)r->r_ax == 0)
01021     {
01022       if (!_pkt_inf || (WORD)r->r_cx > ETH_MAX)
01023       {
01024         r->r_es = 0;
01025         r->r_di = 0;
01026       }
01027       else
01028       {
01029         r->r_es = RP_SEGM();
01030         r->r_di = RX_BUF();
01031       }
01032     }
01033     else if (r->r_si && _pkt_inf)
01034     {
01035       pkt_enqueue (RX_BUF(), (WORD)r->r_cx);
01036     }
01037     POPF();
01038   }
01039 #endif
01040
01041 void _pkt_end (void) {}
01042
01043 #if defined(__WATCOMC__)
01044 #pragma alloc_text (pkt_lock_TEXT, pkt_enqueue, pkt_receiver_pm, _pkt_end);
01045 #endif
01046
01047 #endif  /* !(DOSX & DOS4GW) && !USE_FAST_PKT */
01048
01049
01060 int pkt_send (const void *tx, int length)
01061 {
01062   struct async_iocb asy_cb;
01063   IREGS  regs;
01064   WORD   tx_seg, tx_ofs, as_seg, as_ofs;
01065   int    tx_cnt;
01066
01067   if (!_pkt_inf)
01068      return (0);
01069
01070   PROFILE_START ("pkt_send");
01071
01072   memset (&regs, 0, sizeof(regs));
01073
01074 #if (DOSX & (PHARLAP|POWERPAK))
01075   tx_seg = RP_SEGM();
01076   tx_ofs = TX_BUF();
01077   WriteRealMem (rm_base + tx_ofs, (void*)tx, length);
01078
01079 #elif (DOSX & (DOS4GW|X32VM))
01080   tx_seg = RP_SEGM();
01081   tx_ofs = TX_BUF();
01082   WATT_ASSERT (tx == pkt_tx_buf());  /* no need to copy anything */
01083
01084 #elif (DOSX & DJGPP)
01085   tx_seg = RP_SEGM();
01086   tx_ofs = TX_BUF();
01087   if (_pkt_inf->use_near_ptr)
01088        WATT_ASSERT (tx == pkt_tx_buf());
01089   else DOSMEMPUTL (tx, (length+3)/4, rm_base + tx_ofs);
01090
01091 #else
01092   tx_seg = FP_SEG (tx);
01093   tx_ofs = FP_OFF (tx);
01094 #endif
01095
01096   as_seg = as_ofs = 0;
01097
01098   if (async_txmode)
01099   {
01100 #if (DOSX & (PHARLAP|POWERPAK))
01101     as_seg = RP_SEGM();
01102     as_ofs = PKT_TMP();
01103     WriteRealMem (rm_base + as_ofs, (void*)&asy_cb, sizeof(asy_cb));
01104 #elif (DOSX & (DOS4GW|X32VM))
01105     as_seg = RP_SEGM();
01106     as_ofs = PKT_TMP();
01107 #elif (DOSX & DJGPP)
01108     as_seg = RP_SEGM();
01109     as_ofs = PKT_TMP();
01110     DOSMEMPUT (&asy_cb, sizeof(asy_cb), rm_base + as_ofs);
01111 #else
01112     as_seg = FP_SEG (&asy_cb);
01113     as_ofs = FP_OFF (&asy_cb);
01114 #endif
01115     asy_cb.buffer    = (tx_seg << 4) + tx_ofs;
01116     asy_cb.length    = length;
01117     asy_cb.flagbits  = 0;
01118     asy_cb.xmit_func = 0;
01119   }
01120
01121   for (tx_cnt = 0; tx_cnt <= pkt_txretries; tx_cnt++)
01122   {
01123     DWORD tx_timer;
01124     BOOL  done;
01125     BYTE  flags;
01126
01127     regs.r_cx = length;
01128     regs.r_ax = async_txmode ? PD_ASY_SEND : PD_SEND;
01129     regs.r_ds = tx_seg;
01130     regs.r_si = tx_ofs;
01131     regs.r_es = as_seg;
01132     regs.r_di = as_ofs;
01133
01134     if (!PKT_API(&regs))
01135     {
01136       if (async_txmode && _pkt_errno == PDERR_BAD_COMMAND)
01137       {
01138         async_txmode = FALSE;
01139         PROFILE_STOP();
01140         TCP_CONSOLE_MSG (2, ("Async Tx failed. Retrying in sync mode.\n"));
01141         return pkt_send (tx, length);
01142       }
01143
01144 #if 0
01145       if (elapsed_time > (length / line_speed) + some_margin)
01146          break;
01147 #endif
01148       if (pkt_txwait > 0)
01149          Wait (pkt_txwait);
01150       continue;
01151     }
01152
01153     if (!async_txmode)
01154        break;
01155
01156     /* we should wait for the transmit to complete
01157      */
01158     tx_timer = set_timeout (async_txtime);
01159     done = FALSE;
01160
01161     while (!done)
01162     {
01163       flags = PEEKB (as_seg, as_ofs + offsetof(struct async_iocb, flagbits));
01164       done  = (flags & ASY_DONE);
01165       if (async_txtime > -1 && chk_timeout(tx_timer))
01166       {
01167         STAT (macstats.num_tx_timeout++);
01168         length = 0;
01169         goto quit;  /* no point retrying (?) */
01170       }
01171     }
01172   }
01173
01174 quit:
01175   if (tx_cnt > 0)
01176      STAT (macstats.num_tx_retry += tx_cnt-1);
01177
01178   if (tx_cnt > pkt_txretries)
01179      length = 0;
01180
01181   if (length == 0)
01182      STAT (macstats.num_tx_err++);
01183
01184   PROFILE_STOP();
01185   return (length);
01186 }
01187
01191 int pkt_get_addr (mac_address *eth)
01192 {
01193   IREGS regs;
01194   WORD  seg, ofs;
01195   int   rc;
01196
01197   ASSERT_PKT_INF (0);
01198
01199   PROFILE_START ("pkt_get_addr");
01200
01201   regs.r_ax = PD_GET_ADDRESS;
01202   regs.r_bx = _pkt_inf->handle;
01203   regs.r_cx = sizeof (*eth);
01204
01205 #if (DOSX)
01206   regs.r_es = seg = RP_SEGM();
01207   regs.r_di = ofs = PKT_TMP();
01208 #else
01209   regs.r_es = seg = FP_SEG (eth);
01210   regs.r_di = ofs = FP_OFF (eth);
01211 #endif
01212
01213   if (!PKT_API(&regs))
01214   {
01215     PKT_ERR ("Cannot read own MAC address: ", _pkt_errno);
01216     rc = 0;
01217   }
01218   else
01219   {
01220     get_rmode_data (eth, sizeof(*eth), seg, ofs);
01221     rc = 1;
01222   }
01223   PROFILE_STOP();
01224   return (rc);
01225 }
01226
01230 int pkt_set_addr (const void *addr)
01231 {
01232   IREGS regs;
01233
01234   ASSERT_PKT_INF (0);
01235
01236   regs.r_ax = PD_SET_ADDR;
01237   regs.r_cx = sizeof (mac_address);
01238
01239 #if (DOSX & DJGPP)
01240   DOSMEMPUT (addr, sizeof(mac_address), rm_base + PKT_TMP());
01241   regs.r_es = RP_SEGM();
01242   regs.r_di = PKT_TMP();
01243
01244 #elif (DOSX & DOS4GW)
01245   memcpy ((void*)(rm_base + PKT_TMP()), addr, sizeof(mac_address));
01246   regs.r_es = RP_SEGM();
01247   regs.r_di = PKT_TMP();
01248
01249 #elif (DOSX & (PHARLAP|X32VM|POWERPAK))
01250   WriteRealMem (rm_base + PKT_TMP(), (void*)addr, sizeof(mac_address));
01251   regs.r_es = RP_SEGM();
01252   regs.r_di = PKT_TMP();
01253
01254 #else
01255   {
01256     mac_address tmp;
01257     memcpy (&tmp, addr, sizeof(tmp)); /* prevent driver modifying '*addr' */
01258     regs.r_es = FP_SEG (&tmp);
01259     regs.r_di = FP_OFF (&tmp);
01260   }
01261 #endif
01262
01263   if (!PKT_API(&regs))
01264      return (0);
01265   return (1);
01266 }
01267
01268 #if defined(USE_STATISTICS)
01269
01275 int pkt_get_stats (struct PktStats *stats, struct PktStats *total)
01276 {
01277   IREGS regs;
01278   int   rc = 0;
01279
01280   PROFILE_START ("pkt_get_stats");
01281   DISABLE();
01282
01283   /* Handle in BX is optional for 1.11 drivers
01284    */
01285   regs.r_bx = _pkt_inf ? _pkt_inf->handle : 0;
01286   regs.r_ax = PD_GET_STATS;
01287
01288   if (!PKT_API(&regs))
01289      goto fail;
01290
01291   rc = 1;
01292   get_rmode_data (stats, sizeof(*stats), regs.r_ds, regs.r_si);
01293
01294   if (total)
01295      *total = *stats;
01296
01297   stats->in_packets  -= init_stats.in_packets;
01298   stats->out_packets -= init_stats.out_packets;
01299   stats->in_bytes    -= init_stats.in_bytes;
01300   stats->out_bytes   -= init_stats.out_bytes;
01301   stats->in_errors   -= init_stats.in_errors;
01302   stats->out_errors  -= init_stats.out_errors;
01303   stats->lost        -= init_stats.lost;
01304 fail:
01305   ENABLE();
01306   PROFILE_STOP();
01307   return (rc);
01308 }
01309
01310 static void get_init_stats (void)
01311 {
01312   IREGS regs;
01313
01314   regs.r_ax = PD_GET_STATS;
01315   regs.r_bx = _pkt_inf->handle;
01316   memset (&init_stats, 0, sizeof(init_stats));
01317
01318   DISABLE();
01319   if (PKT_API(&regs))
01320      get_rmode_data (&init_stats, sizeof(init_stats), regs.r_ds, regs.r_si);
01321   ENABLE();
01322 }
01323
01324
01329 static WORD cstate_dseg = 0;
01330
01331 int pkt_get_vjstats (struct slcompress *vjstats)
01332 {
01333   IREGS regs;
01334   int   rc = 0;
01335
01336   regs.r_ax = PD_GET_VJSTATS;
01337   regs.r_bx = sizeof (*vjstats);
01338
01339   DISABLE();
01340   if (PKT_API(&regs))
01341   {
01342     get_rmode_data (vjstats, sizeof(*vjstats), regs.r_ds, regs.r_si);
01343     cstate_dseg = regs.r_ds;
01344     rc = 1;
01345   }
01346   ENABLE();
01347   return (rc);
01348 }
01349
01350 int pkt_get_cstate (struct cstate *cs, WORD cstate_ofs)
01351 {
01352   if (cstate_dseg == 0 || cstate_ofs == 0)
01353      return (0);
01354
01355   DISABLE();
01356   get_rmode_data (cs, sizeof(*cs), cstate_dseg, cstate_ofs);
01357   ENABLE();
01358   return (1);
01359 }
01360 #endif  /* USE_STATISTICS */
01361
01362
01366 int pkt_buf_wipe (void)
01367 {
01368 #if defined(USE_FAST_PKT)
01369   pktq_clear (NULL);
01370 #else
01371   ASSERT_PKT_INF (0);
01372   pktq_clear (&_pkt_inf->pkt_queue);
01373 #endif
01374   return (1);
01375 }
01376
01381 void pkt_free_pkt (const void *pkt)
01382 {
01383 #if !defined(USE_FAST_PKT)  /* packet already copied in pcsed.c */
01384   struct pkt_ringbuf *q;
01385
01386   if (!_pkt_inf || !pkt)
01387      return;
01388
01389   q = &_pkt_inf->pkt_queue;
01390   pkt_drop_cnt = q->num_drop;
01391
01392   if (pkt != (const void*) (pktq_out_buf(q) + _pkt_ip_ofs))
01393   {
01394     TCP_CONSOLE_MSG (0, ("%s: freeing illegal packet 0x%p.\n", __FILE__, pkt));
01395     pktq_clear (q);
01396   }
01397   else
01398     pktq_inc_out (q);
01399 #else
01400   if (rm_base && rm_base < (DWORD)-1)
01401      pkt_drop_cnt = FAR_PEEK_DWORD (struct pkt_info, pkt_queue.num_drop);
01402   ARGSUSED (pkt);
01403 #endif
01404 }
01405
01406
01410 int pkt_waiting (void)
01411 {
01412 #if defined(USE_FAST_PKT)
01413   if (rm_base && rm_base < (DWORD)-1)
01414      return pkt_buffers_used();
01415   return (-1);
01416 #else
01417   if (_pkt_inf)
01418      return pktq_queued (&_pkt_inf->pkt_queue);
01419   return (-1);
01420 #endif
01421 }
01422
01426 DWORD pkt_dropped (void)
01427 {
01428 #if defined(USE_FAST_PKT)
01429   if (rm_base && rm_base < (DWORD)-1)
01430      return pkt_rx_dropped();
01431 #else
01432   if (_pkt_inf)
01433      return (_pkt_inf->pkt_queue.num_drop);
01434 #endif
01435   return (pkt_drop_cnt);    /* return last known value */
01436 }
01437
01438 /*
01439  * Set async transmit mode and Tx timeout.
01440  * "pkt.txmode = async [, timeout]"
01441  */
01442 static void set_txmode (const char *value)
01443 {
01444   const char *p;
01445
01446   if (!strnicmp(value,"async",5))
01447   {
01448     async_txmode = TRUE;
01449     p = strchr (value, ',');
01450     if (p)
01451        async_txtime = atoi (p+1);
01452   }
01453 }
01454
01459 static int parse_config_pass_1 (void)
01460 {
01461   static int    vect = 0;
01462   static const struct config_table pkt_init_cfg[] = {
01463        { "PKT.VECTOR",    ARG_ATOX_B, (void*)&vect },
01464        { "PKT.TXRETRIES", ARG_ATOB,   (void*)&pkt_txretries },
01465        { "PKT.TXWAIT",    ARG_ATOI,   (void*)&pkt_txwait },
01466        { "PKT.RXMODE",    ARG_ATOI,   (void*)&_pkt_forced_rxmode },
01467        { "PKT.TXMODE",    ARG_FUNC,   (void*)set_txmode },
01468        { "PKT.RXBUFS",    ARG_ATOI,   (void*)&pkt_num_rx_bufs },
01469        { "PKT.NEAR_PTR",  ARG_ATOI,   (void*)&pkt_use_near },
01470        { "PKT.RESET",     ARG_ATOI,   (void*)&pkt_do_reset },
01471        { NULL,            0,          NULL }
01472      };
01473   const struct config_table *cfg_save          = watt_init_cfg;
01474   void (*init_save) (const char*, const char*) = usr_init;
01475   int    rc;
01476
01477   watt_init_cfg = pkt_init_cfg;
01478   usr_init      = NULL;    /* only pkt_init_cfg[] gets parsed */
01479   rc = tcp_config (NULL);
01480   usr_init      = init_save;
01481   watt_init_cfg = cfg_save;
01482   if (!rc)
01483      return (0);
01484   return (vect);
01485 }
01486
01499 int pkt_eth_init (mac_address *addr)
01500 {
01501   int vector, rc = -1;
01502
01503   if (_watt_no_config && !_watt_user_config_fn)
01504        vector = 0;
01505   else vector = parse_config_pass_1();
01506
01507   if (vector)
01508   {
01509     pkt_interrupt = vector;
01510     if (pkt_interrupt < PKT_FIRST_VEC_11 || /* 0x20-0xFF range for 1.11 drvr */
01511         pkt_interrupt > PKT_LAST_VEC_11)
01512         pkt_interrupt = 0;                  /* discard illegal value */
01513   }
01514   else
01515     pkt_interrupt = 0;
01516
01517   {
01518 #if (DOSX)
01519     int pm_driver = pkt32_drvr_probe (pm_driver_list);
01520
01521     if (pm_driver > -1)
01522     {
01523       rc = pkt32_drvr_init (pm_driver, addr);
01524       if (rc == 0)
01525          TCP_CONSOLE_MSG (2, ("Using Pmode `%s' driver at %08lX\n",
01526                           pkt32_drvr_name(pm_driver), (DWORD)_pkt32_drvr));
01527     }
01528     if (rc)  /* pmode driver failed, try real-mode driver */
01529 #endif
01530        rc = pkt16_drvr_init (addr);
01531
01532     if (rc)
01533        return (rc);  /* no suitable driver found */
01534   }
01535
01536 #if defined(USE_FAST_PKT)
01537   FAR_POKE_WORD (struct pkt_info, handle, _pkt_inf->handle);
01538   FAR_POKE_WORD (struct pkt_info, is_serial, _pkt_inf->is_serial);
01539   FAR_POKE_WORD (struct pkt_info, pkt_ip_ofs, _pkt_inf->pkt_ip_ofs);
01540   FAR_POKE_WORD (struct pkt_info, pkt_type_ofs, _pkt_inf->pkt_type_ofs);
01541
01542 #if (DOSX & X32VM)
01543   if (!pkt_test_upcall())
01544   {
01545     pkt_release();
01546     return (-1);
01547   }
01548 #endif
01549 #endif
01550
01551   return (0);
01552 }
01553
01557 #if (DOSX & (PHARLAP|X32VM))
01558   static BOOL check_intr_num (WORD intr_num)
01559   {
01560     REALPTR rp;
01561     char    temp[16];
01562
01563     _dx_rmiv_get (intr_num, &rp);
01564     if (rp)
01565     {
01566       ReadRealMem (&temp, rp, sizeof(temp));
01567       if (!memcmp(temp+3, pkt_sign, strlen(pkt_sign)))
01568          return (TRUE);
01569     }
01570     return (FALSE);
01571   }
01572
01573 #elif (DOSX & DJGPP)
01574   static BOOL check_intr_num (WORD intr_num)
01575   {
01576     char  temp[16];
01577     DWORD rp;
01578     __dpmi_raddr realAdr;
01579
01580     __dpmi_get_real_mode_interrupt_vector (intr_num, &realAdr);
01581     rp = (realAdr.segment << 4) + realAdr.offset16;
01582     if (rp)
01583     {
01584       dosmemget (rp, sizeof(temp), &temp);
01585       if (!memcmp(temp+3, pkt_sign, strlen(pkt_sign)))
01586          return (TRUE);
01587     }
01588     return (FALSE);
01589   }
01590
01591 #elif (DOSX & DOS4GW)
01592   static BOOL check_intr_num (WORD intr_num)
01593   {
01594     const BYTE *addr = (const BYTE*) dpmi_get_real_vector (intr_num);
01595
01596     if (addr && !memcmp(addr+3, pkt_sign, strlen(pkt_sign)))
01597        return (TRUE);
01598     return (FALSE);
01599   }
01600
01601 #elif (DOSX & POWERPAK)
01602   static BOOL check_intr_num (WORD intr_num)
01603   {
01604     char    temp[16];
01605     DWORD   addr = (DWORD) dpmi_get_real_vector (intr_num);
01606     REALPTR rp;
01607
01608     RP_SET (rp, addr & 0xF, addr >> 4);
01609     ReadRealMem (&temp, rp, sizeof(temp));
01610     if (!memcmp(temp+3, pkt_sign, strlen(pkt_sign)))
01611        return (TRUE);
01612     return (FALSE);
01613   }
01614
01615 #else       /* real-mode version */
01616   static BOOL check_intr_num (WORD intr_num)
01617   {
01618     char _far *addr = (char _far*) getvect (intr_num);
01619
01620 #if !defined(USE_FAST_PKT)
01621     pkt_enque_ptr  = pkt_enqueue;
01622     _pkt_enque_ptr = pkt_enqueue;
01623 #endif
01624
01625     if (addr && !_fmemcmp (addr+3, pkt_sign, strlen(pkt_sign)))
01626        return (TRUE);
01627     return (FALSE);
01628   }
01629 #endif
01630
01631 /*
01632  * Find the interrupt-number for the PKTDRVR by searching interrupt
01633  * handler entries (at vector+3) for signature string "PKT DRVR".
01634  */
01635 static int find_vector (int first, int num)
01636 {
01637   int inum;
01638
01639   for (inum = first; inum < first + num; inum++)
01640   {
01641     if (inum != 0x67 &&     /* can never be at EMS vector */
01642         check_intr_num(inum))
01643        return (inum);
01644   }
01645   return (0);
01646 }
01647
01648 #if !defined(USE_FAST_PKT)
01649 /*
01650  * DOS-extender functions for allocation a real-mode callback that
01651  * the real-mode PKTDRVR will call when a packet is received.
01652  * Lock down all code and data that is touched in this callback.
01653  */
01654 #if (DOSX & (PHARLAP|X32VM))
01655   static int setup_rmode_callback (void)
01656   {
01657     rm_base = _dx_alloc_rmode_wrapper_retf (pkt_receiver_pm, NULL,
01658                                             RDATA_SIZE, 1024);
01659     if (!rm_base)
01660        return (-1);
01661     return (0);
01662   }
01663
01664   static int lock_code_and_data (void) /* Needed for 386|VMM only (?) */
01665   {
01666     UINT size = (UINT)_pkt_end - (UINT)pkt_enqueue;
01667
01668     _dx_lock_pgsn ((void*)pkt_enqueue, size);
01669     _dx_lock_pgsn ((void*)ReadRealMem, 100);
01670     _dx_lock_pgsn ((void*)_pkt_inf, sizeof(*_pkt_inf));
01671     _dx_lock_pgsn ((void*)&_pkt_inf, sizeof(_pkt_inf));
01672
01673   #if (DOSX & X32VM)
01674     _dx_lock_pgsn ((void*)memcpy, 200);
01675   #endif
01676     return (0);
01677   }
01678
01679   static int unlock_code_and_data (void)
01680   {
01681     UINT size = (UINT)_pkt_end - (UINT)pkt_enqueue;
01682
01683     _dx_ulock_pgsn ((void*)pkt_enqueue, size);
01684     _dx_ulock_pgsn ((void*)ReadRealMem, 100);
01685     _dx_ulock_pgsn ((void*)_pkt_inf, sizeof(*_pkt_inf));
01686     _dx_ulock_pgsn ((void*)&_pkt_inf, sizeof(_pkt_inf));
01687
01688   #if (DOSX & X32VM)
01689     _dx_ulock_pgsn ((void*)memcpy, 200);
01690   #endif
01691     return (0);
01692   }
01693
01694 #elif (DOSX & DJGPP)
01695   static int setup_rmode_callback (void)
01696   {
01697     static __dpmi_regs rm_reg;
01698     int    seg = __dpmi_allocate_dos_memory ((RDATA_SIZE + 15) / 16,
01699                                              &_pkt_inf->rm_sel);
01700     if (seg < 0)
01701        return (-2);
01702
01703     _pkt_inf->rm_seg = seg;
01704     rm_cb.pm_offset = (DWORD) pkt_receiver_pm;
01705
01706     memset (&rm_reg, 0, sizeof(rm_reg));
01707     if (_pkt_dpmi_allocate_real_mode_callback_retf (&rm_cb,&rm_reg))
01708        return (-1);
01709
01710     rm_base = (_pkt_inf->rm_seg << 4);
01711
01712     DOSMEMCLR (rm_base, RDATA_SIZE);
01713     return (0);
01714   }
01715
01716   static int lock_code_and_data (void)
01717   {
01718     DWORD size = (DWORD)_pkt_end - (DWORD)pkt_enqueue;
01719
01720     WATT_ASSERT ((DWORD)_pkt_end > (DWORD)pkt_enqueue);
01721
01722     if (_go32_dpmi_lock_code((void*)pkt_enqueue, size)    ||
01723         _go32_dpmi_lock_code((void*)__movedata, 30)       ||
01724         _go32_dpmi_lock_code((void*)_movedatal, 30)       ||
01725         _go32_dpmi_lock_code((void*)__dj_movedata, 100)   ||
01726         _go32_dpmi_lock_data(&_pkt_inf, sizeof(_pkt_inf)) ||
01727         _go32_dpmi_lock_data(_pkt_inf, sizeof(*_pkt_inf)))
01728        return (-1);
01729     /* rm_reg is already locked */
01730     return (0);
01731   }
01732
01733   static void _unlock (const void *addr, DWORD size)
01734   {
01735     __dpmi_meminfo mem;
01736     DWORD base = 0;
01737
01738     __dpmi_get_segment_base_address (_my_ds(), &base);
01739     mem.address = base + (DWORD)addr;
01740     mem.size    = size;
01741     __dpmi_unlock_linear_region (&mem);
01742   }
01743
01744   static int unlock_code_and_data (void)
01745   {
01746     _unlock ((void*)pkt_enqueue, (DWORD)_pkt_end - (DWORD)pkt_enqueue);
01747     _unlock ((void*)__movedata, 30);
01748     _unlock ((void*)_movedatal, 30);
01749     _unlock ((void*)__dj_movedata, 100);
01750     _unlock (_pkt_inf, sizeof(*_pkt_inf));
01751     _unlock (&_pkt_inf, sizeof(_pkt_inf));
01752     return (0);
01753   }
01754
01755 #elif (DOSX & DOS4GW)
01756   static int setup_rmode_callback (void)
01757   {
01758     int length;
01759
01760     /* test for asmpkt4.asm/pcpkt.h mismatch
01761      */
01762     if (asmpkt_size_chk != sizeof(*_pkt_inf))
01763     {
01764 #ifdef USE_DEBUG
01765       fprintf (stderr,
01766                "%s (%u): Development error:\n"
01767                "  sizeof(pkt_info) = %u pcpkt.h\n"
01768                "  sizeof(pkt_info) = %u asmpkt4.asm, (diff %d)\n",
01769                __FILE__, __LINE__,
01770                sizeof(*_pkt_inf), asmpkt_size_chk,
01771                sizeof(*_pkt_inf) - asmpkt_size_chk);
01772 #endif
01773       return (-3);
01774     }
01775
01776     /* Allocate DOS-memory for pkt_receiver4_rm() and temp/Tx buffers.
01777      */
01778     length = TX_BUF() + RX_SIZE;
01779     _pkt_inf->rm_seg = dpmi_real_malloc (length, &_pkt_inf->rm_sel);
01780     if (!_pkt_inf->rm_seg)
01781        return (-2);
01782
01783     rm_base = ((DWORD)_pkt_inf->rm_seg) << 4;
01784
01785     /* Clear DOS area and copy code down into it.
01786      */
01787     memset ((void*)rm_base, 0, length);
01788     length = PKT_TMP() - 1;
01789     memcpy ((void*)rm_base, pkt_receiver4_start, length);
01790     return (0);
01791   }
01792
01793   /* No need (?) to lock anything.
01794    */
01795   static int lock_code_and_data (void)
01796   {
01797     return (0);
01798   }
01799
01800   static int unlock_code_and_data (void)
01801   {
01802     return (0);
01803   }
01804
01805 #elif (DOSX & POWERPAK)
01806   static int setup_rmode_callback (void)
01807   {
01808     /* Allocate DOS-memory for temp/Tx buffers.
01809      */
01810     _pkt_inf->rm_seg = dpmi_real_malloc (RDATA_SIZE, &_pkt_inf->rm_sel);
01811     if (!_pkt_inf->rm_seg)
01812        return (-2);
01813
01814     rm_base = (REALPTR) ((DWORD)_pkt_inf->rm_seg << 16);
01815
01816     rm_cb.pm_func = pkt_receiver_pm;
01817     if (!dpmi_alloc_callback_retf(&rm_cb))
01818        return (-1);
01819     return (0);
01820   }
01821
01822   static int lock_code_and_data (void)
01823   {
01824     unsigned size = (unsigned)_pkt_end - (unsigned)pkt_enqueue;
01825
01826     if (!dpmi_lock_region ((void*)pkt_enqueue, size) ||
01827         !dpmi_lock_region ((void*)ReadRealMem, 100)  ||
01828         !dpmi_lock_region ((void*)_pkt_inf, sizeof(*_pkt_inf)) ||
01829         !dpmi_lock_region ((void*)&_pkt_inf, sizeof(_pkt_inf)))
01830        return (-1);
01831     return (0);
01832   }
01833
01834   static int unlock_code_and_data (void)
01835   {
01836     unsigned size = (unsigned)_pkt_end - (unsigned)pkt_enqueue;
01837
01838     if (!dpmi_unlock_region ((void*)pkt_enqueue, size) ||
01839         !dpmi_unlock_region ((void*)ReadRealMem, 100)  ||
01840         !dpmi_unlock_region ((void*)_pkt_inf, sizeof(*_pkt_inf)) ||
01841         !dpmi_unlock_region ((void*)&_pkt_inf, sizeof(_pkt_inf)))
01842        return (-1);
01843     return (0);
01844   }
01845 #endif
01846 #endif  /* !USE_FAST_PKT */
01847
01848
01849 /*
01850  * For DOS4GW targets, allocate the '_pkt_inf' structure
01851  * from DOS memory. All others allocate from heap.
01852  */
01853 static int setup_pkt_inf (void)
01854 {
01859   int size = sizeof (*_pkt_inf);
01860
01861 #if (DOSX & DOS4GW) && !defined(USE_FAST_PKT)
01862   DWORD seg;
01863
01864   WATT_ASSERT (size < USHRT_MAX); /* max alloc from DOS is 64k */
01865
01866   seg = dpmi_real_malloc (size, &pkt_inf_sel);
01867
01868   asmpkt_inf = (struct pkt_info*) (seg << 16); /* run-time location */
01869   _pkt_inf   = (struct pkt_info*) (seg << 4);
01870
01871 #else
01872   _pkt_inf = malloc (size);
01873 #endif
01874
01875   if (!_pkt_inf)   /* Allocation failed */
01876      return (0);
01877
01878   memset (_pkt_inf, 0, size);   /* Clear area */
01879
01880 #if defined(USE_FAST_PKT)
01881   rm_base = setup_pkt_inf_fast();
01882   if (!rm_base)
01883      return (0);
01884
01885 #else
01886   pktq_init (&_pkt_inf->pkt_queue,
01887              sizeof(_pkt_inf->rx_buf[0]),  /* RX_SIZE */
01888              DIM(_pkt_inf->rx_buf),        /* RX_BUFS */
01889              (char*)&_pkt_inf->rx_buf);
01890 #endif
01891
01892 #if (DOSX & DOS4GW) && !defined(USE_FAST_PKT)
01893   _pkt_inf->pkt_queue.dos_ofs = offsetof (struct pkt_info, rx_buf[0]);
01894 #elif (DOSX & DJGPP)
01895   _pkt_inf->dos_ds = _dos_ds;
01896 #endif
01897
01898 #if (DOSX & DJGPP)
01899   if (pkt_use_near)
01900   {
01901     if (!(_crt0_startup_flags & _CRT0_FLAG_NEARPTR))
01902        TCP_CONSOLE_MSG (1, ("Near-pointers not enabled\n"));
01903     else
01904     {
01905       _pkt_inf->use_near_ptr = TRUE;
01906       TCP_CONSOLE_MSG (1, ("Near-pointers enabled\n"));
01907     }
01908   }
01909   else if (_crt0_startup_flags & _CRT0_FLAG_NEARPTR)
01910        TCP_CONSOLE_MSG (1, ("Near-pointers on, but \"PKT.NEAR_PTR = 0\"\n"));
01911 #endif
01912
01913   return (1);
01914 }
01915
01916
01920 static void get_rmode_data (void *dest, unsigned size, WORD seg, WORD ofs)
01921 {
01922 #if (DOSX & (PHARLAP|X32VM|POWERPAK))
01923   REALPTR rp;
01924   RP_SET (rp, ofs, seg);
01925   ReadRealMem (dest, rp, size);
01926
01927 #elif (DOSX & DOS4GW)
01928   memcpy (dest, SEG_OFS_TO_LIN(seg,ofs), size);
01929
01930 #elif (DOSX & DJGPP)
01931   dosmemget (ofs + (seg << 4), size, dest);
01932
01933 #else
01934   _fmemcpy (dest, MK_FP(seg,ofs), size);
01935 #endif
01936 }
01937
01938
01946 static BOOL pkt_api_entry (IREGS *reg, unsigned line)
01947 {
01948   _pkt_errno = 0;
01949   reg->r_flags = 0;
01950
01951 #if (DOSX)
01952
01954   if (_pkt32_drvr)
01955   {
01956     if (!(*_pkt32_drvr)(reg))   /* call the pmode interface */
01957     {
01958       /* _pkt_errno should be set above */
01959       reg->r_flags |= CARRY_BIT;
01960       return (FALSE);
01961     }
01962     return (TRUE);
01963   }
01964 #endif
01965
01966   if (!pkt_interrupt)
01967   {
01968 #if defined(USE_DEBUG)
01969     fprintf (stderr, "%s (%d): API called after deinit.\n", __FILE__, line);
01970 #endif
01971     reg->r_flags |= CARRY_BIT;
01972     ARGSUSED (line);
01973     _pkt_errno = PDERR_BAD_COMMAND;
01974     return (FALSE);
01975   }
01976
01977   /* Use the 16-bit real-mode PKTDRVR API.
01978    */
01979   GEN_INTERRUPT (pkt_interrupt, reg);
01980
01981   if (reg->r_flags & CARRY_BIT)
01982   {
01983     _pkt_errno = hiBYTE (reg->r_dx);  /* DH has error-code */
01984     return (FALSE);
01985   }
01986   return (TRUE);
01987 }
01988
01989
02004 int pkt_set_rcv_mode (int mode)
02005 {
02006   IREGS regs;
02007
02008   if (!_pkt_inf)
02009   {
02010     _pkt_errno = PDERR_BAD_HANDLE;
02011     return (0);
02012   }
02013
02014   regs.r_ax = PD_SET_RCV;
02015   regs.r_bx = _pkt_inf->handle;
02016   regs.r_cx = mode;
02017
02018   /* This needs an Extended driver. SLIP/PPP is point-to-point.
02019    */
02020   if (_pktdevlevel < 2 || _pktserial)
02021   {
02022     _pkt_errno = PDERR_CANT_SET;
02023     return (0);
02024   }
02025
02026   if (!PKT_API(&regs))
02027   {
02028     PKT_ERR ("Error setting receiver mode: ", _pkt_errno);
02029     return (0);
02030   }
02031   _pkt_rxmode = mode;
02032   return (1);
02033 }
02034
02048 int pkt_get_rcv_mode (void)
02049 {
02050   IREGS regs;
02051
02052   ASSERT_PKT_INF (-1);
02053
02054   regs.r_ax = PD_GET_RCV;
02055   regs.r_bx = _pkt_inf->handle;
02056
02057   /* This needs an Extended driver (not SLIP/PPP)
02058    */
02059   if (_pktdevlevel < 2 || _pktserial)
02060   {
02061     _pkt_errno = PDERR_BAD_COMMAND;
02062     return (0);
02063   }
02064
02065   if (!PKT_API(&regs))
02066   {
02067     PKT_ERR ("Error getting receive mode: ", _pkt_errno);
02068     return (0);
02069   }
02070   _pkt_rxmode = regs.r_ax;
02071   return (regs.r_ax);
02072 }
02073
02074
02075 #if defined(USE_MULTICAST)
02076
02086 int pkt_get_multicast_list (mac_address *listbuf, int *lenp)
02087 {
02088   IREGS regs;
02089   int   len = *lenp;
02090
02091   ASSERT_PKT_INF (0);
02092
02093   regs.r_ax  = PD_GET_MULTI;
02094   _pkt_errno = PDERR_NO_MULTICAST;
02095
02096   /* Basic drivers don't support multicast
02097    */
02098   if (_pktdevlevel < 2 || _pktserial ||
02099       (got_params && pkt_params.multicast_avail == 0) ||
02100       !PKT_API(&regs))
02101   {
02102     if (debug_on > 0)
02103        PKT_ERR ("Error getting multicast list: ", _pkt_errno);
02104     return (0);
02105   }
02106
02107   if ((WORD)regs.r_cx == 0)  /* no MC addresses, okay */
02108   {
02109     memset (listbuf, 0, len);
02110     *lenp = 0;
02111     return (1);
02112   }
02113
02114   /* move it into the caller's buffer
02115    */
02116   DISABLE();
02117   len = min (len, (WORD)regs.r_cx);
02118   get_rmode_data (listbuf, len, regs.r_es, regs.r_di);
02119   *lenp = len;
02120   ENABLE();
02121   return (1);
02122 }
02123
02133 int pkt_set_multicast_list (const void *listbuf, int len)
02134 {
02135   IREGS regs;
02136   WORD  seg, ofs;
02137
02138   ASSERT_PKT_INF (0);
02139
02140   /* Basic drivers don't support multicast
02141    */
02142   if (_pktdevlevel < 2 || _pktserial ||
02143       (got_params && pkt_params.multicast_avail == 0)) /* no point in trying */
02144   {
02145     _pkt_errno = PDERR_NO_MULTICAST;
02146     return (0);
02147   }
02148
02149 #if (DOSX)
02150   if (len > PKT_TMP_SIZE)
02151   {
02152     _pkt_errno = PDERR_NO_SPACE;
02153     return (0);
02154   }
02155 #endif
02156
02157   DISABLE();
02158
02159 #if (DOSX & (PHARLAP|X32VM|POWERPAK))
02160   seg = RP_SEGM();
02161   ofs = PKT_TMP();
02162   WriteRealMem (rm_base + PKT_TMP(), (void*)listbuf, len);
02163
02164 #elif (DOSX & DOS4GW)
02165   seg = RP_SEGM();
02166   ofs = PKT_TMP();
02167   memcpy ((void*)(rm_base + PKT_TMP()), listbuf, len);
02168
02169 #elif (DOSX & DJGPP)
02170   seg = RP_SEGM();
02171   ofs = PKT_TMP();
02172   DOSMEMPUT (listbuf, len, rm_base + PKT_TMP());
02173
02174 #else
02175   seg = FP_SEG (listbuf);
02176   ofs = FP_OFF (listbuf);
02177 #endif
02178
02179   ENABLE();
02180
02181   regs.r_ax = PD_SET_MULTI;
02182   regs.r_cx = len;
02183   regs.r_es = seg;
02184   regs.r_di = ofs;
02185
02186   if (!PKT_API(&regs))
02187   {
02188     if (debug_on > 0)
02189        PKT_ERR ("Error setting multicast list: ", _pkt_errno);
02190     return (0);
02191   }
02192   return (1);
02193 }
02194 #endif /* USE_MULTICAST */
02195 #endif /* !WIN32 && !_WIN32 */
02196
Generated on Wed Jan 25 15:42:38 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/PCPKT.H Source File

SRC/PCPKT.H

Go to the documentation of this file.
00001
00003 #ifndef _w32_PCPKT_H
00004 #define _w32_PCPKT_H
00005
00006 #ifndef _w32_PCQUEUE_H
00007 #include "pcqueue.h"
00008 #endif
00009
00010 #ifndef _w32_PCSED_H
00011 #include "pcsed.h"
00012 #endif
00013
00014 /*
00015  * Common stuff for PKTDRVR and WinPcap interfaces
00016  */
00017 #if defined(USE_DEBUG)
00018   #define ASSERT_PKT_INF(rc) do {                                \
00019                                if (!_pkt_inf) {                  \
00020                                   fprintf (stderr, "%s (%u): "   \
00021                                            "_pkt_inf == NULL\n", \
00022                                            __FILE__, __LINE__);  \
00023                                   return (rc);                   \
00024                                }                                 \
00025                              } while (0)
00026 #else
00027   #define ASSERT_PKT_INF(rc) do {              \
00028                                if (!_pkt_inf)  \
00029                                   return (rc); \
00030                              } while (0)
00031 #endif
00032
00033 /*\struct PktStats
00034  *
00035  * Driver statistics.
00036  */
00037 struct PktStats {
00038        DWORD  in_packets;       /* # of packets received    */
00039        DWORD  out_packets;      /* # of packets transmitted */
00040        DWORD  in_bytes;         /* # of bytes received      */
00041        DWORD  out_bytes;        /* # of bytes transmitted   */
00042        DWORD  in_errors;        /* # of reception errors    */
00043        DWORD  out_errors;       /* # of transmission errors */
00044        DWORD  lost;             /* # of packets lost (RX)   */
00045      };
00046
00047 W32_FUNC const char *pkt_strerror (int code);
00048 W32_FUNC DWORD       pkt_dropped  (void);
00049
00050 W32_DATA WORD _pktdevclass;
00051 W32_DATA WORD _pkt_ip_ofs;
00052 W32_DATA BOOL _pktserial;
00053 W32_DATA char _pktdrvrname[];
00054 W32_DATA int  _pkt_rxmode;
00055 W32_DATA int  _pkt_rxmode0;
00056 W32_DATA int  _pkt_forced_rxmode;
00057 W32_DATA int  _pkt_errno;
00059 #if defined(WIN32)
00060
00061 #include "winpcap.h"
00062
00063 #else   /* rest of file */
00064
00065 /* Basic PD Functions.
00066  */
00067 #define PD_DRIVER_INFO  0x01FF
00068 #define PD_ACCESS       0x0200
00069 #define PD_RELEASE      0x0300
00070 #define PD_SEND         0x0400
00071 #define PD_TERMINATE    0x0500
00072 #define PD_GET_ADDRESS  0x0600
00073 #define PD_RESET        0x0700
00074
00075 /* Extended PD Functions (1.09+)
00076  */
00077 #define PD_GET_PARAM    0x0A00
00078 #define PD_ASY_SEND_109 0x0B00
00079 #define PD_ASY_SEND     0x0C00
00080 #define PD_ASY_DROP     0x0D00
00081 #define PD_SET_RCV      0x1400
00082 #define PD_GET_RCV      0x1500
00083 #define PD_SET_MULTI    0x1600
00084 #define PD_GET_MULTI    0x1700
00085 #define PD_GET_STATS    0x1800
00086 #define PD_SET_ADDR     0x1900
00087 #define PD_RAW_SEND     0x1A00
00088 #define PD_RAW_FLUSH    0x1B00
00089 #define PD_RAW_GET      0x1C00
00090 #define PD_SIGNAL       0x1D00
00091 #define PD_GET_STRUCT   0x1E00
00092 #define PD_GET_VJSTATS  0x8100
00094 /* Packet-Driver Error Returns.
00095  */
00096 #define PDERR_BAD_HANDLE      1
00097 #define PDERR_NO_CLASS        2
00098 #define PDERR_NO_TYPE         3
00099 #define PDERR_NO_NUMBER       4
00100 #define PDERR_BAD_TYPE        5
00101 #define PDERR_NO_MULTICAST    6
00102 #define PDERR_CANT_TERMINATE  7
00103 #define PDERR_BAD_MODE        8
00104 #define PDERR_NO_SPACE        9
00105 #define PDERR_TYPE_INUSE     10
00106 #define PDERR_BAD_COMMAND    11
00107 #define PDERR_CANT_SEND      12
00108 #define PDERR_CANT_SET       13
00109 #define PDERR_BAD_ADDRESS    14
00110 #define PDERR_CANT_RESET     15
00111 #define PDERR_BASIC_DVR      16
00112
00113 /* Packet-driver classes.
00114  */
00115 #define PDCLASS_ETHER     1
00116 #define PDCLASS_TOKEN     3
00117 #define PDCLASS_SLIP      6
00118 #define PDCLASS_ARCNET    8
00119 #define PDCLASS_AX25      9
00120 #define PDCLASS_FDDI      12
00121 #define PDCLASS_TOKEN_RIF 17
00122 #define PDCLASS_PPP       18
00123 #define PDCLASS_UNKNOWN   0xFFFF
00124
00125 enum ReceiveModes {
00126      RXMODE_OFF        = 1,
00127      RXMODE_DIRECT     = 2,
00128      RXMODE_BROADCAST  = 3,
00129      RXMODE_MULTICAST1 = 4,
00130      RXMODE_MULTICAST2 = 5,
00131      RXMODE_PROMISCOUS = 6
00132    };
00133
00134 extern BYTE _pktdevlevel;
00136 extern int   pkt_eth_init      (mac_address *eth);
00137 extern int   pkt_release       (void);
00138 extern int   pkt_release_handle(WORD);
00139 extern int   pkt_reset_handle  (WORD handle);
00140 extern int   pkt_send          (const void *tx, int length);
00141 extern int   pkt_buf_wipe      (void);
00142 extern void  pkt_free_pkt      (const void *pkt);
00143 extern int   pkt_waiting       (void);
00144 extern int   pkt_set_addr      (const void *eth);
00145 extern int   pkt_get_addr      (mac_address *eth);
00146 extern int   pkt_get_mtu       (void);
00147 extern int   pkt_get_drvr_ver  (DWORD *ver);
00148 extern int   pkt_get_api_ver   (DWORD *ver);
00149 extern int   pkt_get_vector    (void);
00150 extern int   pkt_set_rcv_mode  (int mode);
00151 extern int   pkt_get_rcv_mode  (void);
00152 extern DWORD pkt_dropped       (void);
00153
00154 #if defined(USE_MULTICAST)
00155   extern int pkt_get_multicast_list (mac_address *listbuf, int *len);
00156   extern int pkt_set_multicast_list (const void *listbuf, int len);
00157 #endif
00158
00159 #include <sys/packon.h>       /* cstate, slcompress etc. must be packed */
00160
00161 /*\struct PktParameters
00162  *
00163  * PKTDRVR parameters.
00164  */
00165 struct PktParameters {
00166        BYTE  major_rev;       /* Revision of Packet Driver spec */
00167        BYTE  minor_rev;       /*  this driver conforms to. */
00168        BYTE  length;          /* Length of structure in bytes */
00169        BYTE  addr_len;        /* Length of a MAC-layer address */
00170        WORD  mtu;             /* MTU, including MAC headers */
00171        WORD  multicast_avail; /* Buffer size for multicast addr */
00172        WORD  rcv_bufs;        /* (# of back-to-back MTU rcvs) - 1 */
00173        WORD  xmt_bufs;        /* (# of successive xmits) - 1 */
00174        WORD  int_num;         /* interrupt for post-EOI processing */
00175      };
00176
00177 extern int pkt_get_params (struct PktParameters *params);
00178 extern int pkt_get_stats  (struct PktStats *stats, struct PktStats *total);
00179
00180
00181 /*\struct cstate
00182  *
00183  * Statistics returned from DOS-PPP.
00184  *
00185  * "state" data for each active tcp conversation on the wire.  This is
00186  * basically a copy of the entire IP/TCP header from the last packet
00187  * we saw from the conversation together with a small identifier
00188  * the transmit & receive ends of the line use to locate saved header.
00189  */
00190 struct cstate {
00191        BYTE       cs_this;       /* connection id number (xmit) */
00192        WORD       cs_next;       /* next in ring (xmit) */
00193        in_Header  cs_ip;         /* ip/tcp hdr from most recent packet */
00194        tcp_Header cs_tcp;
00195        BYTE       cs_ipopt[40];
00196        BYTE       cs_tcpopt[40];
00197      };
00198
00199 /*\struct slcompress
00200  *
00201  * Serial line compression statistics.
00202  */
00203 struct slcompress {
00204        WORD  cstate_ptr_tstate;  /* transmit connection states (DOSPPP is small model) */
00205        WORD  cstate_ptr_rstate;  /* receive connection states */
00206
00207        BYTE  tslot_limit;        /* highest transmit slot id (0-l) */
00208        BYTE  rslot_limit;        /* highest receive slot id (0-l) */
00209
00210        BYTE  xmit_oldest;        /* oldest xmit in ring */
00211        BYTE  xmit_current;       /* most recent xmit id */
00212        BYTE  recv_current;       /* most recent rcvd id */
00213        BYTE  flags;
00214
00215        DWORD sls_o_nontcp;       /* outbound non-TCP packets */
00216        DWORD sls_o_tcp;          /* outbound TCP packets */
00217        DWORD sls_o_uncompressed; /* outbound uncompressed packets */
00218        DWORD sls_o_compressed;   /* outbound compressed packets */
00219        DWORD sls_o_searches;     /* searches for connection state */
00220        DWORD sls_o_misses;       /* times couldn't find conn. state */
00221
00222        DWORD sls_i_uncompressed; /* inbound uncompressed packets */
00223        DWORD sls_i_compressed;   /* inbound compressed packets */
00224        DWORD sls_i_error;        /* inbound error packets */
00225        DWORD sls_i_tossed;       /* inbound packets tossed because of error */
00226
00227        DWORD sls_i_runt;         /* inbound packets too short */
00228        DWORD sls_i_badcheck;     /* inbound IP-packets with chksum error */
00229      };
00230
00231 extern int pkt_get_vjstats (struct slcompress *vjstats);
00232 extern int pkt_get_cstate  (struct cstate *cs, WORD cstate_ofs);
00233
00234
00235 /*\struct async_iocb
00236  *
00237  * I/O structure for asynchronous transmit function (v1.11, AH = 12)
00238  * (not used)
00239  */
00240 struct async_iocb {
00241        DWORD buffer;          /* Pointer to xmit buffer */
00242        WORD  length;          /* Length of buffer */
00243        BYTE  flagbits;        /* Flag bits */
00244        BYTE  code;            /* Error code */
00245        DWORD xmit_func;       /* Transmitter upcall */
00246        char  reserved[4];     /* Future gather-write data */
00247        char  private[8];      /* Driver's private data */
00248      };
00249
00250 #define ASY_DONE   1  /* packet driver is done with this iocb */
00251 #define ASY_UPCALL 2  /* requests an upcall when the buffer is re-usable */
00252
00253 /*\struct pkt_info
00254  *
00255  * Placeholder for vital data accessed on packet-driver upcall.
00256  *
00257  * Keep it gathered to simplify locking memory at `_pkt_inf'.
00258  * For DOS4GW targets; this structure \b MUST match same structure
00259  *                     in \b asmpkt4.asm.
00260  */
00261 struct pkt_info {
00262        WORD   rm_sel, rm_seg, rm_ofs; /* real selector, segment, ofs */
00263        WORD   dos_ds;                 /* copy of _dos_ds */
00264        WORD   use_near_ptr;           /* near-pointers enabled */
00265        WORD   handle;                 /* Packet-driver handle */
00266        WORD   is_serial;              /* duplicated from _pktserial */
00267        WORD   pkt_ip_ofs;             /* store length of MAC-header */
00268        WORD   pkt_type_ofs;           /* offset to MAC-type */
00269        struct pkt_ringbuf pkt_queue;  /* Ring-struct for enqueueing */
00270
00271 #if !defined(USE_FAST_PKT)
00272        /* USE_FAST_PKT uses a single rx_buf in pcpkt2.c
00273         */
00274        struct pkt_rx_element rx_buf [RX_BUFS];
00275 #endif
00276      };
00277
00278 extern struct pkt_info *_pkt_inf;
00279
00280 #include <sys/packoff.h>       /* restore default packing */
00281
00282 /*
00283  * sizeof(*_pkt_inf), __LARGE__
00284  * 3*2         = 6
00285  * 16          = 16
00286  * 5*1524      = 7620
00287  *             = 7642
00288  *
00289  * sizeof(*_pkt_inf), DOS4GW
00290  * 3*2             = 6
00291  * 26              = 26
00292  * 20*(14+1500+10) = 30480
00293  *                 = 30512
00294  */
00295
00296 #if (DOSX & (DOS4GW|X32VM|DJGPP))
00297   extern void *pkt_tx_buf (void);
00298 #endif
00299
00300 #if defined(USE_FAST_PKT)
00301   extern int  pkt_append_recv (const void *tx, unsigned len);
00302   extern int  pkt_buffers_used (void);
00303   extern int  pkt_test_upcall  (void);
00304   extern void pkt_dump_real_mem(void);
00305
00306   extern struct pkt_rx_element *pkt_poll_recv (void);
00307 #endif
00308
00309
00310 #define ROUND_UP32(sz)  (4 * (((sz) + 3) / 4))
00311
00312 #if (DOSX & DJGPP)
00313   #if !defined(WATT32_DOS_DLL)
00314     extern void __dj_movedata (void); /* called by __movedata() */
00315     extern void __movedata (unsigned src_sel, unsigned src_ofs,
00316                             unsigned dst_sel, unsigned dst_ofs,
00317                             size_t bytes);
00318   #endif
00319
00320   #define DOSMEMGET(ofs,len,buf)  __movedata (_pkt_inf->dos_ds,   \
00321                                               (unsigned)(ofs),    \
00322                                               (unsigned)_my_ds(), \
00323                                               (unsigned)(buf),    \
00324                                               len)
00325   #define DOSMEMGETL(ofs,d32,buf) _movedatal (_pkt_inf->dos_ds,   \
00326                                               (unsigned)(ofs),    \
00327                                               (unsigned)_my_ds(), \
00328                                               (unsigned)(buf),    \
00329                                               d32)
00330   #define DOSMEMPUT(buf,len,ofs)  __movedata ((unsigned)_my_ds(), \
00331                                               (unsigned)(buf),    \
00332                                               _pkt_inf->dos_ds,   \
00333                                               (unsigned)(ofs),    \
00334                                               len)
00335   #define DOSMEMPUTL(buf,d32,ofs) _movedatal ((unsigned)_my_ds(), \
00336                                               (unsigned)(buf),    \
00337                                               _pkt_inf->dos_ds,   \
00338                                               (unsigned)(ofs),    \
00339                                               d32)
00340
00341   #define DOSMEMCLR(ofs,len)                      \
00342           do {                                    \
00343             int i = ROUND_UP32 (len) - 4;         \
00344             _farsetsel (_dos_ds); /* FS=dos DS */ \
00345             for ( ; i >= 0; i -= 4)               \
00346                 _farnspokel (ofs+i, 0L);          \
00347           } while (0)
00348
00349 #endif  /* (DOSX & DJGPP) */
00350 #endif  /* WIN32 */
00351 #endif
00352
Generated on Wed Jan 25 15:42:38 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/PCPKT32.C Source File

SRC/PCPKT32.C

Go to the documentation of this file.
00001
00036 #include <stdio.h>
00037 #include <stdlib.h>
00038
00039 /* Nothing of this is needed for Win32.
00040  * Refer winpcap.c instead.
00041  */
00042 #if !defined(WIN32) && !defined(_WIN32)
00043
00044 #include "wattcp.h"
00045 #include "pcconfig.h"
00046 #include "wdpmi.h"
00047 #include "x32vm.h"
00048 #include "misc.h"
00049 #include "pcsed.h"
00050 #include "pcpkt.h"
00051 #include "pcpkt32.h"
00052
00053 #if (DOSX)
00054
00055 int (*_pkt32_drvr)(IREGS*) = NULL;
00056
00057 struct PM_driver pm_driver_list[] = {
00058                  { PM_DRVR_3C501,   "3c501"   },
00059                  { PM_DRVR_3C503,   "3c503"   },
00060                  { PM_DRVR_3C505,   "3c505"   },
00061                  { PM_DRVR_3C507,   "3c507"   },
00062                  { PM_DRVR_3C5x9,   "3c5x9"   },
00063                  { PM_DRVR_3C59x,   "3c59x"   },
00064                  { PM_DRVR_NE2000,  "NE2000"  },
00065                  { PM_DRVR_EEXPR,   "EthExp"  },
00066                  { PM_DRVR_RTL8139, "RTL8139" },
00067                  { 0,               NULL      }
00068                };
00069
00070 int pkt32_drvr_probe (const PM_driver *drivers)
00071 {
00072   ARGSUSED (drivers);
00073   return (-1);
00074 }
00075
00076 int pkt32_drvr_init (int driver, mac_address *addr)
00077 {
00078   ARGSUSED (driver);
00079   ARGSUSED (addr);
00080   return (-1);
00081 }
00082
00083 const char *pkt32_drvr_name (int driver)
00084 {
00085   int i;
00086   for (i = 0; pm_driver_list[i].type; i++)
00087       if (pm_driver_list[i].type == driver)
00088          return (pm_driver_list[i].name);
00089
00090   return ("unknown");
00091 }
00092
00093 #endif  /* DOSX */
00094 #endif  /* !WIN32 && !_WIN32 */
00095
Generated on Wed Jan 25 15:42:38 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/PCPKT32.H Source File

SRC/PCPKT32.H

Go to the documentation of this file.
00001
00003 #if !defined(_w32_PCPKT32_H) && (DOSX)
00004 #define _w32_PCPKT32_H
00005
00006 #define PM_DRVR_3C501    1  /* 3COM EtherLink I, a real museum piece! */
00007 #define PM_DRVR_3C503    2
00008 #define PM_DRVR_3C505    3  /* 3COM EtherLink II */
00009 #define PM_DRVR_3C507    4
00010 #define PM_DRVR_3C5x9    5  /* 3COM EtherLink III, ISA */
00011 #define PM_DRVR_3C59x    6  /* 3COM EtherLink III, PCI */
00012 #define PM_DRVR_NE2000   7  /* NE2000 compatible cards */
00013 #define PM_DRVR_EEXPR    8  /* Intel EtherExpress */
00014 #define PM_DRVR_RTL8139  9  /* RealTek RTL8139 */
00015
00018 typedef struct PM_driver {
00019         int         type;
00020         const char *name;
00021       } PM_driver;
00022
00023 extern int (*_pkt32_drvr)(IREGS*);
00024
00025 extern struct PM_driver pm_driver_list[];
00026
00027 extern int         pkt32_drvr_probe (const PM_driver *drivers);
00028 extern int         pkt32_drvr_init  (int driver, mac_address *addr);
00029 extern const char *pkt32_drvr_name  (int driver);
00030
00031 #endif
00032
Generated on Wed Jan 25 15:42:38 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/PCQUEUE.C Source File

SRC/PCQUEUE.C

Go to the documentation of this file.
00001
00035 #include <stdio.h>
00036 #include <stdlib.h>
00037 #include <stddef.h>
00038
00039 #include "wattcp.h"
00040 #include "strings.h"
00041 #include "misc.h"
00042 #include "x32vm.h"
00043 #include "powerpak.h"
00044 #include "pcpkt.h"
00045 #include "pcqueue.h"
00046
00047 #if defined(USE_DEBUG)
00048 int pktq_check (struct pkt_ringbuf *q)
00049 {
00050   int   i;
00051   char *buf;
00052
00053   if (!q || !q->num_buf || !q->buf_start)
00054      return (0);
00055
00056   buf = (char*) q->buf_start;
00057
00058   for (i = 0; i < q->num_buf; i++)
00059   {
00060     buf += q->buf_size;
00061     if (*(DWORD*)(buf - sizeof(DWORD)) != PKTQ_MARKER)
00062        return (0);
00063   }
00064   return (1);
00065 }
00066 #endif  /* USE_DEBUG */
00067
00068
00069 int pktq_init (struct pkt_ringbuf *q, int size, int num, char *buf)
00070 {
00071   q->buf_size  = size;
00072   q->num_buf   = num;
00073   q->buf_start = (DWORD) buf;
00074   q->in_index  = 0;
00075   q->out_index = 0;
00076 #if (DOSX & DOS4GW)
00077   q->dos_ofs = 0;   /* must be set manually */
00078 #endif
00079
00080 #if defined(USE_DEBUG)
00081   WATT_ASSERT (size > 0);
00082   WATT_ASSERT (num > 0);
00083   WATT_ASSERT (buf != NULL);
00084   {
00085     int i;
00086     for (i = 0; i < q->num_buf; i++)
00087     {
00088       buf += q->buf_size;
00089       *(DWORD*) (buf - sizeof(DWORD)) = PKTQ_MARKER;
00090     }
00091   }
00092 #endif
00093   return (1);
00094 }
00095
00096 /*
00097  * Increment the queue 'in_index' (head).
00098  * Check for wraps.
00099  */
00100 int pktq_inc_in (struct pkt_ringbuf *q)
00101 {
00102   q->in_index++;
00103   if (q->in_index >= q->num_buf)
00104       q->in_index = 0;
00105   return (q->in_index);
00106 }
00107
00108 /*
00109  * Increment the queue 'out_index' (tail).
00110  * Check for wraps.
00111  */
00112 int pktq_inc_out (struct pkt_ringbuf *q)
00113 {
00114   q->out_index++;
00115   if (q->out_index >= q->num_buf)
00116       q->out_index = 0;
00117   return (q->out_index);
00118 }
00119
00120 /*
00121  * Return the queue's next 'in_index' (head).
00122  * Check for wraps. Caller is responsible for using cli/sti
00123  * around this function when needed.
00124  */
00125 int pktq_in_index (struct pkt_ringbuf *q)
00126 {
00127   int index = q->in_index + 1;
00128
00129   if (index >= q->num_buf)
00130       index = 0;
00131   return (index);
00132 }
00133
00134 /*
00135  * Return the queue's head-buffer.
00136  * Should be interruptable because 'in_index' is 'volatile'.
00137  */
00138 char *pktq_in_buf (struct pkt_ringbuf *q)
00139 {
00140   return ((char*)q->buf_start + (q->buf_size * q->in_index));
00141 }
00142
00143 /*
00144  * Return the queue's tail-buffer.
00145  */
00146 char *pktq_out_buf (struct pkt_ringbuf *q)
00147 {
00148   return ((char*)q->buf_start + (q->buf_size * q->out_index));
00149 }
00150
00151
00152 /*
00153  * Clear the queue ring-buffer by setting head=tail.
00154  */
00155 void pktq_clear (struct pkt_ringbuf *q)
00156 {
00157 #if defined(USE_FAST_PKT) && !defined(WIN32)
00158   WORD out_ofs;
00159
00160   DISABLE();
00161   out_ofs = FAR_PEEK_WORD (struct pkt_info, pkt_queue.out_index);
00162   FAR_POKE_WORD (struct pkt_info, pkt_queue.in_index, out_ofs);
00163   ENABLE();
00164   ARGSUSED (q);
00165 #else
00166   DISABLE();
00167   q->in_index = q->out_index;
00168   ENABLE();
00169 #endif
00170 }
00171
00172 /*
00173  * Return number of buffers waiting in queue. Check for wraps.
00174  * Should be interruptable because 'in_index' is 'volatile'.
00175  */
00176 int pktq_queued (struct pkt_ringbuf *q)
00177 {
00178   register int index = q->out_index;
00179   register int num   = 0;
00180
00181   DISABLE();
00182
00183   while (index != q->in_index)
00184   {
00185     num++;
00186     if (++index >= q->num_buf)
00187        index = 0;
00188   }
00189   ENABLE();
00190   return (num);
00191 }
00192
00193
00194 #if defined(USE_FAST_PKT) && !defined(WIN32)
00195
00196 #if (DOSX == 0)
00197 #error USE_FAST_PKT is not for real-mode targets.
00198 #endif
00199
00200 DWORD asmpkt_rm_base;
00201
00202 #if defined(USE_DEBUG)
00203 int pktq_far_check (struct pkt_ringbuf *q)
00204 {
00205   DWORD buf_start, buf, marker;
00206   int   i, size;
00207
00208   i = FAR_PEEK_WORD (struct pkt_info, pkt_queue.num_buf);
00209   if (i != q->num_buf)
00210   {
00211     (*_printf) ("pktq_far_check(): num = %d\n", i);
00212     pkt_dump_real_mem();
00213     return (0);
00214   }
00215
00216   buf  = FAR_PEEK_DWORD (struct pkt_info, pkt_queue.buf_start);
00217   size = FAR_PEEK_WORD (struct pkt_info, pkt_queue.buf_size);
00218   buf_start = buf;
00219
00220   for (i = 0; i < q->num_buf; i++)
00221   {
00222     buf += size;
00223
00224     if (buf < asmpkt_rm_base || buf > asmpkt_rm_base + 64*1024)
00225     {
00226       (*_printf) ("pktq_far_check(): illegal buf = %08lX, size %d\n",
00227                   buf, size);
00228       pkt_dump_real_mem();
00229       return (0);
00230     }
00231     marker = PEEKL (0, buf - sizeof(DWORD));
00232     if (marker != PKTQ_MARKER)
00233     {
00234       (*_printf) ("pktq_far_check(): size = %d, buf_start = %08lX, "
00235                   "marker[%d] = %08lX\n", size, buf_start, i, marker);
00236       pkt_dump_real_mem();
00237       return (0);
00238     }
00239   }
00240   return (1);
00241 }
00242 #endif  /* USE_DEBUG */
00243
00244
00245 int pktq_far_init (int size, int num, DWORD real_base)
00246 {
00247   struct pkt_ringbuf q;
00248   DWORD  dos_addr;
00249   size_t rx_buf_ofs = sizeof(struct pkt_info);  /* rx_buf[] after _pkt_inf */
00250   int    i;
00251
00252   memset (&q, 0, sizeof(q));
00253   q.buf_size  = size;
00254   q.buf_start = real_base + rx_buf_ofs;
00255   q.num_buf   = num;
00256   q.dos_ofs   = rx_buf_ofs;
00257   asmpkt_rm_base = real_base;
00258
00259   WATT_ASSERT (size > 0);
00260   WATT_ASSERT (num > 0);
00261
00262   for (i = 0; i < q.num_buf; i++)
00263   {
00264     real_base += q.buf_size;
00265     POKEL (0, q.dos_ofs + real_base - sizeof(DWORD), PKTQ_MARKER);
00266   }
00267
00268   dos_addr = asmpkt_rm_base + offsetof(struct pkt_info,pkt_queue);
00269
00270 #if (DOSX & (PHARLAP|X32VM|POWERPAK))
00271   WriteRealMem (dos_addr, &q, sizeof(q));
00272 #elif (DOSX & DOS4GW)
00273   memcpy ((void*)dos_addr, &q, sizeof(q));
00274 #elif (DOSX & DJGPP)
00275   dosmemput (&q, sizeof(q), dos_addr);
00276 #else
00277   #error Help!
00278 #endif
00279   return (1);
00280 }
00281 #endif /* USE_FAST_PKT && !WIN32 */
Generated on Wed Jan 25 15:42:38 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/PCQUEUE.H Source File

SRC/PCQUEUE.H

Go to the documentation of this file.
00001
00003 #ifndef _w32_PCQUEUE_H
00004 #define _w32_PCQUEUE_H
00005
00006 #include <stddef.h>
00007
00008 #ifndef __SYS_WTIME_H
00009 #include <sys/wtime.h>
00010 #endif
00011
00012 #ifndef _w32_PCSED_H
00013 #include "pcsed.h"
00014 #endif
00015
00019 #if defined(WIN32)
00020   /*
00021    * \todo Make RX_BUFS (i.e. size of thread queue) configurable.
00022    * Only the NPF kernel-buffer size is configurable now (pkt_num_rx_bufs).
00023    */
00024   #define RX_BUFS    20
00025
00026 #elif defined(USE_FAST_PKT)
00027   #define RX_BUFS    40    /* max # that will fit in 64 kB */
00028
00029 #elif (DOSX)
00030   #if (DOSX & DOS4GW)      /* allocation from DOS is limited to 64kB */
00031     #define RX_BUFS  30
00032   #else
00033     #define RX_BUFS  50    /* # of receive buffers to use in queue */
00034   #endif                   /* should be greater than MAX_FRAGMENT */
00035
00036 #else
00037   #define RX_BUFS    5
00038 #endif
00039
00040 #if (DOSX)
00041   #define PKT_TMP_SIZE 64  /* scratch buffer only needed for DOSX */
00042 #endif
00043
00044 #define PKTQ_MARKER  0xDEAFBABE
00045
00046
00047 /*
00048  * asmpkt4.asm depends on these structs beeing packed
00049  */
00050 #if (DOSX & DOS4GW) || defined(USE_FAST_PKT)
00051 #include <sys/packon.h>
00052 #endif
00053
00054 #if defined(WIN32)
00055   struct pkt_rx_element {
00056          struct timeval tstamp_put;  /* timestamp from NPF */
00057          struct timeval tstamp_get;  /* timestamp when polled */
00058          WORD   rx_length;           /* length from PacketReceivePacket() */
00059          BYTE   rx_buf [ETH_MAX+10]; /* add some margin */
00060        };
00061 #else
00062   struct pkt_rx_element {
00063          DWORD  tstamp_put[2];       /* RDTSC timestamp on 1st upcall */
00064          DWORD  tstamp_get[2];       /* RDTSC timestamp when polled */
00065          WORD   handle;              /* Packet-driver handle of upcall */
00066          WORD   rx_length_1;         /* length on 1st upcall */
00067          WORD   rx_length_2;         /* length on 2nd upcall */
00068          WORD   filler;              /* 4 byte alignment */
00069          BYTE   rx_buf [ETH_MAX+10]; /* add some margin */
00070        };  /* = 1548 bytes */
00071 #endif
00072
00073 /* DOS: 1524+24=1548
00074  */
00075 #define RX_SIZE               sizeof(struct pkt_rx_element)
00076 #define RX_ELEMENT_HEAD_SIZE  offsetof (struct pkt_rx_element, rx_buf[0])
00077
00081 struct pkt_ringbuf {
00082        volatile WORD  in_index;   /* index *ahead* of last buffer put */
00083        WORD           out_index;  /* index of buffer pulled out */
00084        WORD           buf_size;   /* size of each buffer */
00085        WORD           num_buf;    /* number of buffers */
00086        volatile DWORD num_drop;   /* number of dropped pkts */
00087        DWORD          buf_start;  /* start of buffer pool (linear addr) */
00088 #if (DOSX & (DOS4GW|POWERPAK)) || defined(USE_FAST_PKT)
00089        WORD           dos_ofs;    /* offset of pool, used by rmode stub */
00090 #endif                            /* total size = 26 for DOS4GW/POWERPAK */
00091      };
00092
00093 #if (DOSX & DOS4GW) || defined(USE_FAST_PKT)
00094 #include <sys/packoff.h>
00095 #endif
00096
00097 extern int   pktq_inc_in  (struct pkt_ringbuf *q);
00098 extern int   pktq_inc_out (struct pkt_ringbuf *q);
00099 extern int   pktq_check   (struct pkt_ringbuf *q);
00100 extern void  pktq_clear   (struct pkt_ringbuf *q);
00101
00102 extern int   pktq_init     (struct pkt_ringbuf *q, int size, int num, char *buf);
00103 extern int   pktq_in_index (struct pkt_ringbuf *q);
00104 extern char *pktq_in_buf   (struct pkt_ringbuf *q);
00105 extern char *pktq_out_buf  (struct pkt_ringbuf *q);
00106 extern int   pktq_queued   (struct pkt_ringbuf *q);
00107
00108 #if defined(USE_FAST_PKT) && !defined(WIN32)
00109   extern DWORD asmpkt_rm_base;
00110
00111   /* macros to access runtime location of 'asmpkt_inf'
00112    */
00113   #define FAR_PEEK_WORD(struc,mbr)    PEEKW (0, asmpkt_rm_base + offsetof(struc,mbr))
00114   #define FAR_PEEK_DWORD(struc,mbr)   PEEKL (0, asmpkt_rm_base + offsetof(struc,mbr))
00115
00116   #define FAR_POKE_WORD(struc,mbr,x)  POKEW (0, asmpkt_rm_base + offsetof(struc,mbr), x)
00117   #define FAR_POKE_DWORD(struc,mbr,x) POKEL (0, asmpkt_rm_base + offsetof(struc,mbr), x)
00118
00119   extern int pktq_far_init   (int size, int num, DWORD asmpkt_real_base);
00120   extern int pktq_far_queued (void);
00121   extern int pktq_far_check  (struct pkt_ringbuf *q);
00122 #endif
00123
00124 #endif
Generated on Wed Jan 25 15:42:38 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/PCRARP.C Source File

SRC/PCRARP.C

Go to the documentation of this file.
00001
00013 #include <stdio.h>
00014 #include <string.h>
00015
00016 #include "copyrigh.h"
00017 #include "wattcp.h"
00018 #include "strings.h"
00019 #include "language.h"
00020 #include "misc.h"
00021 #include "timer.h"
00022 #include "rs232.h"
00023 #include "pcsed.h"
00024 #include "pctcp.h"
00025 #include "pcdbug.h"
00026 #include "pcrarp.h"
00027
00028 #if defined(USE_RARP)
00029
00030 WORD _rarptimeout = 5;
00031
00032 static int _rarp_request (void)
00033 {
00034   rarp_Header *rarp = (rarp_Header*) _eth_formatpacket (&_eth_brdcast[0],
00035                                                         RARP_TYPE);
00036   rarp->hwType       = intel16 (_eth_get_hwtype(NULL,NULL));
00037   rarp->protType     = IP4_TYPE;
00038   rarp->hwAddrLen    = sizeof (mac_address);
00039   rarp->protoAddrLen = sizeof (my_ip_addr);
00040   rarp->opcode       = RARP_REQUEST;
00041   rarp->srcIPAddr    = 0;
00042   rarp->dstIPAddr    = 0;
00043   memcpy (rarp->srcEthAddr, _eth_addr, sizeof(mac_address));
00044   memcpy (rarp->dstEthAddr, _eth_addr, sizeof(mac_address));
00045
00046   return _eth_send (sizeof(*rarp), NULL, __FILE__, __LINE__);
00047 }
00048
00052 BOOL _rarp_handler (const rarp_Header *rh, BOOL brdcast)
00053 {
00054   SIO_TRACE (("_rarp_handler"));
00055
00056   DEBUG_RX (NULL, rh);
00057
00058   if (!brdcast && rh->opcode == RARP_REPLY && rh->protType == IP4_TYPE &&
00059       !memcmp(rh->dstEthAddr,_eth_addr,sizeof(mac_address)))
00060   {
00061     my_ip_addr = intel (rh->dstIPAddr);
00062     return (TRUE);
00063   }
00064   return (FALSE);
00065 }
00066
00067 /*
00068  * _dorarp - Checks global variable _rarptimeout
00069  *           returns 1 on success and sets ip address
00070  */
00071 int _dorarp (void)
00072 {
00073   DWORD rarptimeout    = set_timeout (1000 * _rarptimeout);
00074   WORD  magictimeout   = Random (7000, 14000);
00075
00076   outs (_LANG("Configuring through RARP..."));
00077
00078   while (1)
00079   {
00080     DWORD sendtimeout;
00081
00082     if (!_rarp_request())
00083        break;
00084
00085     sendtimeout   = set_timeout (magictimeout);
00086     magictimeout += Random (1000, 7000);
00087
00088     while (!chk_timeout(sendtimeout))
00089     {
00090       const struct rarp_Header *rarp;
00091       WORD  eth_type;
00092       BOOL  bcast;
00093
00094       if (chk_timeout(rarptimeout))
00095          return (0);
00096
00097       WATT_YIELD();
00098
00099       rarp = (rarp_Header*) _eth_arrived (&eth_type, &bcast);
00100       if (!rarp)
00101          continue;
00102
00103       DEBUG_RX (NULL, rarp);
00104
00105       if (eth_type == RARP_TYPE && !bcast &&
00106           rarp->opcode == RARP_REPLY && rarp->protType == IP4_TYPE &&
00107           !memcmp(rarp->dstEthAddr,_eth_addr,sizeof(mac_address)))
00108       {
00109         my_ip_addr = intel (rarp->dstIPAddr);
00110         _eth_free (rarp);
00111         return (1);
00112       }
00113       _eth_free (rarp);
00114     }
00115   }
00116   return (0);
00117 }
00118 #endif
Generated on Wed Jan 25 15:42:38 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/PCRARP.H Source File

SRC/PCRARP.H

Go to the documentation of this file.
00001
00003 #ifndef _w32_PCRARP_H
00004 #define _w32_PCRARP_H
00005
00006 extern WORD _rarptimeout;
00007 extern int  _dorarp (void);
00008
00009 #endif
Generated on Wed Jan 25 15:42:38 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/PCRECV.C Source File

SRC/PCRECV.C

Go to the documentation of this file.
00001
00006 #include <stdio.h>
00007 #include <stdlib.h>
00008 #include <limits.h>
00009
00010 #include "wattcp.h"
00011 #include "strings.h"
00012 #include "language.h"
00013 #include "bsddbug.h"
00014 #include "misc.h"
00015 #include "pcsed.h"
00016 #include "pcbuf.h"
00017 #include "pctcp.h"
00018 #include "pcrecv.h"
00019
00020 #define RECV_USED    0xF7E3D2B1L
00021 #define RECV_UNUSED  0xE6D2C1AFL
00022
00023 /* UDP "sequence number" for finding the oldest packet.
00024  * Newest received has higher 'p->buf_seqnum' number
00025  */
00026 static long seq_num = 0;
00027
00028 /*
00029  * Gets upcalled when data arrives.
00030  * We MUST set 'p->buf_len = -1' to signal a 0-byte UDP packet
00031  * not 0
00032  */
00033 static int sock_recvdaemon (sock_type *s, const void *data, unsigned len,
00034                             const tcp_PseudoHeader *ph, const udp_Header *udp)
00035 {
00036   recv_data *r;
00037   recv_buf  *p;
00038   unsigned   i;
00039
00040   switch (s->udp.ip_type)
00041   {
00042     case UDP_PROTO:
00043          r = (recv_data*) s->udp.rx_data;
00044          p = (recv_buf*) r->recv_bufs;
00045          if (r->recv_sig != RECV_USED)
00046          {
00047            outsnl (_LANG("ERROR: udp recv data conflict"));
00048            return (0);
00049          }
00050          /* find an unused buffer
00051           */
00052          for (i = 0; i < r->recv_bufnum; i++, p++)
00053              switch (p->buf_sig)
00054              {
00055                case RECV_USED:
00056                     break;
00057                case RECV_UNUSED:  /* take this one */
00058                     p->buf_sig     = RECV_USED;
00059                     p->buf_hisport = udp->srcPort;
00060                     p->buf_seqnum  = seq_num++;
00061 #if defined(USE_IPV6)
00062                     if (s->udp.is_ip6)
00063                        memcpy (&p->buf_hisip6, &((tcp_PseudoHeader6*)ph)->src,
00064                                sizeof(p->buf_hisip6));
00065
00066                     else
00067 #endif
00068                        p->buf_hisip = ph->src;
00069                     len = min (len, sizeof(p->buf_data));
00070                     if (len > 0)
00071                     {
00072                       memcpy (p->buf_data, data, len);
00073                       p->buf_len = (short) len;
00074                     }
00075                     else
00076                       p->buf_len = -1;  /* a 0-byte probe */
00077 #if 0
00078                     SOCK_DEBUGF (("\nsock_recvdaemon(): buffer %d, "
00079                                   "seq-num %ld, len %d",
00080                                   i, seq_num-1, p->buf_len));
00081 #endif
00082                     return (0);
00083                default:
00084                     outsnl (_LANG("ERROR: sock_recv_daemon data err"));
00085                     return (0);
00086              }
00087          return (0);
00088
00089 #if !defined(USE_UDP_ONLY)
00090     case TCP_PROTO:
00091          {
00092            _tcp_Socket *t = &s->tcp;
00093
00094            r = (recv_data*) t->rx_data;
00095
00096            if (r->recv_sig != RECV_USED)
00097            {
00098              outsnl (_LANG("ERROR: tcp recv data conflict"));
00099              return (0);
00100            }
00101            /* stick it on the end if you can
00102             */
00103            i = t->max_rx_data - t->rx_datalen;
00104            if (i > 1)
00105            {
00106              /* we can accept some of this */
00107              if (len > i)
00108                  len = i;
00109              if (len > 0)
00110                 memcpy (r->recv_bufs + t->rx_datalen, data, len);
00111              t->rx_datalen += len;
00112              return (len);
00113            }
00114            return (0);   /* didn't take none */
00115          }
00116 #endif
00117   }
00118   return (0);
00119 }
00120
00121
00122 int sock_recv_used (const sock_type *s)
00123 {
00124   const recv_data *r;
00125   const recv_buf  *p;
00126
00127   int i, len;
00128
00129   switch (_chk_socket(s))
00130   {
00131     case VALID_UDP:
00132          r = (const recv_data*) s->udp.rx_data;
00133          p = (const recv_buf*) r->recv_bufs;
00134          if (r->recv_sig != RECV_USED)
00135             return (-1);
00136
00137          for (i = len = 0; i < r->recv_bufnum; i++, p++)
00138              if (p->buf_sig == RECV_USED)
00139                 len += abs (p->buf_len);   /* -1 -> 1 */
00140          return (len);
00141
00142 #if !defined(USE_UDP_ONLY)
00143     case VALID_TCP:
00144          r = (const recv_data*) s->tcp.rx_data;
00145          if (r->recv_sig != RECV_USED)
00146             return (-1);
00147          return (s->tcp.rx_datalen);
00148 #endif
00149   }
00150   return (0);
00151 }
00152
00153
00154 int sock_recv_init (sock_type *s, void *space, unsigned len)
00155 {
00156   recv_buf  *p = (recv_buf*) space;
00157   recv_data *r = (recv_data*) s->udp.rx_data;
00158   int i;
00159
00160   WATT_ASSERT ((DWORD)len <= USHRT_MAX);
00161   memset (r, 0, s->udp.max_rx_data);  /* clear Rx-buffer */
00162   memset (p, 0, len);                 /* clear data area */
00163
00164   s->udp.protoHandler = (ProtoHandler) sock_recvdaemon;
00165   r->recv_sig         = RECV_USED;
00166   r->recv_bufs        = (BYTE*) p;
00167   r->recv_bufnum      = (WORD) (len / sizeof(recv_buf));
00168
00169   if (s->udp.ip_type == UDP_PROTO)
00170      for (i = 0; i < r->recv_bufnum; i++, p++)
00171          p->buf_sig = RECV_UNUSED;
00172   return (0);
00173 }
00174
00175 int sock_recv_from (sock_type *s, void *hisip, WORD *hisport,
00176                     void *buffer, unsigned len, int peek)
00177 {
00178 #if !defined(USE_UDP_ONLY)
00179   _tcp_Socket *t;
00180 #endif
00181   recv_buf    *p, *oldest = NULL;
00182   recv_data   *r = (recv_data*) s->udp.rx_data;
00183   long seqnum = LONG_MAX;
00184   int  i;
00185
00186   if (r->recv_sig != RECV_USED)
00187   {
00188     SOCK_ERRNO (EBADF);
00189
00190     /* To differentiate an error from 0-byte probe (also -1) */
00191     return (-1);
00192   }
00193
00194   switch (s->udp.ip_type)
00195   {
00196     case UDP_PROTO:
00197          p = (recv_buf*) r->recv_bufs;
00198
00199          /* find the oldest used UDP buffer.
00200           */
00201          for (i = 0; i < r->recv_bufnum; i++, p++)
00202          {
00203            switch (p->buf_sig)
00204            {
00205              case RECV_UNUSED:
00206                   break;
00207
00208              case RECV_USED:
00209                   /* Drop looped packets sent by us (running
00210                    * under Win32 DOS box using NDIS3PKT or SwsVpkt).
00211                    */
00212                   if ((_eth_ndis3pkt || _eth_SwsVpkt) &&
00213                       !s->tcp.is_ip6 && p->buf_hisip == intel(my_ip_addr))
00214                   {
00215                     p->buf_sig = RECV_UNUSED;
00216                     continue;
00217                   }
00218                   if (p->buf_seqnum < seqnum)  /* ignore wraps */
00219                   {
00220                     seqnum = p->buf_seqnum;
00221                     oldest = p;
00222 #if 0
00223                     SOCK_DEBUGF (("\nsock_recv_from(): buffer %d, "
00224                                   "seq-num %ld, len %d",
00225                                   i, seqnum, p->buf_len));
00226 #endif
00227                   }
00228                   break;
00229
00230              default:
00231                   outsnl (_LANG("ERROR: sock_recv_init data err"));
00232                   return (0);
00233            }
00234          }
00235          break;
00236
00237 #if !defined(USE_UDP_ONLY)
00238     case TCP_PROTO:
00239          t = &s->tcp;
00240          len = min (len, (unsigned)t->rx_datalen);
00241          if (len)
00242              memcpy (buffer, r->recv_bufs, len);
00243          return (len);
00244 #endif
00245   }
00246
00247   if (!oldest)
00248      return (0);
00249
00250   /* found the oldest UDP packet */
00251
00252   p = oldest;
00253   if (p->buf_len < 0)  /* a 0-byte probe packet */
00254      len = -1;
00255   else
00256   {
00257     len = min ((unsigned)p->buf_len, len);
00258     memcpy (buffer, p->buf_data, len);
00259   }
00260
00261 #if defined(USE_IPV6)
00262   if (s->tcp.is_ip6)
00263   {
00264     if (hisip)
00265        memcpy (hisip, &p->buf_hisip6, sizeof(ip6_address));
00266   }
00267   else
00268 #endif
00269   if (hisip)
00270      *(DWORD*)hisip = p->buf_hisip;
00271
00272   if (hisport)
00273      *hisport = p->buf_hisport;
00274
00275   if (!peek)
00276      p->buf_sig = RECV_UNUSED;
00277   return (len);
00278 }
00279
00280
00281 int sock_recv (sock_type *s, void *buffer, unsigned len)
00282 {
00283   return sock_recv_from (s, NULL, NULL, buffer, len, 0);
00284 }
00285
Generated on Wed Jan 25 15:42:38 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/PCRECV.H Source File

SRC/PCRECV.H

Go to the documentation of this file.
00001
00003 #ifndef _w32_PCRECV_H
00004 #define _w32_PCRECV_H
00005
00008 typedef struct recv_data {
00009         DWORD  recv_sig;
00010         BYTE  *recv_bufs;
00011         WORD   recv_bufnum;
00012       } recv_data;
00013
00016 typedef struct recv_buf {
00017         DWORD       buf_sig;
00018         DWORD       buf_hisip;
00019         long        buf_seqnum;
00020 #if defined(USE_IPV6)
00021         ip6_address buf_hisip6;
00022 #endif
00023         WORD        buf_hisport;
00024         short       buf_len;
00025         BYTE        buf_data [ETH_MAX]; /* sock_packet_peek() needs 1514 */
00026       } recv_buf;
00027
00028 extern int sock_recv_init (sock_type *s, void *space, unsigned len);
00029 extern int sock_recv_used (const sock_type *s);
00030 extern int sock_recv      (sock_type *s, void *buffer, unsigned len);
00031 extern int sock_recv_from (sock_type *s, void *hisip, WORD *hisport,
00032                            void *buffer, unsigned len, int peek);
00033 #endif
Generated on Wed Jan 25 15:42:38 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/PCSARP.C Source File

SRC/PCSARP.C

Go to the documentation of this file.
00001
00015 #include <stdio.h>
00016 #include <stdlib.h>
00017 #include <string.h>
00018
00019 #include "wattcp.h"
00020 #include "strings.h"
00021 #include "language.h"
00022 #include "netaddr.h"
00023 #include "misc.h"
00024 #include "pcdbug.h"
00025 #include "pcconfig.h"
00026 #include "pctcp.h"
00027 #include "pcsed.h"
00028 #include "pcpkt.h"
00029 #include "pcarp.h"
00030 #include "pcsarp.h"
00031
00032
00033 #if defined(USE_SECURE_ARP)
00034 /*
00035  * OpenSSL include path should be in %INCLUDE% and %C_INCLUDE_PATH%.
00036  */
00037 #include <openssl/dsa.h>
00038 #include <openssl/sha.h>
00039 #include <openssl/rand.h>
00040 #include <openssl/bio.h>
00041 #include <openssl/evp.h>
00042
00043 #if defined(USE_DEBUG)
00044   #define SARP_DEBUG(lvl, args)      \
00045           do {                       \
00046             if (sarp_debug >= lvl) { \
00047                (*_printf) args;      \
00048                fflush (stdout);      \
00049             }                        \
00050           } while (0)
00051 #else
00052   #define SARP_DEBUG(args, lvl) ((void)0)
00053 #endif
00054
00055 struct host_list {
00056        DWORD             ip;     /* on host order */
00057        eth_address       mac;
00058        BOOL              secure;
00059        DSA              *dsa;
00060        struct host_list *next;
00061      };
00062
00063 static void (*prev_cfg_hook) (const char*, const char*);
00064 static char  *ca_keyfile   = NULL;
00065 static char  *priv_keyfile = NULL;
00066 static int    sarp_debug   = 0;
00067
00068 static struct host_list *known_hosts  = NULL;
00069 static struct host_list *secure_hosts = NULL;
00070
00071 static void sarp_parse    (const char *name, const char *value);
00072 static int  sarp_receive  (const struct sarp_Packet *sarp);
00073 static int  sarp_transmit (struct sarp_Packet *sarp);
00074
00079 int sarp_init (void)
00080 {
00081   const char *rand = getenv ("RANDFILE");
00082
00083   prev_cfg_hook   = usr_init;
00084   usr_init        = sarp_parse;
00085   _sarp_recv_hook = sarp_receive;
00086   _sarp_xmit_hook = sarp_transmit;
00087
00088   if (rand && access(rand,0) == 0)
00089        RAND_load_file (rand, -1);
00090   else SARP_DEBUG (0, ("Warning: No random seed file found\n"));
00091   return (0);
00092 }
00093
00094 static int read_ca_keyfile (const char *value)
00095 {
00096   DSA *dsa;
00097
00098   DSA_free (dsa);
00099 }
00100
00101 static int read_priv_keyfile (const char *value)
00102 {
00103   FILE *fil;
00104
00105   ca_keyfile = strdup (value);
00106   if (!ca_keyfile)
00107      return (0);
00108
00109   fil = fopen (ca_keyfile, "rt");
00110   if (!fil)
00111      return (0);
00112
00113 #if 0
00114   priv = d2i_RSAPrivateKey_fp (fil, NULL);
00115 #endif
00116   fclose (fil);
00117   return (1);
00118 }
00119
00120 static BOOL crypto_load_sarp_file (const char *pem_file, DSA **dsa)
00121 {
00122   FILE *fil = fopen (pem_file, "rt");
00123
00124   *dsa = d2i_DSAPublicKey (NULL, raw, len);
00125
00126   if (!crypto_verify_sign(message,strlen(message),sig,siglen,*dsa))
00127   {
00128     SARP_DEBUG (0, ("%s has illegal signature\n", pem_file));
00129     DSA_free (*dsa);
00130     return (FALSE);
00131   }
00132 }
00133
00134 /*
00135  * Parse "SECURE_HOST" 'value' "<IP>, <MAC>, <public-key-file>"
00136  */
00137 static int set_secure_host (const char *value)
00138 {
00139   struct host_list *host;
00140   char   ip[16], mac[21], pem_file[256];
00141   DWORD  ip_addr;
00142   DSA   *dsa;
00143
00144   if (sscanf(value,"%15[^,],%20[^,],%255[^\r\n]", ip, mac, pem_file) != 3)
00145      return (0);
00146
00147   ip_addr = _inet_addr (ip);
00148   if (!ip_addr)
00149      return (0);
00150
00151   host = calloc (sizeof(*host), 1);
00152   if (!host)
00153      return (0);
00154
00155   if (!_inet_atoeth(mac, &host->mac) ||
00156       !crypto_load_sarp_file(pem_file, &dsa))
00157   {
00158     free (host);
00159     return (0);
00160   }
00161
00162   host->secure = TRUE;
00163   host->ip     = ip_addr;
00164   host->dsa    = dsa;
00165   host->next   = secure_hosts;
00166   secure_hosts = host;
00167   return (1);
00168 }
00169
00170 /*
00171  * Parse "KNOWN_HOST" 'value' "<IP>, <MAC>"
00172  */
00173 static int set_known_host (const char *value, int value_len)
00174 {
00175   struct host_list *host;
00176   char   ip[16], mac[21];
00177
00178   if (sscanf(value,"%15[^,],%20[^\r\n]", ip, mac) != 2)
00179      return (0);
00180
00181   host = calloc (sizeof(*host), 1);
00182   if (!host)
00183      return (0);
00184
00185   if (!_inet_atoeth (mac, &host->mac))
00186   {
00187     free (host);
00188     return (0);
00189   }
00190
00191   host->secure = FALSE;
00192   host->ip     = _inet_addr (ip);
00193   host->next  =  known_hosts;
00194   known_hosts = host;
00195   return (1);
00196 }
00197
00198
00202 static void sarp_parse (const char *name, const char *value)
00203 {
00204   static const struct config_table sarp_cfg[] = {
00205          { "CA_KEY",      ARG_FUNC, (void*)read_ca_keyfile   },
00206          { "PRIV_KEY",    ARG_FUNC, (void*)read_priv_keyfile },
00207          { "SECURE_HOST", ARG_FUNC, (void*)set_secure_host   },
00208          { "KNOWN_HOST",  ARG_FUNC, (void*)set_known_host    },
00209          { NULL,          0,        NULL                     }
00210        };
00211
00212   if (!parse_config_table(&sarp_cfg[0], "SEC_ARP.", name, value) &&
00213       prev_cfg_hook)
00214      (*prev_cfg_hook) (name, value);
00215 }
00216
00220 static __inline BOOL is_secure_host (DWORD ip)
00221 {
00222   const struct host_list *host;
00223
00224   for (host = secure_hosts; host; host = host->next)
00225       if (host->ip == ip)
00226          return (host->dsa != NULL);
00227   return (FALSE);
00228 }
00229
00233 static __inline BOOL is_known_host (DWORD ip)
00234 {
00235   const struct host_list *host;
00236
00237   for (host = known_hosts; host; host = host->next)
00238       if (host->ip == ip)
00239          return (TRUE);
00240   return (FALSE);
00241 }
00242
00243 static int make_auth_Header (struct sarp_Packet *sarp)
00244 {
00245   ARGSUSED (sarp);
00246   return (0);
00247 }
00248
00249 /*
00250  * Called from _arp_handler() after hw-type and protocol (IPv4) is
00251  * verified. Must completely replace _arp_handler().
00252  */
00253 static int sarp_receive (const struct sarp_Packet *sarp)
00254 {
00255   DWORD src_ip = ntohl (sarp->arp.srcIPAddr);
00256
00257   if (!is_secure_host(src_ip) && !is_known_host(src_ip))
00258      return (0);   /* drop it */
00259
00261   return (1);
00262 }
00263
00264 /*
00265  * Called from arp_send(). Add any authentication header as needed.
00266  * Return total length of what's need to be transmitted.
00267  */
00268 static int sarp_transmit (struct sarp_Packet *sarp)
00269 {
00270   DWORD dst_ip = ntohl (sarp->arp.dstIPAddr);
00271   WORD  len    = sizeof (sarp->arp);
00272
00273   if (!is_secure_host(dst_ip))
00274      return (len);   /* send as-is */
00275
00276   memset (&sarp->auth, 0, sizeof(sarp->auth));
00277   len += make_auth_Header (sarp);
00278   return (len);
00279 }
00280
00284 void _sarp_debug_dump (void)
00285 {
00286 }
00287 #endif  /* USE_SECURE_ARP */
Generated on Wed Jan 25 15:42:38 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/PCSARP.H Source File

SRC/PCSARP.H

Go to the documentation of this file.
00001
00005 #ifndef _w32_PCSARP_H
00006 #define _w32_PCSARP_H
00007
00008 #include <sys/packon.h>
00009
00010 struct sarp_Auth {
00011        DWORD  magic;
00012        BYTE   type;
00013        BYTE   siglen;
00014        WORD   datalen;
00015        DWORD  timestamp;
00016      };
00017
00018 struct sarp_Packet {
00019        struct arp_Header arp;
00020        struct sarp_Auth  auth;
00021      };
00022
00023 #include <sys/packoff.h>
00024
00025 int sarp_init (void);
00026
00027 #endif
00028
Generated on Wed Jan 25 15:42:38 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/PCSED.C Source File

SRC/PCSED.C

Go to the documentation of this file.
00001
00016 #include <stdio.h>
00017 #include <stdlib.h>
00018 #include <string.h>
00019
00020 #include "copyrigh.h"
00021 #include "wattcp.h"
00022 #include "wdpmi.h"
00023 #include "strings.h"
00024 #include "language.h"
00025 #include "sock_ini.h"
00026 #include "loopback.h"
00027 #include "cpumodel.h"
00028 #include "misc.h"
00029 #include "timer.h"
00030 #include "rs232.h"
00031 #include "split.h"
00032 #include "ip4_in.h"
00033 #include "ip6_in.h"
00034 #include "bsddbug.h"
00035 #include "pcmulti.h"
00036 #include "pcqueue.h"
00037 #include "pcconfig.h"
00038 #include "pcdbug.h"
00039 #include "pctcp.h"
00040 #include "pcstat.h"
00041 #include "pcpkt.h"
00042 #include "pppoe.h"
00043 #include "pcsed.h"
00044
00045 /* !!fix-me: Should allow the largest possible MAC-address to be used;
00046  *           An AX-25 address is 7 bytes.
00047  */
00048 mac_address _eth_addr;
00049 mac_address _eth_brdcast;
00050 mac_address _eth_loop_addr;
00051 mac_address _eth_real_addr;
00052 BYTE        _eth_mac_len;
00053 BOOL        _eth_is_init  = FALSE;
00054 BOOL        _ip_recursion = FALSE;
00055 BOOL        _eth_ndis3pkt = FALSE;
00056 BOOL        _eth_SwsVpkt  = FALSE;
00057
00058 const char  _eth_not_init[] = "Packet driver not initialised";
00059
00063 struct _eth_last_info _eth_last;
00064
00086 void *(*_eth_recv_hook) (WORD *type)                        = NULL;
00087 int   (*_eth_recv_peek) (void *mac_buf)                     = NULL;
00088 int   (*_eth_xmit_hook) (const void *mac_buf, unsigned len) = NULL;
00089
00094 static void *(*mac_tx_format)(void *mac_buf, const void *mac_dest, WORD type);
00095 static int   (*mac_transmit) (const void *mac_buf, WORD len);
00096
00097 static WORD  proto;   /* protocol set in _eth_formatpacket() */
00098 static void *nw_pkt;  /* where network protocol packet starts */
00099
00100
00110 #if (DOSX & (DOS4GW|X32VM))
00111   #define TX_BUF()  ((union link_Packet*) pkt_tx_buf())
00112
00113 #elif (DOSX & DJGPP)
00114   static union link_Packet outbuf;
00115
00116   #define TX_BUF() (_pkt_inf && _pkt_inf->use_near_ptr ? \
00117                      (union link_Packet*)pkt_tx_buf()  : \
00118                      (&outbuf))
00119 #else
00120   static union link_Packet outbuf;
00121   #define TX_BUF()  (&outbuf)
00122 #endif
00123
00129 void *_eth_formatpacket (const void *mac_dest, WORD eth_type)
00130 {
00131   SIO_TRACE (("_eth_formatpacket, type %04X", eth_type));
00132
00133   nw_pkt = (*mac_tx_format) (TX_BUF(), mac_dest, eth_type);
00134   return (nw_pkt);
00135 }
00136
00137
00138 #if defined(USE_LOOPBACK)
00139
00148 static int send_loopback (link_Packet pkt, BOOL is_ip6, unsigned *err_line)
00149 {
00150   struct pkt_ringbuf *q;
00151   const  in_Header   *ip;
00152   int    ip_len;
00153
00154   SIO_TRACE (("send_loopback"));
00155
00156   if (!_pkt_inf)
00157   {
00158     *err_line = __LINE__;
00159     goto drop_it;
00160   }
00161
00162   /* Call loopback handler with IP-packet
00163    */
00164   ip     = (in_Header*) ((BYTE*)&pkt + _pkt_ip_ofs);
00165   ip_len = loopback_device ((in_Header*)ip);
00166
00167   q = &_pkt_inf->pkt_queue;
00168
00169   if (!q || ip_len > (int)_mtu)
00170   {
00171     *err_line = __LINE__;
00172     goto drop_it;
00173   }
00174
00175   if (ip_len > 0)
00176   {
00177 #if defined(USE_FAST_PKT)
00178     /*
00179      * Don't let pkt_receiver() modify the queue while testing/copying.
00180      */
00181     if (pkt_buffers_used() >= _pkt_inf->pkt_queue.num_buf - 1)
00182     {
00183       *err_line = __LINE__;
00184       goto drop_it;
00185     }
00186     {
00187       char     tx_buf [ETH_MAX];
00188       unsigned len = ip_len;
00189
00190       /* Enqueue packet to head of input IP-queue.
00191        */
00192       if (!_pktserial)
00193       {
00194         void *data = (*mac_tx_format) (tx_buf, _eth_addr,
00195                                        is_ip6 ? IP6_TYPE : IP4_TYPE);
00196         memcpy (MAC_SRC(data), &_eth_loop_addr, sizeof(mac_address));
00197         memcpy (data, ip, ip_len);
00198         len += _pkt_ip_ofs;
00199       }
00200       else
00201         memcpy (tx_buf, ip, ip_len);
00202
00203       if (!pkt_append_recv(tx_buf, len))
00204       {
00205         *err_line = __LINE__;
00206         goto drop_it;
00207       }
00208     }
00209 #elif defined(WIN32)
00210     struct pkt_rx_element *head;
00211
00212     ENTER_CRIT();
00213     if (pktq_in_index(q) == q->out_index)  /* queue is full, drop it */
00214     {
00215       q->num_drop++;
00216       LEAVE_CRIT();
00217       *err_line = __LINE__;
00218       goto drop_it;
00219     }
00220
00221     head = (struct pkt_rx_element*) pktq_in_buf (q);
00222     head->rx_length = _pkt_ip_ofs + ip_len;
00223     gettimeofday (&head->tstamp_put, NULL);
00224
00225     /* Enqueue packet to head of input IP-queue.
00226      */
00227     if (!_pktserial)
00228     {
00229       void *data = (*mac_tx_format) (&head->rx_buf, _eth_addr,
00230                                      is_ip6 ? IP6_TYPE : IP4_TYPE);
00231       memcpy (MAC_SRC(data), &_eth_loop_addr, sizeof(mac_address));
00232       memcpy (data, ip, ip_len);
00233     }
00234     else
00235       memcpy (head, ip, ip_len);
00236
00237     /* Update queue head index
00238      */
00239     q->in_index = pktq_in_index (q);
00240
00241     LEAVE_CRIT();
00242
00243 #else
00244     union link_Packet *head;
00245
00246     DISABLE();
00247     if (pktq_in_index(q) == q->out_index)  /* queue is full, drop it */
00248     {
00249       q->num_drop++;
00250       ENABLE();
00251       *err_line = __LINE__;
00252       goto drop_it;
00253     }
00254
00255     head = (union link_Packet*) pktq_in_buf (q);
00256
00257     /* Enqueue packet to head of input IP-queue.
00258      */
00259     if (!_pktserial)
00260     {
00261       void *data = (*mac_tx_format) (head, _eth_addr,
00262                                      is_ip6 ? IP6_TYPE : IP4_TYPE);
00263       memcpy (MAC_SRC(data), &_eth_loop_addr, sizeof(mac_address));
00264       memcpy (data, ip, ip_len);
00265     }
00266     else
00267       memcpy (head, ip, ip_len);
00268
00269     /* Update queue head index
00270      */
00271     q->in_index = pktq_in_index (q);
00272
00273     ENABLE();
00274 #endif
00275   }
00276   *err_line = 0;
00277   return (ip_len + _pkt_ip_ofs);
00278
00279 drop_it:
00280   /*
00281    * Maybe this should be an input counter
00282    */
00283   if (is_ip6)
00284        STAT (ip6stats.ip6s_odropped++);
00285   else STAT (ip4stats.ips_odropped++);
00286   return (0);
00287 }
00288 #endif  /* USE_LOOPBACK */
00289
00290
00300 int _eth_send (WORD len, const void *sock, const char *file, unsigned line)
00301 {
00302 #if defined(USE_DEBUG) || defined(USE_LOOPBACK)
00303   unsigned errline = 0;
00304 #endif
00305   BOOL send_loopback_to_driver = FALSE;
00306
00307   SIO_TRACE (("_eth_send, len %d", len));
00308
00309   if (!_eth_is_init)  /* GvB 2002-09, Lets us run without a working eth */
00310   {
00311     SOCK_ERRNO (ENETDOWN);
00312     return (0);
00313   }
00314
00315 #if defined(WIN32)
00316   /*
00317    * Just a test for now; send it to the driver and look what happens....
00318    * They go on the wire and not to the Winsock loopback provider.
00319    * No surprise here yet.
00320    */
00321   if (loopback_mode & LBACK_MODE_WINSOCK)
00322      send_loopback_to_driver = TRUE;
00323 #endif
00324
00325   if (proto == IP4_TYPE)
00326   {
00327     /* Sending to loopback device if IPv4.
00328      */
00329     const in_Header *ip = (const in_Header*) nw_pkt;
00330
00331     if (!send_loopback_to_driver &&
00332         _ip4_is_loopback_addr(intel(ip->destination)))
00333     {
00334 #if defined(USE_LOOPBACK)
00335       len = send_loopback (*TX_BUF(), FALSE, &errline);
00336 #else
00337       STAT (ip4stats.ips_odropped++);    /* packet dropped (null-device) */
00338 #endif
00339       goto debug_tx;
00340     }
00341   }
00342
00343 #if defined(USE_IPV6)
00344   else if (proto == IP6_TYPE)
00345   {
00346     const in6_Header *ip = (const in6_Header*) nw_pkt;
00347
00348     if (!send_loopback_to_driver &&
00349         IN6_IS_ADDR_LOOPBACK(&ip->destination))
00350     {
00351 #if defined(USE_LOOPBACK)
00352       len = send_loopback (*TX_BUF(), TRUE, &errline);
00353 #else
00354       STAT (ip6stats.ip6s_odropped++);
00355 #endif
00356       goto debug_tx;
00357     }
00358   }
00359 #endif  /* USE_IPV6 */
00360
00361 #if defined(USE_PPPOE)
00362   else if (proto == PPPOE_SESS_TYPE)
00363   {
00364     pppoe_Packet *pppoe = (pppoe_Packet*) TX_BUF()->eth.data;
00365
00366     pppoe->length = intel16 (len+2);
00367     len += PPPOE_HDR_SIZE + 2;      /* add 2 for protocol */
00368   }
00369 #endif
00370
00371   /* Store the last Tx CPU timestamp (for debugging).
00372    */
00373 #if (DOSX) && !(DOSX & WINWATT)
00374   if (_dbugxmit && has_rdtsc)
00375      get_rdtsc2 (&_eth_last.tx.tstamp);
00376 #endif
00377
00378   /* Do the MAC-dependant transmit. `len' on return is total length
00379    * of link-layer packet sent. `len' is 0 on failure. The xmit-hook
00380    * is used by e.g. libpcap/libnet.
00381    */
00382   if (_eth_xmit_hook)
00383        len = (*_eth_xmit_hook) (TX_BUF(), len + _pkt_ip_ofs);
00384   else len = (*mac_transmit) (TX_BUF(), len + _pkt_ip_ofs);
00385
00386   if (len > _pkt_ip_ofs)
00387   {
00388     _eth_last.tx.size = len;
00389     len -= _pkt_ip_ofs;
00390   }
00391   else
00392   {
00393     if (debug_on)
00394        outs ("Tx failed. ");
00395     len = 0;
00396     _eth_last.tx.size = 0;
00397   }
00398
00399 debug_tx:
00400
00401 #if defined(NEED_PKT_SPLIT)
00402   pkt_split_mac_out (TX_BUF());
00403 #endif
00404
00405 #if defined(USE_STATISTICS)
00406   if (len > 0)
00407      update_out_stat();
00408 #endif
00409
00410 #if defined(USE_DEBUG)
00411   if (_dbugxmit)
00412     (*_dbugxmit) (sock, (const in_Header*)nw_pkt, file, line);
00413
00414   if (len == 0)
00415   {
00416     if (errline && !send_loopback_to_driver)
00417        dbug_printf ("** Error in loopback handler, line %u\n", errline);
00418     else
00419     {
00420       const char err[] = "** Transmit fault **\n";
00421       TCP_CONSOLE_MSG (0, ("%s", err));
00422       dbug_printf (err);
00423     }
00424   }
00425 #else
00426   ARGSUSED (sock);
00427   ARGSUSED (file);
00428   ARGSUSED (line);
00429 #endif
00430
00431   /* Undo hack done in pppoe_mac_format()
00432    */
00433   if (proto == PPPOE_SESS_TYPE || _pktdevclass == PDCLASS_ETHER)
00434      _pkt_ip_ofs = sizeof(eth_Header);
00435   return (len);
00436 }
00437
00441 static void *eth_mac_format (void *mac_buf, const void *mac_dest, WORD type)
00442 {
00443   union link_Packet *buf = (union link_Packet*) mac_buf;
00444
00445   SIO_TRACE (("eth_mac_format"));
00446
00447   proto = type;      /* remember protocol for _eth_send() */
00448
00449   /* Clear any remains of an old small packet
00450    */
00451   memset (&buf->eth.data[0], 0, ETH_MIN-sizeof(eth_Header));
00452
00453 #if defined(USE_PPPOE)
00454   if (type == IP4_TYPE && pppoe_is_up(mac_dest))
00455   {
00456     proto = PPPOE_SESS_TYPE;
00457     return pppoe_mac_format (buf);
00458   }
00459 #endif
00460
00461   if (mac_dest)
00462      memcpy (&buf->eth.head.destination, mac_dest, sizeof(mac_address));
00463   memcpy (&buf->eth.head.source, &_eth_addr, sizeof(mac_address));
00464
00465   buf->eth.head.type = type;
00466   return (&buf->eth.data);
00467 }
00468
00472 static void *tok_mac_format (void *mac_buf, const void *mac_dest, WORD type)
00473 {
00474   union link_Packet *buf = (union link_Packet*) mac_buf;
00475
00476   SIO_TRACE (("tok_mac_format"));
00477
00478   /* No need to clear data behind header.
00479    */
00480   if (mac_dest)
00481      memcpy (&buf->tok.head.destination, mac_dest, sizeof(mac_address));
00482   memcpy (&buf->tok.head.source, &_eth_addr, sizeof(mac_address));
00483
00484 #if 0
00485   /* !!fix me: need to expand the RIF
00486    */
00487   if (_pktdevclass == PDCLASSS_TOKEN_RIF)
00488      ((void)0);
00489 #endif
00490
00491   buf->tok.head.accessCtrl = TR_AC;
00492   buf->tok.head.frameCtrl  = TR_FC;
00493   buf->tok.head.DSAP       = TR_DSAP;
00494   buf->tok.head.SSAP       = TR_SSAP;
00495   buf->tok.head.ctrl       = TR_CTRL;
00496   buf->tok.head.org[0]     = TR_ORG;
00497   buf->tok.head.org[1]     = TR_ORG;
00498   buf->tok.head.org[2]     = TR_ORG;
00499   buf->tok.head.type       = type;
00500   proto = type;
00501   return (&buf->tok.data);
00502 }
00503
00507 static void *fddi_mac_format (void *mac_buf, const void *mac_dest, WORD type)
00508 {
00509   union link_Packet *buf = (union link_Packet*) mac_buf;
00510
00511   SIO_TRACE (("fddi_mac_format"));
00512
00513   memset (&buf->fddi.data[0], 0, FDDI_MIN-sizeof(fddi_Header));
00514   if (mac_dest)
00515      memcpy (&buf->fddi.head.destination, mac_dest, sizeof(mac_address));
00516   memcpy (&buf->fddi.head.source, &_eth_addr, sizeof(mac_address));
00517
00518   buf->fddi.head.frameCtrl = FDDI_FC;
00519   buf->fddi.head.DSAP      = FDDI_DSAP;
00520   buf->fddi.head.SSAP      = FDDI_SSAP;
00521   buf->fddi.head.ctrl      = FDDI_CTRL;
00522   buf->fddi.head.org[0]    = FDDI_ORG;
00523   buf->fddi.head.org[1]    = FDDI_ORG;
00524   buf->fddi.head.org[2]    = FDDI_ORG;
00525   buf->fddi.head.type      = type;
00526   proto = type;
00527   return (&buf->fddi.data);
00528 }
00529
00533 static void *arcnet_mac_format (void *mac_buf, const void *mac_dest, WORD type)
00534 {
00535   union link_Packet *buf = (union link_Packet*) mac_buf;
00536   BYTE  dest;
00537
00538   if (type == IP4_TYPE)     /* Map to DataPoint proto types */
00539       type = ARCNET_IP_1201;
00540   else if (type == IP6_TYPE)
00541       type = ARCNET_IP6;
00542   else if (type == ARP_TYPE)
00543       type = ARCNET_ARP_1201;
00544   else if (type == RARP_TYPE)
00545       type = ARCNET_RARP_1201;
00546
00547   if (!mac_dest || !memcmp(mac_dest, &_eth_brdcast, sizeof(_eth_brdcast)))
00548        dest = 0x00;              /* map to ARCNET broadcast */
00549   else dest = *(BYTE*)mac_dest;  /* Use MSB as destination */
00550
00551   buf->arc.head.source      = _eth_addr[0];
00552   buf->arc.head.destination = dest;
00553   buf->arc.head.type        = (BYTE) type;
00554   buf->arc.head.flags       = 0;     /* !! */
00555   buf->arc.head.sequence    = 0;     /* !! */
00556 #if 0 /* should never be transmitted */
00557   buf->arc.head.type2       = type;
00558   buf->arc.head.flags2      = 0;     /* !! */
00559   buf->arc.head.sequence2   = 0;     /* !! */
00560 #endif
00561
00562   proto = (BYTE) type;
00563   return (void*) ((BYTE*)&buf->arc + ARC_HDRLEN);
00564 }
00565
00570 static void *null_mac_format (void *mac_buf, const void *mac_dest, WORD type)
00571 {
00572   union link_Packet *buf = (union link_Packet*) mac_buf;
00573
00574   SIO_TRACE (("null_mac_format"));
00575
00576   memset (&buf->ip.head, 0, sizeof(buf->ip.head));
00577   ARGSUSED (mac_dest);
00578   ARGSUSED (type);
00579   proto = IP4_TYPE;
00580   return (void*) (&buf->ip.head);
00581 }
00582
00587 static int eth_mac_xmit (const void *buf, WORD len)
00588 {
00589   SIO_TRACE (("eth_mac_xmit, len %d", len));
00590
00591   if (len < ETH_MIN)
00592        len = ETH_MIN;  /* zero padding already done in eth_mac_format() */
00593   else if (len > ETH_MAX)
00594        len = ETH_MAX;
00595
00596   return pkt_send (buf, len);
00597 }
00598
00599 static int fddi_mac_xmit (const void *buf, WORD len)
00600 {
00601   SIO_TRACE (("fddi_mac_xmit, len %d", len));
00602
00603   if (len < FDDI_MIN)
00604        len = FDDI_MIN;
00605   else if (len > FDDI_MAX)
00606        len = FDDI_MAX;
00607
00608   return pkt_send (buf, len);
00609 }
00610
00611 static int arcnet_mac_xmit (const void *buf, WORD len)
00612 {
00613   SIO_TRACE (("arcnet_mac_xmit, len %d", len));
00614
00615   if (len < ARCNET_MIN)
00616        len = ARCNET_MIN;
00617   else if (len > ARCNET_MAX)
00618        len = ARCNET_MAX;
00619
00620   return pkt_send (buf, len);
00621 }
00622
00623 static int tok_mac_xmit (const void *buf, WORD len)
00624 {
00625   SIO_TRACE (("tok_mac_xmit, len %d", len));
00626
00627   if (len > TOK_MAX)  /* Token-Ring has no min. length */
00628       len = TOK_MAX;
00629   return pkt_send (buf, len);
00630 }
00631
00632 static int null_mac_xmit (const void *buf, WORD len)
00633 {
00634   SIO_TRACE (("null_mac_xmit, len %d", len));
00635
00636   return pkt_send (buf, len);
00637 }
00638
00639
00645 int _eth_init (void)
00646 {
00647   int rc;
00648
00649   SIO_TRACE (("_eth_init"));
00650
00651   if (_eth_is_init)
00652      return (0);
00653
00654   rc = pkt_eth_init (&_eth_addr);
00655   if (rc)
00656      return (rc);  /* error message already printed */
00657
00658   /* Save our MAC-address incase we change it. Change back at exit.
00659    */
00660   memcpy (_eth_real_addr, _eth_addr, sizeof(_eth_real_addr));
00661
00662   switch (_pktdevclass)
00663   {
00664     case PDCLASS_ETHER:
00665          mac_tx_format = eth_mac_format;
00666          mac_transmit  = eth_mac_xmit;
00667          break;
00668     case PDCLASS_TOKEN:
00669     case PDCLASS_TOKEN_RIF:
00670          mac_tx_format = tok_mac_format;
00671          mac_transmit  = tok_mac_xmit;
00672          break;
00673     case PDCLASS_FDDI:
00674          mac_tx_format = fddi_mac_format;
00675          mac_transmit  = fddi_mac_xmit;
00676          break;
00677     case PDCLASS_ARCNET:
00678          mac_tx_format = arcnet_mac_format;
00679          mac_transmit  = arcnet_mac_xmit;
00680          break;
00681     case PDCLASS_SLIP:
00682     case PDCLASS_PPP:
00683     case PDCLASS_AX25:  /* !! for now */
00684          mac_tx_format = null_mac_format;
00685          mac_transmit  = null_mac_xmit;
00686          break;
00687     default:
00688          outsnl (_LANG("No supported driver class found"));
00689          return (WERR_NO_DRIVER);
00690   }
00691
00692   memset (TX_BUF(), 0, sizeof(union link_Packet));
00693   memset (&_eth_brdcast, 0xFF, sizeof(_eth_brdcast));
00694   _eth_loop_addr[0] = 0xCF;
00695   pkt_buf_wipe();
00696
00697   if (!_eth_get_hwtype(NULL, &_eth_mac_len))
00698      _eth_mac_len = sizeof(eth_address);
00699
00700   if (!strcmp(_pktdrvrname,"NDIS3PKT"))
00701      _eth_ndis3pkt = TRUE;
00702
00703   else if (!strcmp(_pktdrvrname,"SwsVpkt"))
00704      _eth_SwsVpkt = TRUE;
00705
00706   _eth_is_init = TRUE;
00707   RUNDOWN_ADD (_eth_release, 10);
00708
00709   return (0);  /* everything okay */
00710 }
00711
00715 int _eth_set_addr (const void *addr)
00716 {
00717   SIO_TRACE (("_eth_set_addr"));
00718
00719   if (_pktserial || _pktdevclass == PDCLASS_ARCNET)
00720      return (1);
00721
00722   if (pkt_set_addr(addr))
00723   {
00724     memcpy (_eth_addr, addr, sizeof(_eth_addr));
00725     return (1);
00726   }
00727   return (0);
00728 }
00729
00730
00735 BYTE _eth_get_hwtype (BYTE *hwtype, BYTE *hwlen)
00736 {
00737   SIO_TRACE (("_eth_get_hwtype"));
00738
00739   if (_pktdevclass == PDCLASS_ETHER)
00740   {
00741     if (hwlen)  *hwlen  = sizeof (eth_address);
00742     if (hwtype) *hwtype = HW_TYPE_ETHER;
00743     return (HW_TYPE_ETHER);
00744   }
00745   if (_pktdevclass == PDCLASS_FDDI)
00746   {
00747     if (hwlen)  *hwlen  = sizeof (fddi_address);
00748     if (hwtype) *hwtype = HW_TYPE_FDDI;
00749     return (HW_TYPE_FDDI);
00750   }
00751   if (_pktdevclass == PDCLASS_TOKEN || _pktdevclass == PDCLASS_TOKEN_RIF)
00752   {
00753     if (hwlen)  *hwlen  = sizeof (tok_address);
00754     if (hwtype) *hwtype = HW_TYPE_TOKEN;
00755     return (HW_TYPE_TOKEN);
00756   }
00757   if (_pktdevclass == PDCLASS_AX25)
00758   {
00759     if (hwlen)  *hwlen  = sizeof (ax25_address);
00760     if (hwtype) *hwtype = HW_TYPE_AX25;
00761     return (HW_TYPE_AX25);
00762   }
00763   if (_pktdevclass == PDCLASS_ARCNET)
00764   {
00765     if (hwlen)  *hwlen  = sizeof (arcnet_address);  /* 1 byte */
00766     if (hwtype) *hwtype = HW_TYPE_ARCNET;
00767     return (HW_TYPE_ARCNET);
00768   }
00769   return (0);
00770 }
00771
00772
00776 void _eth_free (const void *pkt)
00777 {
00778   SIO_TRACE (("_eth_free"));
00779
00780   if (_eth_recv_hook) /* hook-function should free it's own packet */
00781      return;
00782
00783   if (!pkt)
00784        pkt_buf_wipe();   /* restart the queue */
00785   else pkt_free_pkt (pkt);
00786 }
00787
00788
00794 #define RCF DSAP   /* Routing Control where DSAP is when no routing */
00795
00796 #define TR_IS_SROUTED(th)   ((th)->source[0] & 0x80)
00797 #define TR_IS_BROADCAST(th) (((intel16((th)->RCF) & 0xE000) >> 13) >= 4)
00798 #define TR_RIF_LENGTH(th)   ((intel16((th)->RCF) & 0x1F00) >> 8)
00799
00800 #define TR_MAC_SIZE         (2+2+2*sizeof(mac_address)) /* AC,FC,src/dst */
00801
00802 static void fix_tok_head (tok_Header **trp)
00803 {
00804   tok_Header *tr = *trp;
00805
00806 #if defined(USE_DEBUG)
00807   const BYTE *raw = (const BYTE*)tr;
00808   int   i;
00809
00810   for (i = 0; i < 50; i++)
00811       dbug_printf ("%02X ", raw[i]);
00812   dbug_write ("\n");
00813 #endif
00814
00815   SIO_TRACE (("fix_tok_head"));
00816
00817   if (TR_IS_SROUTED(tr))     /* Source routed */
00818   {
00819     int rlen = TR_RIF_LENGTH (tr);
00820
00821     tr->source[0] &= 0x7F;   /* clear RII bit */
00822
00823     /* Set our notion of link-layer broadcast
00824      */
00825     if (TR_IS_BROADCAST(tr))
00826        tr->destination[0] |= 1;
00827
00828     /* Copy MAC-header rlen bytes upwards
00829      */
00830     memmove ((BYTE*)tr + rlen, tr, TR_MAC_SIZE);
00831     *trp = (tok_Header*) ((BYTE*)tr + rlen);
00832   }
00833 }
00834
00835 /*
00836  * Check (and fix?) the received ARCNET header.
00837  * All frames must have a common layout with headlen ARC_HDRLEN.
00838  */
00839 static BOOL fix_arc_head (const arcnet_Header *head, WORD *type)
00840 {
00841 #if defined(USE_DEBUG)
00842   const BYTE *raw = (const BYTE*)head;
00843   int   i;
00844
00845   for (i = 0; i < 50; i++)
00846       dbug_printf ("%02X ", raw[i]);
00847   dbug_write ("\n");
00848 #endif
00849
00850   *type = head->type;
00851
00852   /* Map to IANA numbers
00853    */
00854   if (*type == ARCNET_IP_1051 || *type == ARCNET_IP_1201)
00855      *type = IP4_TYPE;
00856   if (*type == ARCNET_ARP_1051 || *type == ARCNET_ARP_1201)
00857      *type = ARP_TYPE;
00858
00859   if (head->flags == 0xFF ||   /* Exception packet */
00860       (*type != IP4_TYPE &&    /* Neither IP nor ARP */
00861        *type != ARP_TYPE))
00862      return (FALSE);
00863   return (TRUE);
00864 }
00865
00877 static union link_Packet *poll_recv_queue (WORD *type)
00878 {
00879 #if defined(USE_FAST_PKT) || defined(WIN32)
00880   struct pkt_rx_element *buf;
00881 #endif
00882   struct pkt_ringbuf *q = &_pkt_inf->pkt_queue;
00883   union  link_Packet *pkt;
00884   struct in_Header   *ip;
00885
00886   SIO_TRACE (("poll_recv_queue"));
00887
00888   ASSERT_PKT_INF (NULL);
00889
00890 #if defined(USE_DEBUG)
00891 #if defined(USE_FAST_PKT)
00892   if (!pktq_far_check(q))
00893 #else
00894   if (!pktq_check(q))
00895 #endif
00896   {
00897     fprintf (stderr, "%s: pkt-queue destroyed!\n", __FILE__);
00898     exit (-1);
00899   }
00900 #endif
00901
00902 #if defined(WIN32)
00903   buf = pkt_poll_recv();
00904   if (!buf)
00905      return (NULL);
00906
00907   PROFILE_RECV ((uint64*)&buf->tstamp_put, (uint64*)&buf->tstamp_get);
00908   _eth_last.rx.size      = buf->rx_length;
00909   _eth_last.rx.tstamp.lo = 0UL;  /* no need yet */
00910   _eth_last.rx.tstamp.hi = 0UL;
00911   pkt = (link_Packet*) &buf->rx_buf[0];
00912
00913 #elif defined(USE_FAST_PKT)
00914   buf = pkt_poll_recv();
00915   if (!buf)
00916      return (NULL);
00917
00918   PROFILE_RECV ((uint64*)buf->tstamp_put, (uint64*)buf->tstamp_get);
00919   pkt = (link_Packet*) buf->rx_buf;
00920   _eth_last.rx.size      = buf->rx_length_1;    /* length on 1st upcall */
00921   _eth_last.rx.tstamp.lo = buf->tstamp_put[0];  /* TSC set in asmpkt */
00922   _eth_last.rx.tstamp.hi = buf->tstamp_put[1];
00923
00924 #else
00925   if (!pktq_queued(q))
00926      return (NULL);
00927
00928   pkt = (link_Packet*) pktq_out_buf (q);
00929   _eth_last.rx.size      = ETH_MAX;  /* !! wrong, but doesn't matter for pcap */
00930   _eth_last.rx.tstamp.lo = 0UL;      /* pcdbug.c writes rx-time == dbg-time */
00931   _eth_last.rx.tstamp.hi = 0UL;
00932 #endif
00933
00934
00935   if (_pktserial)
00936   {
00937     ip = &pkt->ip.head;       /* SLIP/PPP/AX25 */
00938     *type = (ip->ver == 4) ? IP4_TYPE : IP6_TYPE;
00939     return (pkt);
00940   }
00941
00942   if (_pktdevclass == PDCLASS_TOKEN || _pktdevclass == PDCLASS_TOKEN_RIF)
00943   {
00944     tok_Header *tr = &pkt->tok.head;
00945
00946     fix_tok_head (&tr);
00947     *type = tr->type;
00948     return (union link_Packet*) tr;
00949   }
00950
00951   if (_pktdevclass == PDCLASS_ARCNET)
00952   {
00953     arcnet_Packet *arc = &pkt->arc;
00954
00955     if (!fix_arc_head(&arc->head, type))
00956     {
00957       DEBUG_RX (NULL, &arc->data);
00958       pkt_free_pkt (pkt);
00959       pkt = NULL;
00960     }
00961     return (pkt);
00962   }
00963
00964   if (_pktdevclass == PDCLASS_FDDI)
00965   {
00966     fddi_Packet *fddi = &pkt->fddi;
00967
00968     *type = fddi->head.type;
00969     return (pkt);
00970   }
00971
00972   /* must be PDCLASS_ETHER */
00973
00974   *type = pkt->eth.head.type;
00975   ARGSUSED (q);
00976   return (pkt);
00977 }
00978
00979 /*
00980  * Fix the LLC header to look like ordinary Ethernet II
00981  * !! not yet.
00982  */
00983 static void fix_llc_head (void **mac)
00984 {
00985   SIO_TRACE (("fix_llc_head"));
00986 #if 1
00987   DEBUG_RX (NULL, *mac);
00988   _eth_free (*mac);
00989   *mac = NULL;
00990 #else
00991
00993 #endif
00994 }
00995
00996
01009 void *_eth_arrived (WORD *type_ptr, BOOL *broadcast)
01010 {
01011   union link_Packet *pkt;
01012   mac_address       *dst;
01013   void              *ret = NULL;
01014   BOOL               is_bcast = FALSE;
01015   WORD               type = 0;
01016
01017   SIO_TRACE (("_eth_arrived"));
01018
01019   if (!_eth_is_init)  /* GvB 2002-09, Lets us run without a working driver */
01020      return (NULL);
01021
01022   if (_eth_recv_hook)
01023        pkt = (union link_Packet*) (*_eth_recv_hook) (&type);
01024   else pkt = poll_recv_queue (&type);
01025
01026   if (!pkt)
01027      return (NULL);
01028
01029   if (_eth_recv_peek && !(*_eth_recv_peek)(pkt))
01030   {
01031     _eth_free (pkt);
01032     return (NULL);
01033   }
01034
01035   /* Hack: If _ip?_handler() can't be reentered, only accept
01036    *       non-IP packets. Assume PPPoE session packets carry only IP.
01037    */
01038   if (_ip_recursion &&
01039       (type == IP4_TYPE || type == IP6_TYPE || type == PPPOE_SESS_TYPE))
01040   {
01042     STAT (macstats.num_ip_recurse++);
01043     _eth_free (pkt);
01044     return (NULL);
01045   }
01046
01047   if (_pktserial)
01048   {
01049     dst = NULL;
01050     ret = (void*) &pkt->ip;
01051   }
01052   else if (_pktdevclass == PDCLASS_TOKEN || _pktdevclass == PDCLASS_TOKEN_RIF)
01053   {
01054     dst = &pkt->tok.head.destination;
01055     ret = (void*) &pkt->tok.data;
01056   }
01057   else if (_pktdevclass == PDCLASS_FDDI)
01058   {
01059     dst = &pkt->fddi.head.destination;
01060     ret = (void*) &pkt->fddi.data;
01061   }
01062   else if (_pktdevclass == PDCLASS_ARCNET)
01063   {
01064     dst = (mac_address*) &pkt->arc.head.destination;
01065     ret = (void*) ((BYTE*)pkt + ARC_HDRLEN);
01066   }
01067   else   /* must be ether */
01068   {
01069     dst = &pkt->eth.head.destination;
01070     ret = (void*) &pkt->eth.data;
01071   }
01072
01073 #if defined(NEED_PKT_SPLIT)
01074   pkt_split_mac_in (pkt);
01075 #endif
01076
01077 #if defined(USE_STATISTICS)
01078   update_in_stat();
01079 #endif
01080
01081 #if defined(NEED_PKT_SPLIT) && defined(USE_DEBUG) && 0  /* test */
01082   pkt_print_split_in();
01083 #endif
01084
01085   /* ARCnet should never have LLC fields. So don't test for it
01086    */
01087   if (_pktdevclass != PDCLASS_ARCNET)
01088   {
01089     if (dst && !memcmp(dst, &_eth_brdcast, sizeof(_eth_brdcast)))
01090        is_bcast = TRUE;
01091
01092     if (intel16(type) < 0x600)       /* LLC length field */
01093        fix_llc_head (&ret);
01094   }
01095   else if (dst && *(BYTE*)dst == 0)  /* ARCnet broadcast */
01096   {
01097     is_bcast = TRUE;
01098   }
01099
01100   if (type_ptr)
01101      *type_ptr = type;
01102
01103   if (broadcast)
01104      *broadcast = is_bcast;
01105
01106   return (ret);
01107 }
01108
01109
01110 #if defined(USE_DEBUG)
01111
01114 void *_eth_mac_hdr (const in_Header *ip)
01115 {
01116   SIO_TRACE (("_eth_mac_hdr"));
01117
01118   if (!_pktserial)
01119      return (void*) ((BYTE*)ip - _pkt_ip_ofs);
01120
01121   (*_printf) ("Illegal use of `_eth_mac_hdr()' for class %d\n",
01122               _pktdevclass);
01123   exit (-1);
01124   /*@-unreachable@*/
01125   return (NULL);
01126 }
01127
01131 void *_eth_mac_dst (const in_Header *ip)
01132 {
01133   const union link_Packet *pkt;
01134
01135   SIO_TRACE (("_eth_mac_dst"));
01136
01137   pkt = (const union link_Packet*) ((BYTE*)ip - _pkt_ip_ofs);
01138
01139   if (_pktdevclass == PDCLASS_ETHER)
01140      return (void*) &pkt->eth.head.destination;
01141
01142   if (_pktdevclass == PDCLASS_TOKEN || _pktdevclass == PDCLASS_TOKEN_RIF)
01143      return (void*) &pkt->tok.head.destination;
01144
01145   if (_pktdevclass == PDCLASS_FDDI)
01146      return (void*) &pkt->fddi.head.destination;
01147
01148   if (_pktdevclass == PDCLASS_ARCNET)
01149      return (void*) &pkt->arc.head.destination;
01150
01151   (*_printf) ("Illegal use of `_eth_mac_dst()' for class %d\n",
01152               _pktdevclass);
01153   exit (-1);
01154   /*@-unreachable@*/
01155   return (NULL);
01156 }
01157
01161 void *_eth_mac_src (const in_Header *ip)
01162 {
01163   const union link_Packet *pkt;
01164
01165   SIO_TRACE (("_eth_mac_src"));
01166
01167   pkt = (const union link_Packet*) ((BYTE*)ip - _pkt_ip_ofs);
01168
01169   if (_pktdevclass == PDCLASS_ETHER)
01170      return (void*) &pkt->eth.head.source;
01171
01172   if (_pktdevclass == PDCLASS_TOKEN || _pktdevclass == PDCLASS_TOKEN_RIF)
01173      return (void*) &pkt->tok.head.source;
01174
01175   if (_pktdevclass == PDCLASS_FDDI)
01176      return (void*) &pkt->fddi.head.source;
01177
01178   if (_pktdevclass == PDCLASS_ARCNET)
01179      return (void*) &pkt->arc.head.source;
01180
01181   (*_printf) ("Illegal use of `_eth_mac_src()' for class %d\n",
01182               _pktdevclass);
01183   exit (-1);
01184   /*@-unreachable@*/
01185   return (NULL);
01186 }
01187
01191 WORD _eth_mac_typ (const in_Header *ip)
01192 {
01193   const union link_Packet *pkt;
01194
01195   SIO_TRACE (("_eth_mac_typ"));
01196
01197   pkt = (const union link_Packet*) ((BYTE*)ip - _pkt_ip_ofs);
01198
01199   if (_pktdevclass == PDCLASS_ETHER)
01200      return (pkt->eth.head.type);
01201
01202   if (_pktdevclass == PDCLASS_TOKEN || _pktdevclass == PDCLASS_TOKEN_RIF)
01203      return (pkt->tok.head.type);
01204
01205   if (_pktdevclass == PDCLASS_FDDI)
01206      return (pkt->fddi.head.type);
01207
01208   if (_pktdevclass == PDCLASS_ARCNET)
01209      return (pkt->arc.head.type);
01210
01211   (*_printf) ("Illegal use of `_eth_mac_typ()' for class %d\n",
01212               _pktdevclass);
01213   exit (-1);
01214   /*@-unreachable@*/
01215   return (0);
01216 }
01217 #endif /* USE_DEBUG */
01218
01219
01220 /*
01221  * Jim Martin's Multicast extensions
01222  */
01223
01224 #if defined(USE_MULTICAST)
01225
01231 BOOL _eth_join_mcast_group (const struct MultiCast *mc)
01232 {
01233   eth_address list [IPMULTI_SIZE];
01234   int         i, len, nextentry;
01235   BOOL        is_mcast1, is_mcast2, is_promis;
01236
01237   SIO_TRACE (("_eth_join_mcast_group"));
01238
01239   /* Return if we're already receiving all multicasts or is in
01240    * promiscous mode.
01241    */
01242 #if defined(WIN32)
01243   is_mcast1 = (_pkt_rxmode & RXMODE_MULTICAST1);
01244   is_mcast2 = (_pkt_rxmode & RXMODE_MULTICAST2);
01245   is_promis = (_pkt_rxmode & RXMODE_PROMISCOUS);
01246 #else
01247   is_mcast1 = (_pkt_rxmode >= RXMODE_MULTICAST1);
01248   is_mcast2 = (_pkt_rxmode >= RXMODE_MULTICAST2);
01249   is_promis = (_pkt_rxmode >= RXMODE_PROMISCOUS);
01250 #endif
01251
01252   if (is_mcast2 || is_promis)
01253      return (TRUE);
01254
01255   if (!is_mcast1)
01256   {
01257     is_mcast1 = pkt_set_rcv_mode(RXMODE_MULTICAST1);
01258     if (!is_mcast1)
01259        is_promis = pkt_set_rcv_mode(RXMODE_PROMISCOUS);
01260     if (is_promis)
01261        return (TRUE);
01262     if (!is_mcast1 && !is_promis)
01263        return (FALSE);     /* hopeless, give up */
01264   }
01265
01266   len = sizeof(list);
01267   if (!pkt_get_multicast_list (list, &len))
01268   {
01269     /* If no MC support, switch to MC2 mode
01270      */
01271     if (_pkt_errno == PDERR_NO_MULTICAST)
01272        return pkt_set_rcv_mode (RXMODE_MULTICAST2);
01273     return (FALSE);
01274   }
01275
01276   /* check to see if the address is already in the list
01277    */
01278   for (i = 0; i < len / SIZEOF(list[0]); i++)
01279       if (!memcmp(list[i], &mc->ethaddr, sizeof(list[0])))
01280          return (TRUE);
01281
01282   if (len > 0)
01283        nextentry = len / sizeof(list[0]);  /* append entry */
01284   else nextentry = 0;
01285
01286   memcpy (&list[nextentry], &mc->ethaddr, sizeof(eth_address));
01287   len += sizeof (list[0]);
01288
01289   if (!pkt_set_multicast_list((const eth_address*)&list,len))
01290   {
01291     /* If no space or no MC support, switch to MC2 mode
01292      */
01293     if (_pkt_errno == PDERR_NO_SPACE ||
01294         _pkt_errno == PDERR_NO_MULTICAST)
01295        return pkt_set_rcv_mode (RXMODE_MULTICAST2);
01296     return (FALSE);
01297   }
01298   return (TRUE);
01299 }
01300
01307 BOOL _eth_leave_mcast_group (const struct MultiCast *mc)
01308 {
01309   eth_address list[IPMULTI_SIZE];
01310   int i, len, idx;
01311
01312   SIO_TRACE (("_eth_leave_mcast_group"));
01313
01314   /* \note This should be expanded to include switching back to
01315    *       RXMODE_MULTCAST1 if the list of multicast addresses has
01316    *       shrunk sufficiently.
01317    *
01318    * First check to see if we're in RXMODE_MULTICAST2. if so return
01319    */
01320 #if defined(WIN32)
01321   if (_pkt_rxmode & RXMODE_MULTICAST2)
01322      return (TRUE);
01323 #else
01324   if (_pkt_rxmode >= RXMODE_MULTICAST2)
01325      return (TRUE);
01326 #endif
01327
01328   /* get the list of current multicast addresses
01329    */
01330   len = sizeof(list);
01331   if (!pkt_get_multicast_list (list, &len))
01332      return (FALSE);
01333
01334   /* find the apropriate entry
01335    */
01336   for (i = 0, idx = -1; i < len/SIZEOF(list[0]); i++)
01337       if (!memcmp(list[i],&mc->ethaddr,sizeof(list[0])))
01338          idx = i;
01339
01340   /* if it's not in the list, just return
01341    */
01342   if (idx == -1)
01343      return (TRUE);
01344
01345   /* ahh, but it _is_ in the list. So shorten the list
01346    * and send it back to the PKTDRVR
01347    */
01348   if (idx+1 < len/SIZEOF(list[0]))
01349      memmove (&list[idx], &list[idx+1], len-(idx+1)*sizeof(list[0]));
01350
01351   len -= sizeof(list[0]);
01352
01353   if (!pkt_set_multicast_list((const eth_address*)&list, len))
01354   {
01355     /* If no space or no MC support, switch mode
01356      */
01357     if (_pkt_errno == PDERR_NO_SPACE ||
01358         _pkt_errno == PDERR_NO_MULTICAST)
01359        return pkt_set_rcv_mode (RXMODE_MULTICAST2);
01360     return (FALSE);
01361   }
01362   return (TRUE);
01363 }
01364 #endif /* USE_MULTICAST */
01365
01370 #include "nochkstk.h"
01371
01375 void _eth_release (void)
01376 {
01377   if (!_eth_is_init)
01378      return;
01379
01380   /* Set original MAC address (if not fatal-error or serial-driver)
01381    */
01382   if (!_watt_fatal_error)
01383   {
01384     if (!_pktserial)
01385     {
01386       if (memcmp(&_eth_addr, &_eth_real_addr, sizeof(_eth_addr)))
01387          pkt_set_addr (&_eth_real_addr);
01388
01389 #if defined(USE_MULTICAST) || defined(USE_IPV6) /* restore startup Rx mode */
01390       if (_pkt_rxmode0 > -1 && _pkt_rxmode0 != _pkt_rxmode)
01391          pkt_set_rcv_mode (_pkt_rxmode0);
01392 #endif
01393     }
01394
01395 #if defined(USE_DEBUG)
01396     if (debug_on > 0)
01397     {
01398       DWORD drops = pkt_dropped();
01399       if (drops)
01400         (*_printf) ("%lu packets dropped\n", drops);
01401     }
01402 #endif
01403   }
01404   _eth_is_init = FALSE;  /* in case we crash in pkt_release() */
01405   pkt_release();
01406 }
01407
Generated on Wed Jan 25 15:42:38 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/PCSED.H Source File

SRC/PCSED.H

Go to the documentation of this file.
00001
00006 #ifndef _w32_PCSED_H
00007 #define _w32_PCSED_H
00008
00012 #define HW_TYPE_ETHER      1   /* Ether >= 10MB */
00013 #define HW_TYPE_ETHER_3MB  2   /* Ether = 3MB */
00014 #define HW_TYPE_AX25       3   /* Amateur packet-radio */
00015 #define HW_TYPE_TOKEN      6   /* IEEE 802 Networks */
00016 #define HW_TYPE_ARCNET     7   /* 2.5 MBit ARCNET */
00017 #define HW_TYPE_APPLETALK  8   /* Not at all supported */
00018 #define HW_TYPE_FDDI       10  /* Not really supported */
00019
00020 #include <sys/packon.h>  /* align structs on byte boundaries */
00021
00026 typedef struct eth_Header {
00027         eth_address  destination;
00028         eth_address  source;
00029         WORD         type;
00030       } eth_Header;
00031
00036 typedef struct eth_Packet {
00037         eth_Header   head;
00038         BYTE         data [ETH_MAX_DATA];
00039       } eth_Packet;
00040
00041
00046 typedef struct vlan_Header {
00047         eth_address  destination;
00048         eth_address  source;
00049         WORD         proto;
00050         WORD         tci;
00051         WORD         encap_proto;
00052       } vlan_Header;
00053
00058 typedef struct vlan_Packet {
00059         vlan_Header head;
00060         BYTE        data [VLAN_MAX_DATA];
00061       } vlan_Packet;
00062
00063
00068 typedef struct tok_Header {
00069         /* MAC header.
00070          */
00071         BYTE        accessCtrl;
00072         BYTE        frameCtrl;
00073         mac_address destination;
00074         mac_address source;
00075
00076         /* 2-18 bytes of Routing Information (RIF) may be present here.
00077          * We discard it anyway (see fix_tok_head()).
00078          */
00079
00080         /* LLC header.
00081          */
00082         BYTE        DSAP;
00083         BYTE        SSAP;
00084         BYTE        ctrl;
00085
00086         /* SNAP extension.
00087          */
00088         BYTE        org[3];
00089         WORD        type;
00090       } tok_Header;
00091
00096 typedef struct tok_Packet {
00097         tok_Header head;
00098         BYTE       data [TOK_MAX_DATA];
00099       } tok_Packet;
00100
00105 typedef struct llc_Header {
00106         BYTE  DSAP;
00107         BYTE  SSAP;
00108         union {
00109           BYTE  u_ctl;
00110           WORD  is_ctl;
00111           struct {
00112             BYTE  snap_ui;
00113             BYTE  snap_pi[5];
00114           } snap;
00115           struct {
00116             BYTE  snap_ui;
00117             BYTE  snap_orgcode[3];
00118             BYTE  snap_ethertype[2];
00119           } snap_ether;
00120         } ctl;
00121       } llc_Header;
00122
00126 #define TR_AC       0x10    /* Access Control; Frame bit (not token) */
00127 #define TR_FC       0x40    /* Frame Control;  LLC header follows */
00128 #define TR_DSAP     0xAA    /* DSAP field; SNAP follows LLC */
00129 #define TR_SSAP     0xAA    /* SSAP field; SNAP follows LLC */
00130 #define TR_CTRL     0x03    /* Unnumbered Information */
00131 #define TR_ORG      0x00    /* Organisation Code or Protocol Id */
00132
00133
00138 typedef struct fddi_Header {
00139         BYTE        frameCtrl;
00140         eth_address destination;
00141         eth_address source;
00142         BYTE        DSAP;
00143         BYTE        SSAP;
00144         BYTE        ctrl;
00145         BYTE        org[3];
00146         WORD        type;
00147       } fddi_Header;
00148
00153 typedef struct fddi_Packet {
00154         fddi_Header head;
00155         BYTE        data [FDDI_MAX_DATA];
00156       } fddi_Packet;
00157
00158 #define FDDI_FC     0x40   /* See above */
00159 #define FDDI_DSAP   0xAA
00160 #define FDDI_SSAP   0xAA
00161 #define FDDI_CTRL   0x03
00162 #define FDDI_ORG    0x00
00163
00164
00169 typedef struct arcnet_Header {
00170         BYTE   source;
00171         BYTE   destination;
00172         BYTE   type;
00173         BYTE   flags;
00174         WORD   sequence;
00175
00176        /* Only present in exception packets (flags == 0xFF)
00177         */
00178         BYTE   type2;     /* same as 'type' */
00179         BYTE   flags2;
00180         WORD   sequence2;
00181       } arcnet_Header;
00182
00183 #define ARC_HDRLEN    6  /* normal header length */
00184 #define ARC_TYPE_OFS  2
00185
00190 typedef struct arcnet_Packet {
00191         arcnet_Header head;
00192         BYTE          data [ARCNET_MAX_DATA];
00193       } arcnet_Packet;
00194
00195
00200 typedef union link_Packet {
00201         struct eth_Packet    eth;   /* _pktdevclass = PDCLASS_ETHER */
00202         struct tok_Packet    tok;   /* _pktdevclass = PDCLASS_TOKEN (_RIF) */
00203         struct fddi_Packet   fddi;  /* _pktdevclass = PDCLASS_FDDI  */
00204         struct arcnet_Packet arc;   /* _pktdevclass = PDCLASS_ARCNET */
00205         struct ip_Packet     ip;    /* _pktdevclass = PDCLASS_PPP/PDCLASS_SLIP */
00206         struct vlan_Packet   vlan;  /* not supported */
00207       } link_Packet;
00208
00209 #include <sys/packoff.h>            /* restore default packing */
00210
00211 struct _eth_last_info {
00212        struct {
00213          unsigned          size;    /* frame-size of last Rx */
00214          struct ulong_long tstamp;  /* timestamp of last Tx (not Win32) */
00215        } tx;
00216        struct {
00217          unsigned          size;    /* frame-size of last Rx */
00218          struct ulong_long tstamp;  /* timestamp of last Rx 1st upcall (not Win32) */
00219        } rx;
00220      };
00221
00222 extern struct _eth_last_info _eth_last;
00223
00224 extern BOOL       _ip_recursion, _eth_is_init;
00225 extern BOOL       _eth_ndis3pkt, _eth_SwsVpkt;
00226 extern BYTE       _eth_mac_len;
00227 extern const char _eth_not_init[];
00228
00229 W32_DATA mac_address _eth_addr;        /* Current MAC-address (not AX-25) */
00230 W32_DATA mac_address _eth_real_addr;   /* MAC-addr before _eth_set_addr() */
00231 W32_DATA mac_address _eth_loop_addr;   /* CF:00:00:00:00:00 */
00232 W32_DATA mac_address _eth_brdcast;     /* FF:FF:FF:FF:FF:FF */
00233
00234 W32_DATA void *(*_eth_recv_hook) (WORD *type);
00235 W32_DATA int   (*_eth_recv_peek) (void *mac_buf);
00236 W32_DATA int   (*_eth_xmit_hook) (const void *mac_buf, unsigned len);
00237
00238 W32_FUNC int   _eth_init         (void);
00239 W32_FUNC void  _eth_release      (void);
00240 W32_FUNC int   _eth_send         (WORD len, const void *sock, const char *file, unsigned line);
00241 W32_FUNC int   _eth_set_addr     (const void *addr);
00242 W32_FUNC void *_eth_formatpacket (const void *mac_dest, WORD mac_type);
00243 W32_FUNC void  _eth_free         (const void *pkt);
00244 W32_FUNC void *_eth_arrived      (WORD *type, BOOL *brdcast);
00245 W32_FUNC BYTE  _eth_get_hwtype   (BYTE *hwtype, BYTE *hwlen);
00246
00247 #if defined(USE_MULTICAST)
00248   #include "pcmulti.h"
00249
00250   W32_FUNC BOOL _eth_join_mcast_group  (const struct MultiCast *mc);
00251   W32_FUNC BOOL _eth_leave_mcast_group (const struct MultiCast *mc);
00252 #endif
00253
00254 /*
00255  * Return pointer to hardware source address of
00256  * an IP packet. For Ethernet:
00257  *
00258  *     struct eth_Packet {
00259  *      -14-> BYTE  dest [6];
00260  *       -8-> BYTE  src  [6];
00261  *            WORD  type;
00262  *       ip-> BYTE  data [1500];
00263  *          };
00264  *
00265  * For Token-Ring:
00266  *     struct tok_Packet {
00267  *      -22-> BYTE  AC, FC;
00268  *            BYTE  dest [6];
00269  *      -14-> BYTE  src  [6];
00270  *            BYTE  DSAP, SSAP, ctrl;
00271  *            BYTE  org [3];
00272  *            WORD  type;
00273  *       ip-> BYTE  data [1500];
00274  *
00275  * These macros and functions should never be called for serial protocols
00276  * except that it doesn't hurt to use MAC_SRC() for all driver classes.
00277  */
00278
00279 #if defined(USE_DEBUG) && 0  /* slower, but safer method */
00280   extern void *_eth_mac_hdr (const in_Header *ip)  ATTR_NORETURN();
00281   extern void *_eth_mac_dst (const in_Header *ip)  ATTR_NORETURN();
00282   extern void *_eth_mac_src (const in_Header *ip)  ATTR_NORETURN();
00283   extern WORD  _eth_mac_typ (const in_Header *ip)  ATTR_NORETURN();
00284
00285   #define MAC_HDR(ip) _eth_mac_hdr(ip)
00286   #define MAC_DST(ip) _eth_mac_dst(ip)
00287   #define MAC_SRC(ip) _eth_mac_src(ip)
00288   #define MAC_TYP(ip) _eth_mac_typ(ip)
00289 #else
00290   #define MAC_HDR(ip) (void*) ((BYTE*)(ip) - _pkt_ip_ofs)
00291
00292   #define MAC_DST(ip) (void*) ((BYTE*)(ip) -                              \
00293                         (_pktdevclass == PDCLASS_TOKEN  ? _pkt_ip_ofs-2 : \
00294                          _pktdevclass == PDCLASS_ARCNET ? _pkt_ip_ofs-1 : \
00295                          _pktdevclass == PDCLASS_FDDI   ? _pkt_ip_ofs-5 : \
00296                          _pkt_ip_ofs))
00297
00298   #define MAC_SRC(ip) (void*) ((BYTE*)(ip) -                              \
00299                         (_pktdevclass == PDCLASS_TOKEN  ? _pkt_ip_ofs-8 : \
00300                          _pktdevclass == PDCLASS_ARCNET ? _pkt_ip_ofs   : \
00301                          _pktdevclass == PDCLASS_FDDI   ? _pkt_ip_ofs-7 : \
00302                          _pkt_ip_ofs-6))
00303
00304   #define MAC_TYP(ip) (*(WORD*) ((BYTE*)(ip) - \
00305                       (_pktdevclass == PDCLASS_ARCNET ? _pkt_ip_ofs-2 : 2)))
00306 #endif
00307
00308 /*
00309  * Macros to set or clear peer's source MAC-address stored in
00310  * the _udp_Socket / _tcp_Socket.
00311  * Only used on passive (listening) udp/tcp sockets.
00312  * We don't use arp_resolve() because of reentrancy problems.
00313  * But if inbound packets come from a different gateway than
00314  * outbound packets, then we're toast..
00315  */
00316 #define SET_PEER_MAC_ADDR(tcb,ip) do {                        \
00317           if (!_pktserial)                                    \
00318              memcpy (&(tcb)->his_ethaddr[0], MAC_SRC(ip), 6); \
00319         } while (0)
00320
00321 #define CLR_PEER_MAC_ADDR(tcb) do {                 \
00322           if (!_pktserial)                          \
00323              memset (&(tcb)->his_ethaddr[0], 0, 6); \
00324         } while (0)
00325
00326 #endif
Generated on Wed Jan 25 15:42:38 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/PCSLIP.H Source File

SRC/PCSLIP.H

Go to the documentation of this file.
00001
00004 #ifndef _w32_PCSLIP_H
00005 #define _w32_PCSLIP_H
00006
00007 extern int slip_init (void);
00008
00009 #endif
Generated on Wed Jan 25 15:42:38 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/PCSTAT.C Source File

SRC/PCSTAT.C

Go to the documentation of this file.
00001
00005 /*  Update and printing of MAC/IP/ICMP/IGMP/UDP/TCP input/output
00006  *  statistics counters.
00007  *
00008  *  Copyright (c) 1997-2002 Gisle Vanem <giva@bgnett.no>
00009  *
00010  *  Redistribution and use in source and binary forms, with or without
00011  *  modification, are permitted provided that the following conditions
00012  *  are met:
00013  *  1. Redistributions of source code must retain the above copyright
00014  *     notice, this list of conditions and the following disclaimer.
00015  *  2. Redistributions in binary form must reproduce the above copyright
00016  *     notice, this list of conditions and the following disclaimer in the
00017  *     documentation and/or other materials provided with the distribution.
00018  *  3. All advertising materials mentioning features or use of this software
00019  *     must display the following acknowledgement:
00020  *       This product includes software developed by Gisle Vanem
00021  *       Bergen, Norway.
00022  *
00023  *  THIS SOFTWARE IS PROVIDED BY ME (Gisle Vanem) AND CONTRIBUTORS ``AS IS''
00024  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00025  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00026  *  ARE DISCLAIMED.  IN NO EVENT SHALL I OR CONTRIBUTORS BE LIABLE FOR ANY
00027  *  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00028  *  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00029  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00030  *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00031  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00032  *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00033  *
00034  *  G. Vanem <giva@bgnett.no> 1997
00035  */
00036
00037 #include <stdio.h>
00038 #include <string.h>
00039 #include <netinet/in.h>
00040 #include <net/ppp_defs.h>
00041 #include <arpa/inet.h>
00042
00043 #include "wattcp.h"
00044 #include "strings.h"
00045 #include "sock_ini.h"
00046 #include "pcconfig.h"
00047 #include "pcicmp.h"
00048 #include "pcqueue.h"
00049 #include "pcsed.h"
00050 #include "split.h"
00051 #include "misc.h"
00052 #include "timer.h"
00053 #include "pcpkt.h"
00054 #include "pcdbug.h"
00055 #include "pppoe.h"
00056 #include "pcstat.h"
00057
00058 int sock_stats (sock_type *sock, DWORD *days, WORD *inactive,
00059                 WORD *cwindow, DWORD *avg, DWORD *sd)
00060 {
00061   _tcp_Socket *s = &sock->tcp;
00062
00063   if (s->ip_type != TCP_PROTO)
00064      return (0);
00065
00066   if (days)     *days     = get_day_num() - start_day;
00067   if (inactive) *inactive = sock_inactive;
00068 #if defined(USE_UDP_ONLY)
00069   if (cwindow)  *cwindow  = 0;
00070   if (avg)      *avg      = 0;
00071   if (sd)       *sd       = 0;
00072 #else
00073   if (cwindow)  *cwindow  = s->cwindow;
00074   if (avg)      *avg      = s->vj_sa >> 3;
00075   if (sd)       *sd       = s->vj_sd >> 2;
00076 #endif
00077   return (1);
00078 }
00079
00080 #if !defined(USE_STATISTICS)
00081   void print_mac_stats (void)  {}
00082   void print_vjc_stats (void)  {}
00083   void print_pkt_stats (void)  {}
00084   void print_ip4_stats (void)  {}
00085   void print_ip6_stats (void)  {}
00086   void print_icmp_stats(void)  {}
00087   void print_icmp6_stats(void) {}
00088   void print_igmp_stats(void)  {}
00089   void print_udp_stats (void)  {}
00090   void print_tcp_stats (void)  {}
00091   void print_all_stats (void)  {}
00092   void reset_stats     (void)  {}
00093
00094 #else  /* rest of file */
00095
00096 struct macstat   macstats;
00097 struct ipstat    ip4stats;
00098 struct ip6stat   ip6stats;
00099 struct udpstat   udpstats;
00100 struct tcpstat   tcpstats;
00101 struct icmpstat  icmpstats;
00102 struct icmp6stat icmp6stats;
00103 struct igmpstat  igmpstats;
00104 struct pppoestat pppoestats;
00105
00106 void reset_stats (void)
00107 {
00108   memset (&macstats,  0, sizeof(macstats));
00109   memset (&ip4stats,  0, sizeof(ip4stats));
00110   memset (&ip6stats,  0, sizeof(ip6stats));
00111   memset (&udpstats,  0, sizeof(udpstats));
00112   memset (&tcpstats,  0, sizeof(tcpstats));
00113   memset (&icmpstats, 0, sizeof(icmpstats));
00114   memset (&igmpstats, 0, sizeof(igmpstats));
00115   memset (&pppoestats,0, sizeof(pppoestats));
00116 }
00117
00118 static __inline void show_stat (const char *name, DWORD num)
00119 {
00120   if (num)
00121     (*_printf) ("      %-13s %10lu\n", name, num);
00122 }
00123
00124 #if defined(HAVE_UINT64) && defined(USE_IPV6)
00125 static __inline void show_stat64 (const char *name, uint64 num)
00126 {
00127   if (num)
00128     (*_printf) ("      %-13s %10" U64_FMT "\n", name, num);
00129 }
00130 #endif
00131
00132 void print_mac_stats (void)
00133 {
00134   (*_printf) ("MAC   input stats:\n"
00135               "      dropped %lu, waiting %d, looped %lu, non-IP recv %lu sent %lu\n"
00136               "      unknown types, %lu, LLC frames %lu, IP-recursions %lu",
00137               pkt_dropped(), pkt_waiting(), macstats.num_mac_loop,
00138               macstats.non_ip_recv, macstats.non_ip_sent,
00139               macstats.num_unk_type, macstats.num_llc_frames,
00140               macstats.num_ip_recurse);
00141
00142 #if defined(USE_FAST_PKT) || defined(WIN32)
00143   (*_printf) (" \n      wrong handle %lu, bad-sync %lu, too large %lu, too small %lu",
00144               macstats.num_wrong_handle, macstats.num_bad_sync,
00145               macstats.num_too_large, macstats.num_too_small);
00146 #endif
00147
00148   (*_printf) (" \nMAC   output stats:\n"
00149               "      Tx errors     %10lu %s\n"
00150               "      Tx retries    %10lu\n"
00151               "      Tx timeout    %10lu\n",
00152               macstats.num_tx_err, macstats.num_tx_err ? "****" : "",
00153               macstats.num_tx_retry, macstats.num_tx_timeout);
00154 }
00155
00156 void print_arp_stats (void)
00157 {
00158   (*_printf) ("ARP   Requests:     %10lu recv\n"
00159               "      Requests:     %10lu sent\n"
00160               "      Replies:      %10lu recv\n"
00161               "      Replies:      %10lu sent\n",
00162               macstats.arp.request_recv, macstats.arp.request_sent,
00163               macstats.arp.reply_recv, macstats.arp.reply_sent);
00164 }
00165
00166 void print_rarp_stats (void)
00167 {
00168 #if defined(USE_RARP)
00169   DWORD total = macstats.rarp.request_recv +
00170                 macstats.rarp.request_sent +
00171                 macstats.rarp.reply_recv   +
00172                 macstats.rarp.reply_sent;
00173
00174   if (total > 0)
00175      (*_printf) ("RARP  Requests:     %10lu recv\n"
00176                  "      Requests:     %10lu sent\n"
00177                  "      Replies:      %10lu recv\n"
00178                  "      Replies:      %10lu sent\n",
00179                  macstats.rarp.request_recv, macstats.rarp.request_sent,
00180                  macstats.rarp.reply_recv, macstats.rarp.reply_sent);
00181 #endif
00182 }
00183
00184 void print_vjc_stats (void)
00185 {
00186 #if !defined(WIN32)
00187   struct slcompress vjc;
00188
00189   if (stricmp(_pktdrvrname,"PPPD220F") &&   /* not using DOSPPP driver */
00190       stricmp(_pktdrvrname,"LADSoftPPP$"))  /* or LadSoft's lsppp */
00191      return;
00192
00193   (*_printf) ("VJ compression:\n");
00194
00195   if (!pkt_get_vjstats(&vjc))
00196   {
00197     (*_printf) ("      not available\n\n");
00198     return;
00199   }
00200
00201   (*_printf) ("      Tx TCP packets: %lu, non-TCP: %lu\n",
00202               vjc.sls_o_tcp, vjc.sls_o_nontcp);
00203
00204   (*_printf) ("      Rx error packets: %lu, tossed: %lu\n",
00205               vjc.sls_i_error, vjc.sls_i_tossed);
00206
00207   (*_printf) ("      Rx runt packets: %lu, bad checksum: %lu\n",
00208                vjc.sls_i_runt, vjc.sls_i_badcheck);
00209
00210   (*_printf) ("      connection state searches: %lu, misses: %lu\n",
00211               vjc.sls_o_searches, vjc.sls_o_misses);
00212
00213   (*_printf) ("      oldest xmit in ring: %-9u\n", vjc.xmit_oldest);
00214   (*_printf) ("      compression state flags: 0x%X\n",  vjc.flags);
00215
00216   (*_printf) ("      highest slot:         Tx %-5u Rx %u\n",
00217               vjc.tslot_limit, vjc.rslot_limit);
00218
00219   (*_printf) ("      most recent id:       Tx %-5u Rx %u\n",
00220                vjc.xmit_current, vjc.recv_current);
00221
00222   (*_printf) ("      uncompressed packets: Tx %-5lu Rx %lu\n",
00223               vjc.sls_o_uncompressed, vjc.sls_i_uncompressed);
00224
00225   (*_printf) ("      compressed packets:   Tx %-5lu Rx %lu\n",
00226               vjc.sls_o_compressed, vjc.sls_i_compressed);
00227
00228   if (!stricmp(_pktdrvrname,"PPPD220F"))  /* using DOSPPP driver */
00229   {
00230     struct cstate cstate;
00231     WORD   cs_ofs, rx_num = 0, tx_num = 0;
00232
00233     (*_printf) ("  Connection states:\n");
00234
00235     for (cs_ofs = vjc.cstate_ptr_tstate;
00236          pkt_get_cstate(&cstate,cs_ofs) && tx_num < vjc.tslot_limit;
00237          cs_ofs = cstate.cs_next, tx_num++)
00238         (*_printf) ("      Tx-id %2d: IP %15s -> %15s, TCP port %u -> %d\n",
00239                     cstate.cs_this,
00240                     inet_ntoa(*(struct in_addr*)&cstate.cs_ip.source),
00241                     inet_ntoa(*(struct in_addr*)&cstate.cs_ip.destination),
00242                     intel16(cstate.cs_tcp.srcPort),
00243                     intel16(cstate.cs_tcp.dstPort));
00244
00245     for (cs_ofs = vjc.cstate_ptr_rstate;
00246          pkt_get_cstate(&cstate,cs_ofs) && rx_num < vjc.rslot_limit;
00247          cs_ofs = cstate.cs_next, rx_num++)
00248         (*_printf) ("      Rx-id %2d: IP %15s -> %15s, TCP port %u -> %d\n",
00249                     cstate.cs_this,
00250                     inet_ntoa(*(struct in_addr*)&cstate.cs_ip.source),
00251                     inet_ntoa(*(struct in_addr*)&cstate.cs_ip.destination),
00252                     intel16(cstate.cs_tcp.srcPort),
00253                     intel16(cstate.cs_tcp.dstPort));
00254     if (rx_num + tx_num == 0)
00255        (*_printf) ("      not available\n");
00256   }
00257   (*_printf) (" \n");
00258 #endif
00259 }
00260
00261 void print_pkt_stats (void)
00262 {
00263   struct PktStats stat, total;
00264
00265   (*_printf) ("Driver statistics:\n");
00266   if (!pkt_get_stats(&stat,&total))
00267   {
00268     (*_printf) ("      Not available\n");
00269     return;
00270   }
00271
00272   (*_printf) ("      Rx: %9lu pkt, %10lu bytes, %6lu errors, %6lu lost  (this session)\n",
00273               stat.in_packets, stat.in_bytes, stat.in_errors, stat.lost);
00274   (*_printf) ("      Tx: %9lu pkt, %10lu bytes, %6lu errors\n",
00275               stat.out_packets, stat.out_bytes, stat.out_errors);
00276
00277   (*_printf) ("      Rx: %9lu pkt, %10lu bytes, %6lu errors, %6lu lost  (since boot)\n",
00278               total.in_packets, total.in_bytes, total.in_errors, total.lost);
00279   (*_printf) ("      Tx: %9lu pkt, %10lu bytes, %6lu errors\n",
00280               total.out_packets, total.out_bytes, total.out_errors);
00281 }
00282
00283 void print_pppoe_stats (void)
00284 {
00285 #if defined(USE_PPPOE)
00286   (*_printf) ("PPPoE stats:\n");
00287   show_stat ("Tx Discovery:", pppoestats.num_disc_sent);
00288   show_stat ("Rx Discovery:", pppoestats.num_disc_recv);
00289   show_stat ("Tx Session:",   pppoestats.num_sess_sent);
00290   show_stat ("Rx Session:",   pppoestats.num_sess_recv);
00291 #endif
00292 }
00293
00294 void print_ip4_stats (void)
00295 {
00296   (*_printf) ("IP4   input stats:\n");
00297   show_stat ("total:",      ip4stats.ips_total);
00298   show_stat ("badsum:",     ip4stats.ips_badsum);
00299   show_stat ("badver:",     ip4stats.ips_badvers);
00300   show_stat ("short:",      ip4stats.ips_tooshort);
00301   show_stat ("frags:",      ip4stats.ips_fragments);
00302   show_stat ("fragdrop:",   ip4stats.ips_fragdropped);
00303   show_stat ("fragtimeout:",ip4stats.ips_fragtimeout);
00304   show_stat ("reassemble:", ip4stats.ips_reassembled);
00305   show_stat ("noproto:",    ip4stats.ips_noproto);
00306   show_stat ("delivered:",  ip4stats.ips_delivered);
00307   show_stat ("badoptions:", ip4stats.ips_badoptions);
00308   show_stat ("dropped:",    ip4stats.ips_idropped);
00309
00310   (*_printf) ("IP4   output stats:\n");
00311   show_stat ("total:",      ip4stats.ips_rawout);
00312   show_stat ("noroute:",    ip4stats.ips_noroute);
00313   show_stat ("frags:",      ip4stats.ips_ofragments);
00314   show_stat ("dropped:",    ip4stats.ips_odropped);
00315 }
00316
00317 void print_ip6_stats (void)
00318 {
00319 #if defined(HAVE_UINT64) && defined(USE_IPV6)
00320   (*_printf) ("IP6   input stats:\n");
00321   show_stat64 ("total:",     ip6stats.ip6s_total);
00322   show_stat64 ("badver:",    ip6stats.ip6s_badvers);
00323   show_stat64 ("short:",     ip6stats.ip6s_tooshort);
00324   show_stat64 ("frags:",     ip6stats.ip6s_fragments);
00325   show_stat64 ("fragdrop:",  ip6stats.ip6s_fragdropped);
00326   show_stat64 ("fragtime:",  ip6stats.ip6s_fragtimeout);
00327   show_stat64 ("reassemble:",ip6stats.ip6s_reassembled);
00328   show_stat64 ("delivered:", ip6stats.ip6s_delivered);
00329   show_stat64 ("badoptions:",ip6stats.ip6s_badoptions);
00330
00331   (*_printf) ("IP6   output stats:\n");
00332   show_stat64 ("total:",     ip6stats.ip6s_rawout);
00333   show_stat64 ("noroute:",   ip6stats.ip6s_noroute);
00334   show_stat64 ("frags:",     ip6stats.ip6s_ofragments);
00335   show_stat64 ("dropped:",   ip6stats.ip6s_odropped);
00336 #endif
00337 }
00338
00339 void print_icmp6_stats (void)
00340 {
00341 #if defined(HAVE_UINT64) && defined(USE_IPV6)
00342   uint64 total_in  = 0;
00343   uint64 total_out = 0;
00344   int    i;
00345
00346   (*_printf) ("ICMP6 input stats:\n");
00347
00348   for (i = 0; i < DIM(icmp6stats.icp6s_inhist); i++)
00349       total_in += icmp6stats.icp6s_inhist[i];
00350
00351   show_stat64 ("total:",       total_in);
00352
00353   show_stat64 ("badsum:",     icmp6stats.icp6s_checksum);
00354   show_stat64 ("short:",      icmp6stats.icp6s_tooshort);
00355   show_stat64 ("badcode:",    icmp6stats.icp6s_badcode);
00356
00357   (*_printf) ("ICMP6 output stats:\n");
00358   for (i = 0; i < DIM(icmp6stats.icp6s_outhist); i++)
00359       total_out += icmp6stats.icp6s_outhist[i];
00360
00361   show_stat64 ("total:",       total_out);
00362   show_stat64 ("too big:",     icmp6stats.icp6s_opacket_too_big);
00363   show_stat64 ("exceed xmit:", icmp6stats.icp6s_otime_exceed_transit);
00364   show_stat64 ("exceed reasm:",icmp6stats.icp6s_otime_exceed_reassembly);
00365 #endif
00366 }
00367
00368 void print_icmp_stats (void)
00369 {
00370   DWORD  total_in  = 0;
00371   DWORD  total_out = 0;
00372   int    i;
00373   static const char *types[ICMP_MAXTYPE+1] = {
00374               "echoreply:",
00375               "1?:",
00376               "2?:",
00377               "unreach:",
00378               "srcquench:",
00379               "redirect:",
00380               "6?:",
00381               "7?:",
00382               "echorequest:",
00383               "router adv:",
00384               "router sol:",
00385               "timex:",
00386               "parm prob:",
00387               "tstamp req:",
00388               "tstamp rep:",
00389               "info req:",
00390               "info rep:",
00391               "mask req:",
00392               "mask rep:"
00393             };
00394
00395   (*_printf) ("ICMP  input stats:\n");
00396   for (i = 0; i < ICMP_MAXTYPE; i++)
00397       total_in += icmpstats.icps_inhist[i];
00398   show_stat ("total:", total_in);
00399
00400   show_stat ("badsum:", icmpstats.icps_checksum);
00401   show_stat ("badcode:",icmpstats.icps_badcode);
00402   show_stat ("short:",  icmpstats.icps_tooshort);
00403
00404   for (i = 0; i < ICMP_MAXTYPE; i++)
00405      show_stat (types[i], icmpstats.icps_inhist[i]);
00406
00407   (*_printf) ("ICMP  output stats:\n");
00408   for (i = 0; i < ICMP_MAXTYPE; i++)
00409       total_out += icmpstats.icps_outhist[i];
00410   show_stat ("total:", total_out);
00411
00412   for (i = 0; i < ICMP_MAXTYPE; i++)
00413      show_stat (types[i], icmpstats.icps_outhist[i]);
00414 }
00415
00416 void print_igmp_stats (void)
00417 {
00418 #if defined(USE_MULTICAST)
00419   (*_printf) ("IGMP  input stats:\n");
00420   show_stat ("total:",        igmpstats.igps_rcv_total);
00421   show_stat ("badsum:",       igmpstats.igps_rcv_badsum);
00422   show_stat ("short:",        igmpstats.igps_rcv_tooshort);
00423   show_stat ("queries:",      igmpstats.igps_rcv_queries);
00424   show_stat ("queries (bad):",igmpstats.igps_rcv_badqueries);
00425   show_stat ("reports:",      igmpstats.igps_rcv_reports);
00426   show_stat ("  bad:",        igmpstats.igps_rcv_badreports);
00427   show_stat ("  group:",      igmpstats.igps_rcv_ourreports);
00428
00429   (*_printf) ("IGMP  output stats:\n");
00430   show_stat ("reports:", igmpstats.igps_snd_reports);
00431 #endif
00432 }
00433
00434 void print_udp_stats (void)
00435 {
00436   (*_printf) ("UDP   input stats:\n");
00437   show_stat ("total:",      udpstats.udps_ipackets);
00438   show_stat ("drops:",      udpstats.udps_hdrops);
00439   show_stat ("badsum:",     udpstats.udps_badsum);
00440   show_stat ("no service:", udpstats.udps_noport);
00441   show_stat ("broadcast:",  udpstats.udps_noportbcast);
00442   show_stat ("queue full:", udpstats.udps_fullsock);
00443
00444   (*_printf) ("UDP   output stats:\n");
00445   show_stat ("total:",      udpstats.udps_opackets);
00446 }
00447
00448 void print_tcp_stats (void)
00449 {
00450 #if !defined(USE_UDP_ONLY)
00451   (*_printf) ("TCP   input stats:\n");
00452   show_stat ("total:",       tcpstats.tcps_rcvtotal);
00453   show_stat ("drops:",       tcpstats.tcps_drops);
00454   show_stat ("badsum:",      tcpstats.tcps_rcvbadsum);
00455   show_stat ("badhofs:",     tcpstats.tcps_rcvbadoff);
00456   show_stat ("conn-okay:",   tcpstats.tcps_connects);
00457   show_stat ("conn-accept:", tcpstats.tcps_accepts);
00458   show_stat ("conn-drops:",  tcpstats.tcps_conndrops);
00459   show_stat ("inS pkts:",    tcpstats.tcps_rcvpack);
00460   show_stat ("inS bytes:",   tcpstats.tcps_rcvbyte);
00461   show_stat ("OoO pkts:",    tcpstats.tcps_rcvoopack);
00462   show_stat ("OoO bytes:",   tcpstats.tcps_rcvoobyte);
00463   show_stat ("ACK pkts:",    tcpstats.tcps_rcvackpack);
00464   show_stat ("ACK bytes:",   tcpstats.tcps_rcvackbyte);
00465   show_stat ("ACK nosent:",   tcpstats.tcps_rcvacktoomuch);
00466   show_stat ("dup ACK:",     tcpstats.tcps_rcvduppack);
00467   show_stat ("dup bytes:",   tcpstats.tcps_rcvdupbyte);
00468   show_stat ("pers-drop:",   tcpstats.tcps_persistdrop);
00469
00470   (*_printf) ("TCP   output stats:\n");
00471   show_stat ("total:",       tcpstats.tcps_sndtotal);
00472   show_stat ("data pkts:",   tcpstats.tcps_sndpack);
00473   show_stat ("data bytes:",  tcpstats.tcps_sndbyte);
00474   show_stat ("conn-attempt:",tcpstats.tcps_connattempt);
00475   show_stat ("SYN/FIN/RST:", tcpstats.tcps_sndctrl);
00476   show_stat ("close/drops:", tcpstats.tcps_closed);
00477   show_stat ("OOB pkts:",    tcpstats.tcps_sndurg);
00478   show_stat ("ACK pkts:",    tcpstats.tcps_sndacks);
00479   show_stat ("ACK dly:",     tcpstats.tcps_delack);
00480   show_stat ("ACK win upd:", tcpstats.tcps_sndwinup);
00481   show_stat ("retrans to:",  tcpstats.tcps_rexmttimeo);
00482   show_stat ("keepalive pr:",tcpstats.tcps_keepprobe);
00483   show_stat ("keepalive to:",tcpstats.tcps_keeptimeo);
00484   show_stat ("RTTcache add:",tcpstats.tcps_cachedrtt);
00485   show_stat ("RTTcache get:",tcpstats.tcps_usedrtt);
00486 #endif
00487 }
00488
00489 void print_all_stats (void)
00490 {
00491   int save = ctrace_on;
00492
00493   ctrace_on = 0;
00494
00495   print_vjc_stats();
00496   print_pkt_stats();
00497   print_mac_stats();
00498
00499   if (!_pktserial)
00500   {
00501     print_arp_stats();
00502     print_rarp_stats();
00503     print_pppoe_stats();
00504   }
00505
00506   print_ip4_stats();
00507   print_ip6_stats();
00508   print_icmp_stats();
00509   print_icmp6_stats();
00510   print_igmp_stats();
00511   print_udp_stats();
00512   print_tcp_stats();
00513
00514   ctrace_on = save;
00515 }
00516
00517 /*
00518  * Called from the link-layer input routine _eth_arrived().
00519  */
00520 void update_in_stat (void)
00521 {
00522   const struct pkt_split *ps;
00523   const eth_Header       *eth;
00524   const tok_Header       *tok;
00525   const ICMP_PKT         *icmp;
00526   BOOL  got_ip = FALSE;
00527   BYTE  type;
00528
00529   for (ps = pkt_get_split_in(); ps->data; ps++)
00530   {
00531     switch (ps->type)
00532     {
00533       case TYPE_ETHER_HEAD:
00534            eth = (const eth_Header*) ps->data;
00535            if (!memcmp(eth->source,_eth_addr,sizeof(_eth_addr)))
00536               macstats.num_mac_loop++;
00537            break;
00538
00539       case TYPE_TOKEN_HEAD:
00540            tok = (const tok_Header*) ps->data;
00541            if (!memcmp(tok->source,_eth_addr,sizeof(_eth_addr)))
00542               macstats.num_mac_loop++;
00543            break;
00544
00545       case TYPE_LLC_HEAD:
00546            macstats.num_llc_frames++;
00547            break;
00548
00549       case TYPE_ARP:
00550            {
00551              const arp_Header *arp = (const arp_Header*) ps->data;
00552
00553              if (arp->opcode == ARP_REQUEST)
00554                 macstats.arp.request_recv++;
00555              else if (arp->opcode == ARP_REPLY)
00556                 macstats.arp.reply_recv++;
00557              break;
00558            }
00559 #if defined(USE_RARP)
00560       case TYPE_RARP:
00561            {
00562              const rarp_Header *rarp = (const rarp_Header*) ps->data;
00563
00564              if (rarp->opcode == RARP_REQUEST)
00565                 macstats.rarp.request_recv++;
00566              else if (rarp->opcode == RARP_REPLY)
00567                 macstats.rarp.reply_recv++;
00568              break;
00569            }
00570 #endif
00571
00572 #if defined(USE_PPPOE)
00573       case TYPE_PPPOE_DISC:
00574            pppoestats.num_disc_recv++;
00575            break;
00576
00577       case TYPE_PPPOE_SESS:
00578            pppoestats.num_sess_recv++;
00579            break;
00580
00581       case TYPE_PPP_LCP:
00582       case TYPE_PPP_IPCP:
00584            break;
00585 #endif
00586
00587 #if defined(USE_IPV6)
00588       case TYPE_IP6:
00589            ip6stats.ip6s_total++;
00590            got_ip = TRUE;
00591            break;
00592
00593       case TYPE_IP6_HOP:
00594       case TYPE_IP6_IPV6:
00595       case TYPE_IP6_ROUTING:
00596       case TYPE_IP6_FRAGMENT:
00597       case TYPE_IP6_ESP:
00598       case TYPE_IP6_AUTH:
00599       case TYPE_IP6_ICMP:
00600       case TYPE_IP6_DEST:
00602            break;
00603       case TYPE_IP6_NONE:
00604       case TYPE_IP6_UNSUPP:
00605            break; /* ignore */
00606 #endif
00607
00608       case TYPE_IP4:
00609            ip4stats.ips_total++;
00610            got_ip = TRUE;
00611            break;
00612
00613       case TYPE_IP4_FRAG:
00614            got_ip = TRUE;
00615            break;
00616
00617       case TYPE_ICMP:
00618            icmp = (const ICMP_PKT*) ps->data;
00619            type = icmp->unused.type;
00620            if (type <= ICMP_MAXTYPE)
00621               icmpstats.icps_inhist[(int)type]++;
00622            return;
00623
00624       case TYPE_IGMP:
00625            igmpstats.igps_rcv_total++;
00626            return;
00627
00628       case TYPE_UDP_HEAD:
00629            udpstats.udps_ipackets++;
00630            return;
00631
00632       case TYPE_TCP_HEAD:
00633            tcpstats.tcps_rcvtotal++;
00634            return;
00635
00636       default:
00637 #if defined(USE_DEBUG) && 1  /* !! bug hunt */
00638            dbug_printf ("Unknown split-type %d\n", ps->type);
00639 #endif
00640            macstats.num_unk_type++;
00641            break;
00642     }
00643   }
00644   if (!got_ip)
00645      macstats.non_ip_recv++;
00646 }
00647
00648 /*
00649  * Called from the link-layer output routine _eth_send().
00650  */
00651 void update_out_stat (void)
00652 {
00653   const struct pkt_split *ps;
00654   const arp_Header       *arp;
00655   const in_Header        *ip;
00656   const ICMP_PKT         *icmp;
00657   BOOL  got_ip  = FALSE;
00658   BYTE  type, flags;
00659   DWORD ofs;
00660
00661   for (ps = pkt_get_split_out(); ps->data; ps++)
00662   {
00663     switch (ps->type)
00664     {
00665       case TYPE_ARP:
00666            arp = (arp_Header*) ps->data;
00667            if (arp->opcode == ARP_REQUEST)
00668               macstats.arp.request_sent++;
00669            else if (arp->opcode == ARP_REPLY)
00670               macstats.arp.reply_sent++;
00671            break;
00672
00673 #if defined(USE_RARP)
00674       case TYPE_RARP:
00675            {
00676              const rarp_Header *rarp = (rarp_Header*) ps->data;
00677
00678              if (rarp->opcode == RARP_REQUEST)
00679                 macstats.rarp.request_sent++;
00680              else if (rarp->opcode == RARP_REPLY)
00681                 macstats.rarp.reply_sent++;
00682            }
00683            break;
00684 #endif
00685
00686 #if defined(USE_PPPOE)
00687       case TYPE_PPPOE_DISC:
00688            pppoestats.num_disc_sent++;
00689            break;
00690
00691       case TYPE_PPPOE_SESS:
00692            pppoestats.num_sess_sent++;
00693
00694       case TYPE_PPP_LCP:
00695       case TYPE_PPP_IPCP:
00697            break;
00698 #endif
00699
00700 #if defined(USE_IPV6)
00701       case TYPE_IP6:
00702            got_ip = TRUE;
00703            ip6stats.ip6s_rawout++;
00704            break;
00705
00706       case TYPE_IP6_HOP:
00707       case TYPE_IP6_IPV6:
00708       case TYPE_IP6_ROUTING:
00709       case TYPE_IP6_FRAGMENT:
00710       case TYPE_IP6_ESP:
00711       case TYPE_IP6_AUTH:
00712       case TYPE_IP6_ICMP:
00713       case TYPE_IP6_DEST:
00715            break;
00716 #endif
00717
00718       case TYPE_IP4:
00719            got_ip = TRUE;
00720            ip = (const struct in_Header*) ps->data;
00721            ip4stats.ips_rawout++;   /* count raw IP (fragmented or not) */
00722
00723            ofs = intel16 (ip->frag_ofs);
00724            ofs = (ofs & IP_OFFMASK) << 3;
00725            if (ofs)
00726               return;  /* only fragments with ofs 0 (already counted) */
00727            break;
00728
00729       case TYPE_ICMP:
00730            icmp = (const ICMP_PKT*) ps->data;
00731            type = icmp->unused.type;
00732            if (type <= ICMP_MAXTYPE)
00733               icmpstats.icps_outhist[(int)type]++;
00734            return;
00735
00736 #if defined(USE_MULTICAST)
00737       case TYPE_IGMP:
00738            {
00739              const IGMP_packet *igmp = (const IGMP_packet*) ps->data;
00740
00741              if (igmp->version == 1 && igmp->type == IGMPv1_REPORT)
00742                 igmpstats.igps_snd_reports++;
00743              return;
00744            }
00745 #endif
00746
00747       case TYPE_UDP_HEAD:
00748            udpstats.udps_opackets++;
00749            return;
00750
00751 #if !defined(USE_UDP_ONLY)
00752       case TYPE_TCP_HEAD:
00753            {
00754              const tcp_Header *tcp = (const tcp_Header*) ps->data;
00755
00756              flags = tcp->flags & tcp_FlagMASK;
00757              tcpstats.tcps_sndtotal++;
00758
00759              if (flags & (tcp_FlagSYN|tcp_FlagFIN|tcp_FlagRST))
00760                 tcpstats.tcps_sndctrl++;
00761              else if (flags & tcp_FlagACK) /* ACK only flag */
00762                 tcpstats.tcps_sndacks++;
00763              if (flags & tcp_FlagURG)
00764                 tcpstats.tcps_sndurg++;
00765              if (flags & (tcp_FlagFIN|tcp_FlagRST))
00766                 tcpstats.tcps_closed++;
00767            }
00768            break;
00769
00770       case TYPE_TCP_DATA:
00771            if (ps->len > 0)
00772            {
00773              tcpstats.tcps_sndpack++;
00774              tcpstats.tcps_sndbyte += ps->len;
00775            }
00776            return;   /* nothing behind this */
00777 #endif
00778
00779       default: ;    /* squelch gcc warning */
00780     }
00781   }
00782
00783  if (!got_ip)
00784     macstats.non_ip_sent++;
00785 }
00786 #endif  /* USE_STATISTICS */
00787
Generated on Wed Jan 25 15:42:38 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/PCSTAT.H Source File

SRC/PCSTAT.H

Go to the documentation of this file.
00001
00003 #ifndef _w32_PCSTAT_H
00004 #define _w32_PCSTAT_H
00005
00006 /*
00007  * tcc <= 2.01 lacks proper bit-field support.
00008  * Don't define USE_BSD_API/USE_STATISTICS with this compiler.
00009  */
00010
00011 #ifndef ICMP_MAXTYPE
00012 #define ICMP_MAXTYPE 18
00013 #endif
00014
00015 #if !defined(OLD_TURBOC)
00016   #include <sys/socket.h>
00017   #include <net/if.h>
00018   #include <net/if_dl.h>
00019   #include <net/if_ether.h>
00020   #include <net/route.h>
00021   #include <netinet/in.h>
00022   #include <netinet/in_systm.h>
00023   #include <netinet/in_var.h>
00024   #include <netinet/ip.h>
00025   #include <netinet/ip_var.h>
00026   #include <netinet/in_pcb.h>
00027   #include <netinet/tcp.h>
00028   #include <netinet/tcp_time.h>
00029   #include <netinet/tcpip.h>
00030   #include <netinet/udp.h>
00031   #include <netinet/udp_var.h>
00032   #include <netinet/tcp_var.h>
00033   #include <netinet/icmp_var.h>
00034   #include <netinet/igmp_var.h>
00035   #include <netinet/icmp6.h>
00036   #include <netinet6/ip6_var.h>
00037 #endif
00038
00039
00044 struct macstat {
00045        DWORD  non_ip_recv;            /* # of non-IP packets received */
00046        DWORD  non_ip_sent;            /*                     sent */
00047        DWORD  num_tx_err;             /* # of transmission errors */
00048        DWORD  num_tx_retry;           /* # of transmission retries */
00049        DWORD  num_tx_timeout;         /* # of async transmission timeouts */
00050        DWORD  num_unk_type;           /* # of unhandled types */
00051        DWORD  num_llc_frames;         /* # of LLC frames received */
00052        DWORD  num_wrong_handle;       /* # upcalls with wrong handle */
00053        DWORD  num_bad_sync;           /* # upcalls with different lengths */
00054        DWORD  num_too_large;          /* # upcalls with > ETH_MAX pkts */
00055        DWORD  num_too_small;          /* # upcalls with < ETH_MIN pkts */
00056        DWORD  num_mac_loop;           /* # of pkts looped by NDIS */
00057        DWORD  num_ip_recurse;         /* # of IP-pkts blocked due to recursion */
00058
00060        struct {
00061          DWORD request_recv;          /* # of ARP requests received */
00062          DWORD request_sent;          /*                   sent */
00063          DWORD reply_recv;            /* # of ARP replies received */
00064          DWORD reply_sent;            /*                  sent */
00065        } arp;
00066
00068        struct {
00069          DWORD request_recv;          /* # of RARP requests received */
00070          DWORD request_sent;          /*                    sent */
00071          DWORD reply_recv;            /* # of RARP replies received */
00072          DWORD reply_sent;            /*                   sent */
00073        } rarp;
00074      };
00075
00080 struct pppoestat {
00081        DWORD  num_disc_sent;
00082        DWORD  num_disc_recv;
00083        DWORD  num_sess_sent;
00084        DWORD  num_sess_recv;
00085      };
00086
00087 /*
00088  * IP statistics for all in/out messages, <netinet/ip_var.h>
00089  *
00090  * ips_total;           - total packets received
00091  * ips_badsum;          - checksum bad
00092  * ips_tooshort;        - packet too short
00093  * ips_toosmall;        - not enough data
00094  * ips_badhlen;         - ip header length < data size
00095  * ips_badlen;          - ip length < ip header length
00096  * ips_fragments;       - fragments received
00097  * ips_fragdropped;     - frags dropped (dups, out of space)
00098  * ips_fragtimeout;     - fragments timed out
00099  * ips_forward;         - packets forwarded
00100  * ips_cantforward;     - packets rcvd for unreachable dest
00101  * ips_redirectsent;    - packets forwarded on same net
00102  * ips_noproto;         - unknown or unsupported protocol
00103  * ips_delivered;       - datagrams delivered to upper level
00104  * ips_localout;        - total ip packets generated here
00105  * ips_odropped;        - lost out packets due to nobufs, etc.
00106  * ips_idropped;        - lost in packets due to nobufs, etc.  !! added
00107  * ips_reassembled;     - total packets reassembled ok
00108  * ips_fragmented;      - datagrams successfully fragmented
00109  * ips_ofragments;      - output fragments created
00110  * ips_cantfrag;        - don't fragment flag was set, etc.
00111  * ips_badoptions;      - error in option processing
00112  * ips_noroute;         - packets discarded due to no route
00113  * ips_badvers;         - ip version != 4
00114  * ips_rawout;          - total raw ip packets generated
00115  * ips_toolong;         - ip length > max ip packet size
00116  *
00117  *
00118  * UDP statistics, <netinet/udp_var.h>
00119  *
00120  * udps_ipackets        - total input packets
00121  * udps_hdrops          - packet shorter than header
00122  * udps_badsum          - checksum error
00123  * udps_badlen          - data length larger than packet
00124  * udps_noport          - no socket on port
00125  * udps_noportbcast     - as above, arrived as broadcast
00126  * udps_fullsock        - not delivered, input socket full
00127  * udpps_pcbcachemiss   - input packets missing pcb cache
00128  * udpps_pcbhashmiss    - input packets not for hashed pcb
00129  * udps_opackets        - total output packets
00130  *
00131  *
00132  * TCP statistics for all connections, <netinet/tcp_var.h>
00133  *
00134  * tcps_connattempt     - connections initiated         (output)
00135  * tcps_accepts         - connections accepted          (input)
00136  * tcps_connects        - connections established       (input)
00137  * tcps_drops           - connections dropped           (output)
00138  * tcps_conndrops       - embryonic connections dropped (output)
00139  * tcps_closed          - conn. closed (includes drops)
00140  * tcps_segstimed       - segs where we tried to get rtt
00141  * tcps_rttupdated      - times we succeeded
00142  * tcps_delack          - delayed acks sent
00143  * tcps_timeoutdrop     - conn. dropped in rxmt timeout
00144  * tcps_rexmttimeo      - retransmit timeouts
00145  * tcps_persisttimeo    - persist timeouts
00146  * tcps_keeptimeo       - keepalive timeouts
00147  * tcps_keepprobe       - keepalive probes sent
00148  * tcps_keepdrops       - connections dropped in keepalive
00149  *
00150  * tcps_sndtotal        - total packets sent
00151  * tcps_sndpack         - data packets sent
00152  * tcps_sndbyte         - data bytes sent
00153  * tcps_sndrexmitpack   - data packets retransmitted
00154  * tcps_sndrexmitbyte   - data bytes retransmitted
00155  * tcps_sndacks         - ack-only packets sent
00156  * tcps_sndprobe        - window probes sent
00157  * tcps_sndurg          - packets sent with URG only
00158  * tcps_sndwinup        - window update  -only packets sent
00159  * tcps_sndctrl         - control (SYN|FIN|RST) packets sent
00160  *
00161  * tcps_rcvtotal        - total packets received
00162  * tcps_rcvpack         - packets received in sequence
00163  * tcps_rcvbyte         - bytes received in sequence
00164  * tcps_rcvbadsum       - packets received with ccksum errs
00165  * tcps_rcvbadoff       - packets received with bad offset
00166  * tcps_rcvshort        - packets received too short
00167  * tcps_rcvduppack      - duplicate-only packets received
00168  * tcps_rcvdupbyte      - duplicate-only bytes received
00169  * tcps_rcvpartduppack  - packets with some duplicate data
00170  * tcps_rcvpartdupbyte  - dup. bytes in part-dup. packets
00171  * tcps_rcvoopack       - out-of-order packets received
00172  * tcps_rcvoobyte       - out-of-order bytes received
00173  * tcps_rcvpackafterwin - packets with data after window
00174  * tcps_rcvbyteafterwin - bytes rcvd after window
00175  * tcps_rcvafterclose   - packets rcvd after "close"
00176  * tcps_rcvwinprobe     - rcvd window probe packets
00177  * tcps_rcvdupack       - rcvd duplicate acks
00178  * tcps_rcvacktoomuch   - rcvd acks for unsent data
00179  * tcps_rcvackpack      - rcvd ack packets
00180  * tcps_rcvackbyte      - bytes acked by rcvd acks
00181  * tcps_rcvwinupd       - rcvd window update packets
00182  * tcps_pawsdrop        - segments dropped due to PAWS (protected against wrapped segments)
00183  * tcps_predack         - times hdr predict ok for acks
00184  * tcps_preddat         - times hdr predict ok for data pkts
00185  * tcps_pcbcachemiss    - times missed cache for input segment
00186  * tcps_cachedrtt       - times cached RTT in route updated
00187  * tcps_cachedrttvar    - times cached rttvar updated
00188  * tcps_cachedssthresh  - times cached ssthresh updated
00189  * tcps_usedrtt         - times RTT initialized from route
00190  * tcps_usedrttvar      - times RTTVAR initialized from rt
00191  * tcps_usedssthresh    - times ssthresh initialized from rt
00192  * tcps_persistdrop     - timeout in persist state
00193  * tcps_badsyn          - bogus SYN, e.g. premature ACK
00194  * tcps_mturesent       - resends due to MTU discovery
00195  * tcps_listendrop      - listen queue overflows
00196  * #ifdef TCP_FACK
00197  * tcps_fack_recovery;     - recovery episodes
00198  * tcps_fack_sndpack;      - data packets sent
00199  * tcps_fack_sndbyte;      - data bytes sent
00200  * tcps_fack_sndrexmitpack - data packets retransmitted
00201  * tcps_fack_sndrexmitbyte - data bytes retransmitted
00202  * #endif
00203  *
00204  *
00205  * ICMP statistics, in <netinet/icmp_var.h>
00206  *
00207  * icps_error           - # of calls to icmp_error
00208  * icps_oldshort        - no error 'cuz old ip too short
00209  * icps_oldicmp         - no error 'cuz old was icmp
00210  * icps_outhist[18+1]   - output counters for ICMP_xx
00211  * icps_badcode         - icmp_code out of range
00212  * icps_tooshort        - packet < ICMP_MINLEN
00213  * icps_checksum        - bad checksum
00214  * icps_badlen          - calculated bound mismatch
00215  * icps_reflect         - number of responses
00216  * icps_inhist[18+1]    - input counters for ICMP_xx
00217  *
00218  *
00219  * IGMP statistics, <netinet/igmp_var.h>
00220  *
00221  * igps_rcv_total       - total IGMP messages received
00222  * igps_rcv_tooshort    - received with too few bytes
00223  * igps_rcv_badsum      - received with bad checksum
00224  * igps_rcv_queries     - received membership queries
00225  * igps_rcv_badqueries  - received invalid queries
00226  * igps_rcv_reports     - received membership reports
00227  * igps_rcv_badreports  - received invalid reports
00228  * igps_rcv_ourreports  - received reports for our groups
00229  * igps_snd_reports     - sent membership reports
00230  */
00231
00232 extern int sock_stats (sock_type *sock, DWORD *days, WORD *inactive,
00233                        WORD *cwindow, DWORD *avg, DWORD *sd);
00234
00235 extern void print_mac_stats  (void);
00236 extern void print_arp_stats  (void);
00237 extern void print_pkt_stats  (void);
00238 extern void print_vjc_stats  (void);
00239 extern void print_pppoe_stats(void);
00240 extern void print_ip4_stats  (void);
00241 extern void print_ip6_stats  (void);
00242 extern void print_icmp_stats (void);
00243 extern void print_icmp6_stats(void);
00244 extern void print_igmp_stats (void);
00245 extern void print_udp_stats  (void);
00246 extern void print_tcp_stats  (void);
00247 extern void print_all_stats  (void);
00248 extern void reset_stats      (void);
00249
00250
00251 #if defined(USE_STATISTICS)
00252   #define macstats     NAMESPACE (macstats)
00253   #define ip4stats     NAMESPACE (ip4stats)
00254   #define ip6stats     NAMESPACE (ip6stats)
00255   #define udpstats     NAMESPACE (udpstats)
00256   #define tcpstats     NAMESPACE (tcpstats)
00257   #define icmpstats    NAMESPACE (icmpstats)
00258   #define icmp6stats   NAMESPACE (icmp6stats)
00259   #define igmpstats    NAMESPACE (igmpstats)
00260   #define pppoestats   NAMESPACE (pppoestats)
00261
00262   #define STAT(x) x
00263
00264   extern struct macstat   macstats;
00265   extern struct ipstat    ip4stats;
00266   extern struct ip6stat   ip6stats;
00267   extern struct udpstat   udpstats;
00268   extern struct tcpstat   tcpstats;
00269   extern struct icmpstat  icmpstats;
00270   extern struct icmp6stat icmp6stats;
00271   extern struct igmpstat  igmpstats;
00272   extern struct pppoestat pppoestats;
00273
00274   extern void update_in_stat  (void);
00275   extern void update_out_stat (void);
00276
00277 #else
00278   #define STAT(x)  ((void)0)
00279 #endif
00280
00281 #endif /* !_w32_PCSTAT_H */
00282
Generated on Wed Jan 25 15:42:38 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/PCTCP.C Source File

SRC/PCTCP.C

Go to the documentation of this file.
00001
00012 #include <stdio.h>
00013 #include <stdarg.h>
00014 #include <stdlib.h>
00015 #include <string.h>
00016 #include <limits.h>
00017
00018 #include "copyrigh.h"
00019 #include "wattcp.h"
00020 #include "chksum.h"
00021 #include "strings.h"
00022 #include "language.h"
00023 #include "udp_dom.h"
00024 #include "bsdname.h"
00025 #include "pcconfig.h"
00026 #include "pcqueue.h"
00027 #include "pcsed.h"
00028 #include "pcstat.h"
00029 #include "pcpkt.h"
00030 #include "pcicmp.h"
00031 #include "pcicmp6.h"
00032 #include "pcmulti.h"
00033 #include "pcdbug.h"
00034 #include "pcdhcp.h"
00035 #include "pcarp.h"
00036 #include "pcbuf.h"
00037 #include "netaddr.h"
00038 #include "ip4_frag.h"
00039 #include "ip4_in.h"
00040 #include "ip4_out.h"
00041 #include "misc.h"
00042 #include "timer.h"
00043 #include "rs232.h"
00044 #include "split.h"
00045 #include "pppoe.h"
00046 #include "pctcp.h"
00047
00048 #if defined(USE_BSD_API) || defined(USE_IPV6)
00049 #include "socket.h"
00050 #endif
00051
00052 #if defined(USE_TCP_MD5)
00053 #include "tcp_md5.h"
00054 #endif
00055
00056 #if !defined(USE_FORTIFY)
00057 #undef free
00058 #endif
00059
00060 #ifndef __inline
00061 #define __inline
00062 #endif
00063
00066 char     hostname [MAX_HOSTLEN+1] = "random-pc";
00067
00068 unsigned _mss          = ETH_MAX_DATA - TCP_OVERHEAD;
00069 unsigned _mtu          = ETH_MAX_DATA;
00070 BOOL     mtu_discover  = 0;
00071 BOOL     mtu_blackhole = 0;
00072 BOOL     block_tcp     = 0;
00073 BOOL     block_udp     = 0;
00074 BOOL     block_icmp    = 0;
00075 BOOL     block_ip      = 0;
00077 DWORD    my_ip_addr    = 0L;
00078 DWORD    sin_mask      = 0xFFFFFF00L;
00080 _udp_Socket *_udp_allsocs = NULL;
00082 #include <sys/packon.h>
00083
00084 struct ip4_packet {
00085        in_Header  in;
00086        udp_Header udp;
00087     /* BYTE       data[]; */
00088      };
00089
00090 struct ip6_packet {
00091        in6_Header in;
00092        udp_Header udp;
00093     /* BYTE       data[]; */
00094      };
00095
00096 struct tcp_pkt {
00097        in_Header  in;
00098        tcp_Header tcp;
00099      };
00100
00101 struct tcp6_pkt {
00102        in6_Header in;
00103        tcp_Header tcp;
00104      };
00105
00106 #include <sys/packoff.h>
00107
00108 #if defined(USE_BSD_API)
00109
00113   void *(MS_CDECL *_bsd_socket_hook) (enum BSD_SOCKET_OPS op, ...) = NULL;
00114 #endif
00115
00116 #if !defined(USE_UDP_ONLY)
00117
00120   unsigned tcp_OPEN_TO     = DEF_OPEN_TO;
00121   unsigned tcp_CLOSE_TO    = DEF_CLOSE_TO;
00122   unsigned tcp_RTO_ADD     = DEF_RTO_ADD;
00123   unsigned tcp_RTO_BASE    = DEF_RTO_BASE;
00124   unsigned tcp_RTO_SCALE   = DEF_RTO_SCALE;
00125   unsigned tcp_RST_TIME    = DEF_RST_TIME;
00126   unsigned tcp_RETRAN_TIME = DEF_RETRAN_TIME;
00127   unsigned tcp_MAX_VJSA    = DEF_MAX_VJSA;
00128   unsigned tcp_MAX_VJSD    = DEF_MAX_VJSD;
00132   BOOL tcp_opt_ts     = FALSE;
00133   BOOL tcp_opt_wscale = FALSE;
00134   BOOL tcp_opt_sack   = FALSE;
00135
00138   BOOL     tcp_nagle      = TRUE;
00139   unsigned tcp_keep_idle  = 2*60;
00140   unsigned tcp_keep_intvl = 30;
00141   unsigned tcp_max_idle   = 60;
00142   DWORD    tcp_recv_win   = DEF_RECV_WIN;
00144   _tcp_Socket *_tcp_allsocs = NULL;
00146   extern int _tcp_fsm (_tcp_Socket **s, const in_Header *ip);
00147
00148   static _tcp_Socket *tcp_findseq (const in_Header *ip, const tcp_Header *tcp);
00149   static void         tcp_sockreset (_tcp_Socket *s, BOOL proxy);
00150
00151   static void tcp_no_arp  (_tcp_Socket *s);
00152   static void tcp_rtt_win (_tcp_Socket *s);
00153   static void tcp_upd_win (_tcp_Socket *s, unsigned line);
00154   static BOOL tcp_checksum(const in_Header *ip, const tcp_Header *tcp, int len);
00155 #endif
00156
00157 static DWORD daemon_timer = 0UL;
00159 static void run_daemons (void);
00160 static void udp_close (const _udp_Socket *s);
00161
00162 static void (*system_yield)(void) = NULL;
00163
00167 int udp_listen (_udp_Socket *s, WORD lport, DWORD ip,
00168                 WORD port, ProtoHandler handler)
00169 {
00170   SIO_TRACE (("udp_listen"));
00171
00172   udp_close (s);
00173   WATT_LARGE_CHECK (s, sizeof(*s));
00174   memset (s, 0, sizeof(*s));
00175
00176   if (!_eth_is_init) /* GvB 2002-09, Lets us survive without a working eth */
00177   {
00178     SOCK_ERRNO (ENETDOWN);
00179     s->err_msg = _LANG (_eth_not_init);
00180     return (0);
00181   }
00182
00183   s->rx_data      = &s->rx_buf[0];
00184   s->max_rx_data  = sizeof(s->rx_buf) - 1;
00185   s->ip_type      = UDP_PROTO;
00186   s->sockmode     = SOCK_MODE_BINARY | SOCK_MODE_UDPCHK;
00187   s->myport       = find_free_port (lport, 0); /* grab a local port */
00188   s->hisport      = port;
00189   s->hisaddr      = ip;
00190   s->ttl          = _default_ttl;
00191   s->protoHandler = handler;
00192   s->usr_yield    = system_yield;
00193   s->safetysig    = SAFETY_UDP;
00194   s->next         = _udp_allsocs;            /* insert into chain */
00195   _udp_allsocs    = s;
00196   return (1);
00197 }
00198
00202 int udp_open (_udp_Socket *s, WORD lport, DWORD ip,
00203               WORD port, ProtoHandler handler)
00204 {
00205   BOOL bcast;
00206
00207   SIO_TRACE (("udp_open"));
00208
00209   udp_close (s);
00210   WATT_LARGE_CHECK (s, sizeof(*s));
00211   memset (s, 0, sizeof(*s));
00212
00213   if (!_eth_is_init) /* GvB 2002-09, Lets us survive without a working eth */
00214   {
00215     SOCK_ERRNO (ENETDOWN);
00216     s->err_msg = _LANG (_eth_not_init);
00217     return (0);
00218   }
00219
00220   if (ip && _ip4_is_multihome_addr(ip))  /* 0.0.0.0 is legal */
00221   {
00222     SOCK_ERRNO (EINVAL);
00223     strcpy (s->err_buf, _LANG("Illegal destination "));
00224     strcat (s->err_buf, _inet_ntoa(NULL,ip));
00225     s->err_msg = s->err_buf;
00226     return (0);
00227   }
00228
00229   bcast = ((ip == IP_BCAST_ADDR) || (~ip & ~sin_mask) == 0);
00230
00231   if (bcast || !ip)      /* check for broadcast */
00232   {
00233     memset (s->his_ethaddr, 0xFF, sizeof(eth_address));
00234     if (!ip)
00235        ip = IP_BCAST_ADDR; /* s->hisaddr = 255.255.255.255 (this network) */
00236   }
00237 #if defined(USE_MULTICAST)
00238   else if (_ip4_is_multicast(ip))   /* check for multicast */
00239   {
00240     multi_to_eth (ip, &s->his_ethaddr);
00241     s->ttl = 1;     /* so we don't send worldwide as default */
00242   }
00243 #endif
00244   else if (!_arp_resolve(ip,&s->his_ethaddr))
00245   {
00246     SOCK_ERRNO (EHOSTUNREACH);
00247     strcpy (s->err_buf, _LANG("ARP failed "));
00248     strcat (s->err_buf, _inet_ntoa(NULL,ip));
00249     s->err_msg = s->err_buf;
00250     STAT (ip4stats.ips_noroute++);
00251     return (0);
00252   }
00253
00254   s->rx_data      = &s->rx_buf[0];
00255   s->max_rx_data  = sizeof(s->rx_buf) - 1;
00256   s->ip_type      = UDP_PROTO;
00257   s->sockmode     = SOCK_MODE_BINARY | SOCK_MODE_UDPCHK;
00258   s->myport       = find_free_port (lport, 0);
00259   s->myaddr       = my_ip_addr;
00260   s->ttl          = _default_ttl;
00261   s->hisaddr      = ip;
00262   s->hisport      = port;
00263   s->protoHandler = handler;
00264   s->usr_yield    = system_yield;
00265   s->safetysig    = SAFETY_UDP;
00266   s->next         = _udp_allsocs;
00267   _udp_allsocs    = s;
00268   return (1);
00269 }
00270
00275 static void udp_close (const _udp_Socket *udp)
00276 {
00277   _udp_Socket *s, *prev;
00278
00279   SIO_TRACE (("udp_close"));
00280
00281   for (s = prev = _udp_allsocs; s; prev = s, s = s->next)
00282   {
00283     if (udp != s)
00284        continue;
00285
00286     reuse_localport (s->myport);
00287
00288     if (s == _udp_allsocs)
00289          _udp_allsocs = s->next;
00290     else prev->next   = s->next;
00291     SET_ERR_MSG (s, _LANG("UDP Close called"));
00292     break;
00293   }
00294 }
00295
00299 void udp_SetTTL (_udp_Socket *s, BYTE ttl)
00300 {
00301   s->ttl = ttl;
00302 }
00303
00304
00305 #if !defined(USE_UDP_ONLY)
00306
00317 int tcp_open (_tcp_Socket *s, WORD lport, DWORD ip,
00318               WORD rport, ProtoHandler handler)
00319 {
00320   SIO_TRACE (("tcp_open"));
00321
00322   WATT_LARGE_CHECK (s, sizeof(*s));
00323   _tcp_unthread (s, FALSE);    /* just in case not totally closed */
00324
00325   memset (s, 0, sizeof(*s));
00326   s->state = tcp_StateCLOSED; /* otherwise is tcp_StateLISTEN on failure */
00327
00328   STAT (tcpstats.tcps_connattempt++);
00329
00330   if (!_eth_is_init) /* GvB 2002-09, Lets us survive without a working eth */
00331   {
00332     SOCK_ERRNO (ENETDOWN);
00333     s->err_msg = _LANG (_eth_not_init);
00334     return (0);
00335   }
00336
00337   if (!ip || _ip4_is_multihome_addr(ip) || _ip4_is_multicast(ip))
00338   {
00339     SOCK_ERRNO (EINVAL);
00340     strcpy (s->err_buf, _LANG("Illegal destination "));
00341     strcat (s->err_buf, _inet_ntoa(NULL,ip));
00342     s->err_msg = s->err_buf;
00343     return (0);
00344   }
00345
00346   if (!arp_start_lookup(ip)) /* GvB 2002-09, now non-blocking */
00347   {
00348     SOCK_ERRNO (EHOSTUNREACH);
00349     strcpy (s->err_buf, _LANG("Failed to start ARP lookup "));
00350     strcat (s->err_buf, _inet_ntoa(NULL,ip));
00351     s->err_msg = s->err_buf;
00352     return (0);
00353   }
00354
00355   s->rx_data      = &s->rx_buf[0];
00356   s->max_rx_data  = sizeof(s->rx_buf) - 1;
00357   s->tx_data      = &s->tx_buf[0];
00358   s->max_tx_data  = sizeof(s->tx_buf) - 1;
00359   s->ip_type      = TCP_PROTO;
00360   s->max_seg      = _mss;
00361   s->state        = tcp_StateRESOLVE;
00362
00363   s->cwindow      = 1;
00364   s->wwindow      = 0;                        /* slow start VJ algorithm */
00365   s->vj_sa        = INIT_VJSA;
00366   s->rto          = tcp_OPEN_TO;              /* added 14-Dec 1999, GV */
00367   s->myaddr       = my_ip_addr;
00368   s->myport       = find_free_port (lport,1); /* get a nonzero port val */
00369   s->locflags     = LF_LINGER;                /* close via TIMEWT state */
00370   s->ttl          = _default_ttl;
00371   s->hisaddr      = ip;
00372   s->hisport      = rport;
00373   s->send_next    = INIT_SEQ();
00374   s->flags        = tcp_FlagSYN;
00375   s->unhappy      = TRUE;
00376   s->protoHandler = handler;
00377   s->usr_yield    = system_yield;
00378
00379   s->safetysig    = SAFETY_TCP;             /* marker signatures */
00380   s->safetytcp    = SAFETY_TCP;
00381   s->next         = _tcp_allsocs;           /* insert into chain */
00382   _tcp_allsocs    = s;
00383
00386   if (tcp_nagle)
00387      s->sockmode = SOCK_MODE_NAGLE;
00388   s->sockmode |= SOCK_MODE_BINARY;
00389
00390   return (1);
00391 }
00392
00398 int tcp_listen (_tcp_Socket *s, WORD lport, DWORD ip,
00399                 WORD port, ProtoHandler handler, WORD timeout)
00400 {
00401   SIO_TRACE (("tcp_listen"));
00402
00403   WATT_LARGE_CHECK (s, sizeof(*s));
00404   _tcp_unthread (s, FALSE);     /* just in case not totally closed */
00405   memset (s, 0, sizeof(*s));
00406
00407   s->state = tcp_StateCLOSED;   /* otherwise is tcp_StateLISTEN if success */
00408
00409   if (!_eth_is_init) /* GvB 2002-09, Lets us survive without a working eth */
00410   {
00411     SOCK_ERRNO (ENETDOWN);
00412     s->err_msg = _LANG (_eth_not_init);
00413     return (0);
00414   }
00415
00416   if (_ip4_is_multicast(ip))     /* 0.0.0.0 is legal */
00417   {
00418     SOCK_ERRNO (EINVAL);
00419     strcpy (s->err_buf, _LANG("Illegal destination "));
00420     strcat (s->err_buf, _inet_ntoa(NULL,ip));
00421     s->err_msg = s->err_buf;
00422     return (0);
00423   }
00424
00425   s->rx_data      = &s->rx_buf[0];
00426   s->max_rx_data  = sizeof(s->rx_buf) - 1;
00427   s->tx_data      = &s->tx_buf[0];
00428   s->max_tx_data  = sizeof(s->tx_buf) - 1;
00429   s->ip_type      = TCP_PROTO;
00430   s->max_seg      = _mss;
00431   s->cwindow      = 1;
00432   s->wwindow      = 0;               /* slow start VJ algorithm */
00433   s->vj_sa        = INIT_VJSA;
00434   s->state        = tcp_StateLISTEN;
00435   s->locflags     = LF_LINGER | LF_IS_SERVER;
00436   s->myport       = find_free_port (lport, 0);
00437   s->hisport      = port;
00438   s->hisaddr      = ip;
00439   s->send_next    = INIT_SEQ();
00440   s->unhappy      = FALSE;
00441   s->ttl          = _default_ttl;
00442   s->protoHandler = handler;
00443   s->usr_yield    = system_yield;
00444   s->safetysig    = SAFETY_TCP;     /* marker signatures */
00445   s->safetytcp    = SAFETY_TCP;
00446   s->next         = _tcp_allsocs;   /* insert into chain */
00447   _tcp_allsocs    = s;
00448
00449   if (tcp_nagle)
00450      s->sockmode = SOCK_MODE_NAGLE;
00451   s->sockmode |= SOCK_MODE_BINARY;
00452
00453   if (timeout != 0)
00454      s->timeout = set_timeout (1000 * timeout);
00455   return (1);
00456 }
00457
00464 void _tcp_close (_tcp_Socket *s)
00465 {
00466   SIO_TRACE (("_tcp_close"));
00467
00468   if (s->ip_type != TCP_PROTO)
00469   {
00470     SIO_TRACE (("_tcp_close~0"));
00471     return;
00472   }
00473
00474   if (s->state == tcp_StateESTAB ||
00475       s->state == tcp_StateESTCL ||
00476       s->state == tcp_StateSYNREC)
00477   {
00478     if (s->tx_datalen)      /* must first flush all Tx data */
00479     {
00480       s->flags |= (tcp_FlagPUSH | tcp_FlagACK);
00481       if (s->state < tcp_StateESTCL)
00482       {
00483         s->state = tcp_StateESTCL;
00484         TCP_SENDSOON (s);
00485       }
00486     }
00487     else  /* really closing */
00488     {
00489       SET_ERR_MSG (s, _LANG("Connection closed normally"));
00490       s->flags    = (tcp_FlagACK | tcp_FlagFIN);
00491       s->state    = tcp_StateFINWT1;
00492       s->timeout  = set_timeout (tcp_TIMEOUT);
00493       s->rtt_time = 0UL;   /* stop RTT timer */
00494       TCP_SEND (s);
00495     }
00496     s->unhappy = TRUE;
00497   }
00498   else if (s->state == tcp_StateCLOSWT)
00499   {
00500    /* need to ACK the FIN and get on with it
00501     */
00502     s->timeout = set_timeout (tcp_LASTACK_TIME); /* Added AGW 6 Jan 2001 */
00503     s->state   = tcp_StateLASTACK;
00504     s->flags  |= tcp_FlagFIN;
00505     TCP_SEND (s);
00506     s->unhappy = TRUE;
00507   }
00508   else if (s->state == tcp_StateRESOLVE ||  /* unlink failed connection */
00509            s->state == tcp_StateSYNSENT)
00510   {
00511     s->state = tcp_StateCLOSED;
00512     maybe_reuse_localport (s);
00513     _tcp_unthread (s, FALSE);
00514   }
00515   SIO_TRACE (("_tcp_close~"));
00516 }
00517
00521 _tcp_Socket *_tcp_abort (_tcp_Socket *s, const char *file, unsigned line)
00522 {
00523   SIO_TRACE (("_tcp_abort"));
00524
00525   SET_ERR_MSG (s, _LANG("TCP Abort"));
00526   TCP_TRACE_MSG (("_tcp_abort(%08lX) called from %s (%u). State %s\n",
00527                   (DWORD)s, file, line, tcpStateName(s->state)));
00528
00529   if (s->state >= tcp_StateSYNSENT &&
00530       s->state <= tcp_StateLASTACK)
00531   {
00532     s->flags   = (tcp_FlagRST | tcp_FlagACK);
00533     s->unhappy = TRUE;
00534     if (s->state <= tcp_StateSYNREC)
00535     {
00536       s->rtt_time = 0UL;  /* Stop RTT timer */
00537       tcp_rtt_clr (s);    /* Clear cached RTT */
00538     }
00539     s->tx_datalen = 0;    /* RST should not carry any data */
00540     TCP_SEND (s);
00541   }
00542   s->unhappy    = FALSE;
00543   s->ip_type    = 0;
00544   s->tx_datalen = 0;      /* discard Tx buffer, but not Rx buffer */
00545
00546   maybe_reuse_localport (s);
00547   ARGSUSED (file);
00548   ARGSUSED (line);
00549   return _tcp_unthread (s, TRUE);
00550 }
00551
00563 int _tcp_sendsoon (_tcp_Socket *s, char *file, unsigned line)
00564 {
00565   DWORD timeout;
00566
00567   SIO_TRACE (("_tcp_sendsoon"));
00568
00569   if (s->ip_type != TCP_PROTO)
00570      return (0);
00571
00572   if (s->state >= tcp_StateCLOSWT)
00573        timeout = set_timeout (tcp_CLOSE_TO);
00574   else timeout = set_timeout (tcp_RTO_BASE);
00575
00576   if (s->rto <= tcp_RTO_BASE && s->recent == 0 &&
00577       cmp_timers(s->rtt_time,timeout) <= 0)
00578   {                         /* !! was == */
00579     int rc;
00580
00581     s->karn_count = 0;
00582     rc = _tcp_send (s, file, line);
00583     s->recent = 1;
00584     return (rc);
00585   }
00586
00587   if ((s->unhappy || s->tx_datalen > 0 || s->karn_count == 1) &&
00588       (s->rtt_time && cmp_timers(s->rtt_time,timeout) < 0))
00589      return (0);
00590
00591   if (s->state == tcp_StateSYNSENT)  /* relaxed in SYNSENT state */
00592        s->rtt_time = set_timeout (tcp_OPEN_TO);
00593   else s->rtt_time = set_timeout (s->rto / tcp_RTO_SCALE);
00594
00595   s->karn_count = 1;
00596
00597   return (0);
00598 }
00599
00604 _tcp_Socket *_tcp_unthread (_tcp_Socket *ds, BOOL free_tx)
00605 {
00606   _tcp_Socket *s, *prev;
00607   _tcp_Socket *next = NULL;
00608
00609   SIO_TRACE (("_tcp_unthread"));
00610
00611   if (ds == NULL)
00612      return (NULL);
00613
00614   for (s = prev = _tcp_allsocs; s; prev = s, s = s->next)
00615   {
00616     if (ds != s)
00617        continue;
00618
00619     if (s == _tcp_allsocs)
00620          _tcp_allsocs = s->next;
00621     else prev->next   = s->next;
00622     next = s->next;
00623     break;
00624   }
00625
00626   if (ds->rx_datalen == 0 || (ds->state > tcp_StateESTCL))
00627       ds->ip_type = 0;             /* fail further I/O */
00628   ds->state = tcp_StateCLOSED;     /* tcp_tick needs this */
00629
00630   if (free_tx && ds->tx_data && ds->tx_data != &ds->tx_buf[0] &&
00631       *(DWORD*)(ds->tx_data-4) == SAFETY_TCP)
00632   {
00633     free (ds->tx_data-4);
00634     ds->tx_data    = NULL;
00635     ds->tx_datalen = 0;    /* should already be 0 */
00636   }
00637   return (next);
00638 }
00639
00643 int tcp_established (const _tcp_Socket *s)
00644 {
00645   return (s->state >= tcp_StateESTAB);
00646 }
00647
00653 _tcp_Socket *_tcp_handler (const in_Header *ip, BOOL broadcast)
00654 {
00655 #if defined(USE_IPV6)
00656   const in6_Header *ip6 = (const in6_Header*)ip;
00657   ip6_address       ip6_src, ip6_dst;
00658 #endif
00659
00660   tcp_Header  *tcp;
00661   _tcp_Socket *s;
00662   int          len;
00663   BYTE         flags;
00664   DWORD        source = intel (ip->source);
00665   DWORD        destin = intel (ip->destination);
00666   DWORD        seq;
00667   WORD         dstPort, srcPort;
00668   BOOL         is_ip4 = (ip->ver == 4);
00669
00670   SIO_TRACE (("_tcp_handler"));
00671
00672   if (is_ip4)
00673   {
00674     if (broadcast || block_tcp ||
00675         !_ip4_is_local_addr(destin) || _ip4_is_multicast(source))
00676     {
00677       DEBUG_RX (NULL, ip);
00678       return (NULL);
00679     }
00680
00681     len   = in_GetHdrLen (ip);                /* len of IP header  */
00682     tcp   = (tcp_Header*) ((BYTE*)ip + len);  /* tcp frame pointer */
00683     len   = intel16 (ip->length) - len;       /* len of tcp+data */
00684     flags = tcp->flags & tcp_FlagMASK;        /* get TCP flags */
00685
00686     if (!tcp_checksum(ip,tcp,len))
00687     {
00688       DEBUG_RX (NULL, ip);
00689       return (NULL);
00690     }
00691   }
00692 #if defined(USE_IPV6)
00693   else
00694   {
00695     if (broadcast || block_tcp ||
00696         !IN6_IS_ADDR_LINKLOCAL(&ip6->destination) ||
00697          IN6_IS_ADDR_MULTICAST(&ip6->source))
00698     {
00699       DEBUG_RX (NULL, ip);
00700       return (NULL);
00701     }
00702
00703     len   = intel16 (ip6->len);
00704     tcp   = (tcp_Header*) pkt_get_type_in (TYPE_TCP_HEAD)->data;
00705     flags = tcp->flags & tcp_FlagMASK;
00706     memcpy (&ip6_dst, &ip6->destination, sizeof(ip6_dst));
00707     memcpy (&ip6_src, &ip6->source, sizeof(ip6_src));
00708     if (!_ip6_tcp_checksum(ip6,tcp,len))
00709     {
00710       DEBUG_RX (NULL, ip6);
00711       return (NULL);
00712     }
00713   }
00714 #else
00715   else
00716   {
00717     DEBUG_RX (NULL, ip);
00718     return (NULL);
00719   }
00720 #endif
00721
00722
00723   dstPort = intel16 (tcp->dstPort);
00724   srcPort = intel16 (tcp->srcPort);
00725
00726   /* demux to active sockets
00727    */
00728   for (s = _tcp_allsocs; s; s = s->next)
00729   {
00730     if (s->safetysig != SAFETY_TCP || s->safetytcp != SAFETY_TCP)
00731     {
00732       outsnl (_LANG("Error in _tcp_handler()"));
00733       DEBUG_RX (s, ip);
00734       return (NULL);
00735     }
00736
00737     if (s->is_ip6 && !is_ip4)
00738     {
00739 #if defined(USE_IPV6)
00740       if (s->hisport                                       &&
00741           !memcmp(&ip6_dst, &s->my6addr, sizeof(ip6_dst))  &&
00742           !memcmp(&ip6_src, &s->his6addr, sizeof(ip6_src)) &&
00743           dstPort == s->myport                             &&
00744           srcPort == s->hisport)
00745          break;
00746 #endif
00747     }
00748     else if (is_ip4)
00749     {
00750       if (s->hisport            &&   /* IP4: not a listening socket */
00751           destin  == s->myaddr  &&   /* addressed to my IP */
00752           source  == s->hisaddr &&   /* and from my peer address */
00753           dstPort == s->myport  &&   /* addressed to my local port */
00754           srcPort == s->hisport)     /* and from correct remote port */
00755         break;
00756     }
00757   }
00758
00759   if (!s && (flags & tcp_FlagSYN))
00760   {
00761     /* demux to passive (listening) sockets, must be a new session
00762      */
00763     for (s = _tcp_allsocs; s; s = s->next)
00764         if (s->hisport == 0 &&     /* =0, listening socket */
00765             s->myport  == dstPort) /* addressed to my local port */
00766         {
00767           if (s->is_ip6)
00768           {
00769 #if defined(USE_IPV6)
00770             if (!is_ip4)
00771             {
00772               s->hisaddr = source;
00773               s->hisport = srcPort;
00774               memcpy (&s->my6addr, ip6_dst, sizeof(s->my6addr));
00775             }
00776 #endif
00777           }
00778           else if (is_ip4)
00779           {
00780             s->hisaddr = source;     /* remember his IP-address */
00781             s->hisport = srcPort;    /*   and src-port */
00782             s->myaddr  = destin;     /* socket is now active (should be same) */
00783           }
00784           break;
00785         }
00786   }
00787
00788   DEBUG_RX (s, ip);
00789
00790   if (!s)
00791   {
00792     if (!(flags & tcp_FlagRST))                  /* don't answer RST */
00793     {
00794       TCP_SEND_RESET (NULL, ip, tcp);
00795     }
00796     else if ((flags & tcp_FlagACK) &&            /* got ACK,RS */
00797              (s = tcp_findseq(ip,tcp)) != NULL)  /* ACK = SEQ + 1 */
00798     {
00799       /* e.g. a firewall is sending RST for host on inside.
00800        */
00801       tcp_sockreset (s, TRUE);
00802     }
00803     return (NULL);
00804   }
00805
00806 #if defined(USE_TCP_MD5)
00807   if (is_ip4)
00808   {
00809     /* \todo: check in a src-host database and drop if not found
00810      *        and MD5 fails.
00811      */
00812     check_md5_signature (s, ip);
00813   }
00814 #endif
00815
00816   /* Restart idle-timer unless overridden by tcp_connect().
00817    */
00818   if (sock_inactive && !(s->locflags & LF_RCVTIMEO))
00819      s->inactive_to = set_timeout (1000 * sock_inactive);
00820
00821   /* Got a RST with correct SEQ (RCV.NXT - RCV.NXT-RCV.RWIN+1).
00822    * Reset socket (if socket is a server, go back to listening).
00823    */
00824   seq = intel (tcp->seqnum);
00825   if ((flags & tcp_FlagRST)      &&
00826       SEQ_GEQ(seq, s->recv_next) &&
00827       SEQ_LEQ(seq, s->recv_next+s->adv_win+1))
00828   {
00829     TCP_TRACE_MSG (("_tcp_handler(): got RST, SEQ %lu\n", seq));
00830     tcp_sockreset (s, FALSE);
00831     return (NULL);
00832   }
00833
00834   if (flags & tcp_FlagPUSH)       /* EE 2002.2.28 */
00835        s->locflags |= LF_GOT_PUSH;
00836   else s->locflags &= ~LF_GOT_PUSH;
00837
00838   tcp_rtt_win (s);        /* update retrans timer, windows etc. */
00839
00840   if (_tcp_fsm(&s,ip) &&  /* do input tcp state-machine */
00841       s->unhappy)         /* if "unhappy", retransmit soon */
00842      TCP_SENDSOON (s);
00843
00844 #if defined(USE_DEBUG)
00845   _sock_check_tcp_buffers (s);
00846 #endif
00847
00848   return (s);
00849 }
00850 #endif  /* !USE_UDP_ONLY */
00851
00852
00856 static BOOL udp_checksum (const in_Header *ip, const udp_Header *udp, int len)
00857 {
00858   tcp_PseudoHeader ph = { 0,0,0,0,0,0 };
00859
00860   ph.src      = ip->source;      /* already network order */
00861   ph.dst      = ip->destination;
00862   ph.protocol = UDP_PROTO;
00863   ph.length   = udp->length;
00864   ph.checksum = CHECKSUM (udp, len);
00865
00866   if (CHECKSUM(&ph,sizeof(ph)) != 0xFFFF)
00867   {
00868     TCP_CONSOLE_MSG (1, (_LANG("Bad udp checksum. ")));
00869     TCP_TRACE_MSG (("Bad udp checksum\n"));
00870     STAT (udpstats.udps_badsum++);
00871     return (FALSE);
00872   }
00873   return (TRUE);
00874 }
00875
00876
00881 static _udp_Socket *udp_demux (const in_Header *ip, BOOL ip_bcast,
00882                                DWORD destin, WORD srcPort, WORD dstPort,
00883                                BOOL *udp_err)
00884 {
00885   _udp_Socket *s;
00886   BOOL is_ip4 = (ip->ver == 4);
00887
00888 #if defined(USE_IPV6)
00889   const in6_Header *ip6 = (const in6_Header*)ip;
00890   ip6_address       ip6_src, ip6_dst;
00891
00892   if (!is_ip4)
00893   {
00894     memcpy (&ip6_dst, &ip6->destination, sizeof(ip6_dst));
00895     memcpy (&ip6_src, &ip6->source, sizeof(ip6_src));
00896   }
00897 #endif
00898
00899   *udp_err = FALSE;   /* assume socket-list is OK */
00900
00904   for (s = _udp_allsocs; s; s = s->next)
00905   {
00906     if (s->safetysig != SAFETY_UDP)
00907     {
00908       outsnl (_LANG("Error in udp_demux()"));
00909       s->safetysig = SAFETY_UDP;
00910       DEBUG_RX (s, ip);
00911       *udp_err = TRUE;
00912       return (NULL);
00913     }
00914
00915     if (!ip_bcast              &&
00916         (s->hisport != 0)      &&
00917         (dstPort == s->myport) &&
00918         (srcPort == s->hisport))
00919     {
00920       if (s->is_ip6)
00921       {
00922 #if defined(USE_IPV6)
00923         if (!is_ip4 &&
00924             IN6_ARE_ADDR_EQUAL(&ip6_src,&s->his6addr))  /* !!mask */
00925         {
00926           DEBUG_RX (s, ip);
00927           break;
00928         }
00929 #endif
00930       }
00931       else if (is_ip4 &&
00932                ((destin & sin_mask) == (s->myaddr & sin_mask)) &&
00933                (intel(ip->source)   == s->hisaddr))
00934       {
00935         DEBUG_RX (s, ip);
00936         break;
00937       }
00938     }
00939   }
00940
00941   if (!s)
00942   {
00943     /* demux to passive sockets
00944      */
00945     for (s = _udp_allsocs; s; s = s->next)
00946     {
00947       if (s->is_ip6)
00948       {
00949 #if defined(USE_IPV6)
00950         if (!is_ip4 && dstPort == s->myport &&
00951             IN6_IS_ADDR_UNSPECIFIED(&s->his6addr))
00952         {
00953           DEBUG_RX (s, ip);
00954
00955           memcpy (&s->his6addr, &ip6_src, sizeof(s->his6addr));
00956           s->hisport = srcPort;
00957           SET_PEER_MAC_ADDR (s, ip6);
00958           if (!ip_bcast)
00959              memcpy (&s->my6addr, &ip6_dst, sizeof(s->my6addr));
00960           break;
00961         }
00962 #endif
00963       }
00964       else if (is_ip4 && (s->hisaddr == 0 || s->hisaddr == IP_BCAST_ADDR) &&
00965                dstPort == s->myport)
00966       {
00967         DEBUG_RX (s, ip);
00968
00969         if (s->hisaddr == 0)
00970         {
00971           s->hisaddr = intel (ip->source);  /* socket now active */
00972           s->hisport = srcPort;
00973           SET_PEER_MAC_ADDR (s, ip);
00974
00975           /* take on value of expected destination
00976            * unless it is broadcast
00977            */
00978           if (!ip_bcast)
00979              s->myaddr = destin;
00980         }
00981         break;
00982       }
00983     }
00984   }
00985
00986
00987 #if defined(USE_MULTICAST)
00988   if (is_ip4 && !s)
00989   {
00990     /* demux to multicast sockets
00991      */
00992     for (s = _udp_allsocs; s; s = s->next)
00993     {
00994       if (s->hisport != 0         &&
00995           s->hisaddr == destin    &&
00996           dstPort    == s->myport &&
00997           _ip4_is_multicast(destin))
00998       {
00999         DEBUG_RX (s, ip);
01000         break;
01001       }
01002     }
01003   }
01004 #endif
01005
01006   if (!s)
01007   {
01008     /* Demux to broadcast sockets.
01009      */
01010     for (s = _udp_allsocs; s; s = s->next)
01011     {
01012       if (s->is_ip6 && !is_ip4)
01013       {
01014 #if defined(USE_IPV6)
01015         if (dstPort == s->myport && IN6_IS_ADDR_UNSPECIFIED(&s->his6addr))
01016         {
01017           DEBUG_RX (s, ip);
01018           break;
01019         }
01020 #endif
01021       }
01022       else if (is_ip4)
01023       {
01024         if (s->hisaddr == IP_BCAST_ADDR && dstPort == s->myport)
01025         {
01026           DEBUG_RX (s, ip);
01027           break;
01028         }
01029       }
01030     }
01031   }
01032   return (s);
01033 }
01034
01035
01039 _udp_Socket *_udp_handler (const in_Header *ip, BOOL broadcast)
01040 {
01041 #if defined(USE_IPV6)
01042   const in6_Header *ip6 = (const in6_Header*)ip;
01043   ip6_address       ip6_src, ip6_dst;
01044 #endif
01045
01046   _udp_Socket *s;
01047   UINT         len = 0;
01048   WORD         dst_port, src_port;
01049   DWORD        destin = 0;
01050   BOOL         is_ip4 = (ip->ver == 4);
01051   BOOL         ip_bcast = 0;
01052   BOOL         udp_err;
01053
01054   const BYTE       *data;
01055   const udp_Header *udp = NULL;
01056
01057   SIO_TRACE (("_udp_handler"));
01058
01059   if (is_ip4)
01060   {
01061     destin   = intel (ip->destination);
01062     ip_bcast = broadcast ||             /* link-layer broadcast */
01063                _ip4_is_ip_brdcast(ip);  /* (directed) ip-broadcast */
01064   }
01065 #if defined(USE_IPV6)
01066   else
01067   {
01068     memcpy (&ip6_dst, &ip6->destination, sizeof(ip6_dst));
01069     memcpy (&ip6_src, &ip6->source, sizeof(ip6_src));
01070     ip_bcast = broadcast ||
01071                IN6_IS_ADDR_MULTICAST (&ip6->destination); /* !! */
01072   }
01073 #endif
01074
01075 #if !defined(USE_MULTICAST)
01076
01077   /* dst = ip number
01078    *     or 255.255.255.255
01079    *     or sin_mask.255.255
01080    * This is the only really gross hack in the multicasting stuff.
01081    * I'll fix it as soon as I can figure out what I want to do here.
01082    * -JRM 8/1/93
01083    */
01084   if (is_ip4 && !ip_bcast &&            /* not a IPv4 broadcast packet */
01085       my_ip_addr &&                     /* and I know my address */
01086       !_ip4_is_multihome_addr(destin))  /* and not my address */
01087   {
01088     DEBUG_RX (NULL, ip);
01089     STAT (udpstats.udps_noport++);
01090     return (NULL);
01091   }
01092 #endif
01093
01094   if (is_ip4)
01095   {
01096     len = in_GetHdrLen (ip);
01097     udp = (const udp_Header*) ((BYTE*)ip + len);   /* udp segment pointer */
01098     len = intel16 (udp->length);
01099   }
01100 #if defined(USE_IPV6)
01101   else
01102   {
01103     len = intel16 (ip6->len);
01104     udp = (const udp_Header*) pkt_get_type_in (TYPE_UDP_HEAD)->data;
01105     len = intel16 (udp->length);
01106   }
01107 #endif
01108
01109   if (len < sizeof(*udp))
01110   {
01111     DEBUG_RX (NULL, ip);
01112     STAT (udpstats.udps_hdrops++);
01113     return (NULL);
01114   }
01115
01116   src_port = intel16 (udp->srcPort);
01117   dst_port = intel16 (udp->dstPort);
01118
01119   if (dst_port == 0 || src_port == 0)
01120   {
01121     DEBUG_RX (NULL, ip);
01122     return (NULL);
01123   }
01124
01125   s = udp_demux (ip, ip_bcast, destin, src_port, dst_port, &udp_err);
01126
01127   if (!s)              /* no demultiplexer found anything */
01128   {
01129     if (udp_err)       /* error in udp_allsocs, don't send ICMP */
01130        return (NULL);
01131
01132     DEBUG_RX (NULL, ip);
01133
01134 #if defined(USE_IPV6)
01135     if (!is_ip4 && !IN6_IS_ADDR_UNSPECIFIED(&in6addr_my_ip) &&
01136         !memcmp(&in6addr_my_ip,&ip6_dst,sizeof(in6addr_my_ip)))
01137     {
01138       if (!ip_bcast && src_port != DOM_DST_PORT)
01139          icmp6_unreach (ip6, 3);
01140
01141       if (ip_bcast)
01142            STAT (udpstats.udps_noportbcast++);
01143       else STAT (udpstats.udps_noport++);
01144     }
01145     else
01146 #endif
01147     if (is_ip4 && my_ip_addr && _ip4_is_multihome_addr(destin))
01148     {
01149       if (!ip_bcast &&               /* not broadcast */
01150           src_port != DOM_DST_PORT)  /* not a late reply from a nameserver */
01151          icmp_send_unreach (ip, ICMP_UNREACH_PORT);
01152
01153       if (ip_bcast)
01154            STAT (udpstats.udps_noportbcast++);
01155       else STAT (udpstats.udps_noport++);
01156     }
01157     return (NULL);
01158   }
01159
01160   if (is_ip4)
01161   {
01162     if (udp->checksum && (s->sockmode & SOCK_MODE_UDPCHK) &&
01163         !udp_checksum (ip,udp,len))
01164        return (s);
01165   }
01166 #if defined(USE_IPV6)
01167   else
01168   {
01169     if (_ip6_udp_checksum(ip6,udp,len)) /* checksums are compulsary */
01170        return (s);
01171   }
01172 #endif
01173
01174
01175   /* Process user data. 0-byte probe is legal for s->protoHandler.
01176    */
01177   data = (const BYTE*) (udp+1);
01178   len -= sizeof(*udp);
01179
01180   if (s->protoHandler)
01181   {
01182     if (is_ip4)
01183     {
01184       tcp_PseudoHeader ph = { 0,0,0,0,0,0 };
01185       ph.src = ip->source;  /* only source needed by protoHandler */
01186       (*s->protoHandler) (s, data, len, &ph, udp);
01187     }
01188 #if defined(USE_IPV6)
01189     else
01190     {
01191       tcp_PseudoHeader6 ph6;
01192       memset (&ph6, 0, sizeof(ph6));
01193       memcpy (&ph6.src, &ip6->source, sizeof(ph6.src));
01194       (*s->protoHandler) (s, data, len, &ph6, udp);
01195     }
01196 #endif
01197   }
01198   else if (len > 0 /* && s->rx_datalen == 0 !! overwrite current data */)
01199   {
01200     if (len > s->max_rx_data)   /* truncate data :-( */
01201     {
01202       len = s->max_rx_data;
01203       STAT (udpstats.udps_fullsock++);
01204     }
01205     memcpy (s->rx_data, data, len);
01206     s->rx_datalen = len;
01207   }
01208   return (s);
01209 }
01210
01211
01212 #if !defined(USE_UDP_ONLY)
01213
01217 void tcp_Retransmitter (BOOL force)
01218 {
01219   _tcp_Socket *s, *next;
01220
01221   static DWORD timeout = 0UL;
01222
01223   SIO_TRACE (("tcp_Retransmitter"));
01224
01225   /* do this once per tcp_RETRAN_TIME
01226    */
01227   if (!force && timeout && !chk_timeout(timeout))
01228      return;
01229
01230   timeout = set_timeout (tcp_RETRAN_TIME);
01231
01232   for (s = _tcp_allsocs; s; s = next)
01233   {
01234     next = s->next;
01235
01236     /* Check on ARP resolve status, GvB 2002-09
01237      */
01238     if (s->state == tcp_StateRESOLVE)
01239     {
01240       if (arp_lookup (s->hisaddr, &s->his_ethaddr))   /* Success */
01241       {
01242         UINT rtt, MTU;
01243
01244         s->state   = tcp_StateSYNSENT;
01245         s->timeout = set_timeout (tcp_LONGTIMEOUT);
01246         TCP_SEND (s);  /* send opening SYN */
01247
01248         /* find previous RTT replacing RTT set in tcp_send() above
01249          */
01250         if (tcp_rtt_get(s, &rtt, &MTU))
01251              s->rtt_time = set_timeout (rtt);
01252         else s->rtt_time = set_timeout (tcp_OPEN_TO);
01253       }
01254
01255       /* If ARP no longer pending (timed out), hence we abort
01256        */
01257       else if (!arp_lookup_pending(s->hisaddr))    /* ARP timed out */
01258       {
01259         tcp_no_arp (s);
01260         next = TCP_ABORT (s);
01261       }
01262       continue;    /* don't do anything more on this TCB */
01263     }
01264
01265     /* possible to be closed with Rx-data still queued
01266      */
01267     if (s->state == tcp_StateCLOSED)
01268     {
01269       if (s->rx_datalen == 0)
01270       {
01271         maybe_reuse_localport (s);
01272         next = _tcp_unthread (s, TRUE);
01273       }
01274       continue;
01275     }
01276
01277     /* Need to send a window update? Because we advertised a 0 window
01278      * in a previous _tcp_send() (but only in ESTAB state).
01279      */
01280     if ((s->locflags & LF_WINUPDATE) && sock_rbleft((sock_type*)s) > 0)
01281     {
01282       STAT (tcpstats.tcps_sndwinup++);
01283       s->locflags &= ~LF_WINUPDATE;
01284       s->flags |= tcp_FlagACK;
01285       TCP_SEND (s);
01286     }
01287
01288     else if (s->tx_datalen > 0 || s->unhappy || s->karn_count == 1)
01289     {
01290       if (chk_timeout(s->rtt_time))  /* retransmission timeout */
01291       {
01292         s->rtt_time = 0UL;           /* stop RTT timer */
01293
01294         TCP_CONSOLE_MSG (3, ("Regular retran TO set unacked back to "
01295                              "0 from %ld\n", s->send_una));
01296
01297         /* strategy handles closed windows.  JD + EE
01298          */
01299         if (s->window == 0 && s->karn_count == 2)
01300             s->window = 1;
01301
01302         if (s->karn_count == 0)
01303         {
01304           /* Simple "Slow start" algorithm:
01305            * Use the backed off RTO - implied, no code necessary.
01306            * Reduce the congestion window by 25%
01307            */
01308           unsigned cwindow = ((unsigned)(s->cwindow + 1) * 3) >> 2;
01309
01310           s->cwindow = (BYTE) cwindow;
01311           if (s->cwindow == 0)
01312               s->cwindow = 1;
01313
01314           s->wwindow = 0;
01315 #if 0
01316
01317           s->send_ssthresh = s->cwindow * s->max_seg;
01318 #endif
01319           /* if really did timeout
01320            */
01321           s->karn_count = 2;
01322           s->send_una   = 0;
01323         }
01324
01325         if (s->tx_datalen > 0)
01326         {
01327           s->flags |= (tcp_FlagPUSH | tcp_FlagACK);
01328           if (s->cwindow > 1)
01329              s->cwindow--;
01330         }
01331
01332         if (s->unhappy)
01333            STAT (tcpstats.tcps_rexmttimeo++);  /* Normal re-xmit */
01334         else if (s->flags & tcp_FlagACK)
01335            STAT (tcpstats.tcps_delack++);
01336
01337         TCP_SEND (s);
01338
01339         if (s->state == tcp_StateSYNSENT)
01340         {
01343           TCP_TRACE_MSG (("SYN (re)sent in tcp_Retransmitter(), "
01344                           " rtt_time %ld\n",
01345                           get_timediff(s->rtt_time,set_timeout(0))));
01346         }
01347       }
01348
01349       /* handle inactive tcp timeouts (not sending data)
01350        */
01351       else if (chk_timeout(s->datatimer))  /* EE 99.08.23 */
01352       {
01353         next = TCP_ABORT (s);
01354         s->datatimer = 0UL;
01355         s->err_msg   = _LANG ("Connection timed out - no data sent");
01356       }
01357     }  /* end of retransmission strategy */
01358
01359
01360     /* handle inactive TCP timeouts (not received anything)
01361      */
01362     if (chk_timeout(s->inactive_to))
01363     {
01364       /* this baby has timed out. Don't do this again.
01365        */
01366       s->inactive_to = 0UL;
01367       s->err_msg     = _LANG ("Timeout, nothing received");
01368       sock_close ((sock_type*)s);
01369     }
01370     else if (chk_timeout(s->timeout))
01371     {
01372       if (s->state == tcp_StateTIMEWT)
01373       {
01374         s->state = tcp_StateCLOSED;
01375         break;
01376       }
01377       if (s->state != tcp_StateESTAB && s->state != tcp_StateESTCL)
01378       {
01379         next = TCP_ABORT (s);
01380         s->err_msg = _LANG ("Timeout, aborting");
01381         break;
01382       }
01383     }
01384   }
01385 }
01386 #endif /* !USE_UDP_ONLY */
01387
01388
01397 WORD tcp_tick (sock_type *s)
01398 {
01399   static int active = 0;
01400
01401   if (active > 0)
01402   {
01403     TCP_CONSOLE_MSG (1, ("tcp_tick() reentered\n"));
01404     return (s ? s->tcp.ip_type : 0);
01405   }
01406   active++;
01407
01408   SIO_TRACE (("tcp_tick"));
01409
01410 #if !defined(USE_UDP_ONLY)
01411   /*
01412    * Finish off dead sockets
01413    */
01414   if (s)
01415   {
01416     if (s->tcp.ip_type    == TCP_PROTO       &&
01417         s->tcp.state      == tcp_StateCLOSED &&
01418         s->tcp.rx_datalen == 0)
01419     {
01420       _tcp_unthread (&s->tcp, TRUE);
01421       s->tcp.ip_type = 0;   /* fail further I/O */
01422     }
01423   }
01424 #endif
01425
01431   while (active == 1)
01432   {
01433     WORD  eth_type = 0;
01434     BOOL  brdcast  = FALSE;
01435     void *packet   = _eth_arrived (&eth_type, &brdcast);
01436
01437     if (!packet)  /* packet points to network layer protocol */
01438        break;
01439
01440     switch (eth_type)
01441     {
01442       case IP4_TYPE:
01443            _ip4_handler ((in_Header*)packet, brdcast);
01444            break;
01445
01446       case ARP_TYPE:
01447            _arp_handler ((arp_Header*)packet, brdcast);
01448            break;
01449 #if 0
01450       case RARP_TYPE:
01451            _rarp_handler ((rarp_Header*)packet, brdcast);
01452            break;
01453 #endif
01454
01455 #if defined(USE_IPV6)
01456       case IP6_TYPE:
01457            _ip6_handler ((in6_Header*)packet, brdcast);
01458            break;
01459 #endif
01460
01461 #if defined(USE_PPPOE)
01462       case PPPOE_DISC_TYPE:
01463       case PPPOE_SESS_TYPE:
01464            pppoe_handler ((pppoe_Packet*)packet);
01465            break;
01466 #endif
01467
01468       default:
01469 #if defined(USE_DEBUG)
01470            dbug_printf ("\n%s (%d): Unhandled Rx packet, type %04X, "
01471                         "broadcast %d\n", __FILE__, __LINE__,
01472                         intel16(eth_type), brdcast);
01473 #endif
01474            break;
01475
01476            /* RARP is only used during boot. Not needed here */
01477     }
01478     _eth_free (packet);
01479   }
01480
01481 #if !defined(USE_UDP_ONLY)
01482   tcp_Retransmitter (FALSE); /* check for our outstanding packets */
01483 #endif
01484
01485   if (daemon_timer == 0UL || chk_timeout(daemon_timer))
01486   {
01487     run_daemons();
01488     daemon_timer = set_timeout (DAEMON_PERIOD);
01489   }
01490
01491   --active;
01492   return (s ? s->tcp.ip_type : 0);
01493 }
01494
01503 static int udp_write (_udp_Socket *s, const BYTE *data, int len)
01504 {
01505   struct ip4_packet *ip4_pkt = NULL;
01506
01507 #if defined(USE_IPV6)
01508   struct ip6_packet *ip6_pkt = NULL;
01509   struct in6_Header *ip6     = NULL;
01510 #endif
01511
01512   mac_address *dst = (_pktserial ? NULL : &s->his_ethaddr);
01513   in_Header   *ip4 = NULL;
01514   udp_Header  *udp;
01515
01516   SIO_TRACE (("udp_write"));
01517
01518 #if defined(USE_IPV6)
01519   if (s->is_ip6)
01520   {
01521     ip6_pkt = (struct ip6_packet*) _eth_formatpacket (dst, IP6_TYPE);
01522     ip6     = &ip6_pkt->in;
01523     udp     = &ip6_pkt->udp;
01524   }
01525   else
01526 #endif
01527   {
01528     ip4_pkt = (struct ip4_packet*) _eth_formatpacket (dst, IP4_TYPE);
01529     ip4     = &ip4_pkt->in;
01530     udp     = &ip4_pkt->udp;
01531   }
01532
01533   /* build udp header
01534    */
01535   udp->srcPort  = intel16 (s->myport);
01536   udp->dstPort  = intel16 (s->hisport);
01537   udp->checksum = 0;
01538   udp->length   = intel16 (sizeof(*udp)+len);
01539
01540 #if defined(USE_IPV6)
01541   if (s->is_ip6)
01542   {
01543     memcpy (&ip6->source, &in6addr_my_ip, sizeof(ip6->source));
01544     memcpy (&ip6->destination, &s->his6addr, sizeof(ip6->destination));
01545     memcpy (ip6_pkt+1, data, len);   /* copy 'data' to 'ip6_pkt->data[]' */
01546     udp->checksum = _ip6_checksum (ip6, IP6_NEXT_UDP, udp, sizeof(*udp)+len);
01547     if (!IP6_OUTPUT(ip6, &ip6->source, &ip6->destination, IP6_NEXT_UDP,
01548                     sizeof(*udp)+len, 0, s))
01549        return (-1);
01550     return (len);
01551   }
01552   else
01553 #endif
01554   {
01555     tcp_PseudoHeader ph;
01556
01557     memset (&ph, 0, sizeof(ph));
01558     ph.src = intel (s->myaddr);
01559     ph.dst = intel (s->hisaddr);
01560     if (len > 0)
01561        memcpy (ip4_pkt+1, data, len);  /* copy 'data' to 'ip4_pkt->data[]' */
01562
01563     if (s->sockmode & SOCK_MODE_UDPCHK)
01564     {
01565       ph.protocol = UDP_PROTO;
01566       ph.length   = udp->length;
01567       ph.checksum = CHECKSUM (udp, sizeof(*udp)+len);
01568       udp->checksum = ~CHECKSUM (&ph, sizeof(ph));
01569     }
01570     if (!IP4_OUTPUT(ip4, ph.src, ph.dst, UDP_PROTO, s->ttl,
01571                     (BYTE)_default_tos, 0, sizeof(*udp)+len, s))
01572        return (-1);
01573     return (len);
01574   }
01575 }
01576
01583 static int udp_read (_udp_Socket *s, BYTE *buf, int maxlen)
01584 {
01585   int len = s->rx_datalen;
01586
01587   SIO_TRACE (("udp_read"));
01588
01589   if (maxlen < 0)
01590       maxlen = INT_MAX;
01591
01592   if (len > maxlen)
01593       len = maxlen;
01594
01595   if (len > 0)
01596   {
01597     if (buf)
01598        memcpy (buf, s->rx_data, len);
01599     s->rx_datalen -= len;
01600     if (s->rx_datalen > 0)
01601        memmove (s->rx_data, s->rx_data+len, s->rx_datalen);
01602   }
01603   return (len);
01604 }
01605
01610 static void sock_reduce_mss (sock_type *s, WORD MTU)
01611 {
01612   if (s->tcp.ip_type == TCP_PROTO)
01613   {
01614 #if !defined(USE_UDP_ONLY)
01615     _tcp_Socket *tcp = &s->tcp;
01616
01617     if (MTU)
01618          tcp->max_seg = _mtu - TCP_OVERHEAD;
01619     else if (tcp->max_seg > MSS_MIN)
01620          tcp->max_seg -= MSS_REDUCE;
01621     tcp->max_seg = min (max(MSS_MIN, tcp->max_seg), _mss);
01622
01623     TCP_TRACE_MSG (("MSS for %s reduced to %u\n",
01624                     _inet_ntoa(NULL,tcp->hisaddr), tcp->max_seg));
01625 #endif
01626   }
01627   else
01628   {
01629     /* doesn't use MSS yet (always MTU-28) */
01630   }
01631   ARGSUSED (MTU);
01632 }
01633
01639 void _udp_cancel (const in_Header *ip, int icmp_type, int icmp_code,
01640                   const char *msg, const void *arg) /* use a var-arg here ? */
01641 {
01642   WORD         src_port, dst_port, next_mtu;
01643   DWORD        gateway;
01644   int          len     = in_GetHdrLen (ip);
01645   BOOL         passive = FALSE;
01646   udp_Header  *udp     = (udp_Header*) ((BYTE*)ip + len);
01647   _udp_Socket *s;
01648
01649   SIO_TRACE (("_udp_cancel"));
01650
01651   src_port = intel16 (udp->srcPort);
01652   dst_port = intel16 (udp->dstPort);
01653
01654   for (s = _udp_allsocs; s; s = s->next)  /* demux to active sockets */
01655   {
01656     if (s->hisport > 0 &&
01657         dst_port == s->hisport && src_port == s->myport &&
01658         intel(ip->destination) == s->hisaddr)
01659        break;
01660   }
01661
01662   if (!s)       /* check passive sockets */
01663   {
01664     passive = TRUE;
01665     for (s = _udp_allsocs; s; s = s->next)
01666         if (s->hisport == 0 && dst_port == s->myport)
01667            break;
01668   }
01669
01670   if (s)
01671   {
01672     SET_ERR_MSG (s, msg);
01673
01674     /* handle redirect on active sockets
01675      */
01676     if (icmp_type == ICMP_REDIRECT && !passive)
01677     {
01678       WATT_ASSERT (arg != NULL);
01679       gateway = *(DWORD*)arg;
01680       _ip_recursion = 1;
01681       _arp_resolve (gateway, &s->his_ethaddr);
01682       _ip_recursion = 0;
01683     }
01684     else if (icmp_type == ICMP_UNREACH && icmp_code == ICMP_UNREACH_NEEDFRAG)
01685     {
01686       WATT_ASSERT (arg != NULL);
01687       next_mtu = *(WORD*) arg;
01688       if (!passive)
01689          sock_reduce_mss ((sock_type*)s, next_mtu);
01690     }
01691     else if (icmp_type != ICMP_TIMXCEED)
01692     {
01693       /* UDP isn't sturdy, close it on 1st ICMP error
01694        */
01695       SET_ERR_MSG (s, _LANG("Port unreachable"));
01696       s->ip_type   = 0;
01697       s->locflags |= LF_GOT_ICMP;
01698       udp_close (s);
01699     }
01700     if (s->icmp_callb)         /* tell the socket layer about it */
01701       (*s->icmp_callb) (s, icmp_type, icmp_code);
01702   }
01703   else
01704   {
01705     /* tell the INADDR_ANY sockets about it
01706      */
01707     for (s = _udp_allsocs; s; s = s->next)
01708     {
01709       if (s->icmp_callb)
01710         (*s->icmp_callb) (s, icmp_type, icmp_code);
01711     }
01712   }
01713 }
01714
01715 #if !defined(USE_UDP_ONLY)
01716 /*
01717  * Default is to terminate socket on receiving 2nd
01718  * ICMP error. Use sock_sturdy() to change.
01719  */
01720 static BOOL tcp_stress_test (_tcp_Socket *s, const char *msg)
01721 {
01722   if (s->stress++ > s->rigid && s->rigid < 100)  /* halt it */
01723   {
01724     SET_ERR_MSG (s, msg);
01725     s->rx_datalen = 0;
01726     s->tx_datalen = 0;
01727     s->unhappy    = FALSE;
01728     s->locflags  |= LF_GOT_ICMP;
01729     return (FALSE);
01730   }
01731   return (TRUE);
01732 }
01733
01745 void _tcp_cancel (const in_Header *ip, int icmp_type, int icmp_code,
01746                   const char *msg, const void *arg) /* use a var-arg here ? */
01747 {
01748   tcp_Header  *tcp = (tcp_Header*) ((BYTE*)ip + in_GetHdrLen (ip));
01749   _tcp_Socket *s;
01750   DWORD  gateway;
01751   WORD   next_mtu;
01752   WORD   src_port = intel16 (tcp->srcPort);
01753   WORD   dst_port = intel16 (tcp->dstPort);
01754
01755   SIO_TRACE (("_tcp_cancel"));
01756
01757   /* demux to active sockets (passive cannot get ICMP)
01758    */
01759   for (s = _tcp_allsocs; s; s = s->next)
01760   {
01761     if (src_port != s->myport || dst_port != s->hisport ||
01762         intel(ip->destination) != s->hisaddr)
01763        continue;
01764
01765     switch (icmp_type)
01766     {
01767       case ICMP_TIMXCEED:
01768            if (s->ttl < 255)
01769                s->ttl++;
01770            if (tcp_stress_test(s,msg))
01771               goto quench_it;
01772            TCP_ABORT (s);
01773            break;
01774
01775       case ICMP_UNREACH:
01776            if (icmp_code == ICMP_UNREACH_NEEDFRAG)
01777            {
01778              WATT_ASSERT (arg != NULL);
01779              next_mtu = *(WORD*) arg;
01780
01781              /* This should never happen since we normally don't send
01782               * with "Don't Fragment" set. As an optimisation we should
01783               * maybe reduce 'max_seg' for all sockets to this destination.
01784               */
01785              sock_reduce_mss ((sock_type*)s, next_mtu);
01786              break;
01787            }
01788            /* Other types are "fatal"
01789             */
01790            if (!tcp_stress_test(s,msg))
01791            {
01792              TCP_ABORT (s);
01793              break;
01794            }
01795            /* FALLTHROUGH */
01796
01797       case ICMP_SOURCEQUENCH:
01798       quench_it:
01799            s->cwindow = 1;       /* slow-down tx-rate */
01800            s->wwindow = 1;
01801            s->vj_sa <<= 2;
01802            s->vj_sd <<= 2;
01803            s->rto   <<= 2;
01804            tcp_rtt_add (s, s->rto, _mtu);
01805            break;
01806
01807       case ICMP_REDIRECT:
01808            /* don't bother handling redirect if we're closing
01809             */
01810            if (s->state < tcp_StateFINWT1)
01811            {
01812              WATT_ASSERT (arg != NULL);
01813              gateway = *(DWORD*)arg;
01814              SET_ERR_MSG (s, msg);
01815              _ip_recursion = 1;
01816              _arp_resolve (gateway, &s->his_ethaddr);
01817              _ip_recursion = 0;
01818            }
01819            break;
01820
01821       case ICMP_PARAMPROB:
01822            SET_ERR_MSG (s, msg);
01823            TCP_ABORT (s);
01824            break;
01825     }
01826     if (s->icmp_callb)
01827       (*s->icmp_callb) (s, icmp_type, icmp_code);  /* Notify BSD-socket */
01828
01829     return;  /* One ICMP message should only match one TCP socket */
01830   }
01831 }
01832
01838 static int tcp_read (_tcp_Socket *s, BYTE *buf, int maxlen)
01839 {
01840   int len;
01841
01842   SIO_TRACE (("tcp_read"));
01843
01844   if (maxlen < 0)
01845       maxlen = INT_MAX;
01846
01847   len = min (maxlen, s->rx_datalen);
01848
01849   if (len > 0)
01850   {
01851     int to_move;
01852
01853     if (buf)
01854        memcpy (buf, s->rx_data, len);
01855     s->rx_datalen -= len;
01856
01857     to_move = s->rx_datalen;
01858     if (s->missed_seq[0] != s->missed_seq[1])
01859        to_move += s->missed_seq[1] - s->recv_next;
01860
01861     if (to_move > 0)
01862     {
01863       memmove (s->rx_data, s->rx_data + len, to_move);
01864
01865       TCP_SENDSOON (s);     /* delayed ACK */
01866     }
01867     else
01868       tcp_upd_win (s, __LINE__);
01869   }
01870   else if (s->state == tcp_StateCLOSWT)
01871           _tcp_close (s);
01872
01873   /* Added new EOF condition (GV, 11-Oct-2003)
01874    */
01875   if (len == 0 && (s->locflags & LF_GOT_FIN))
01876      return (-1);
01877   return (len);
01878 }
01879
01886 static int tcp_write (_tcp_Socket *s, const BYTE *data, UINT len)
01887 {
01888   UINT room;
01889
01890   SIO_TRACE (("tcp_write"));
01891
01892   if (s->state != tcp_StateESTAB)
01893      return (0);
01894
01895   room = s->max_tx_data - s->tx_datalen - 1;
01896   if (len > room)
01897       len = room;
01898   if (len > 0)
01899   {
01900     int rc = 0;
01901
01902 #if defined(USE_DEBUG)
01903     _sock_check_tcp_buffers (s);
01904 #endif
01905
01906     memcpy (s->tx_data + s->tx_datalen, data, len);
01907     s->tx_datalen += len;
01908
01909     s->unhappy = TRUE;         /* redundant because we have outstanding data */
01910     if (sock_data_timeout)
01911          s->datatimer = set_timeout (1000*sock_data_timeout); /* EE 99.08.23 */
01912     else s->datatimer = 0;
01913
01914     if (s->sockmode & SOCK_MODE_LOCAL) /* queue up data, flush on next write */
01915     {
01916       s->sockmode &= ~SOCK_MODE_LOCAL;
01917       return (len);
01918     }
01919
01920     if (!(s->sockmode & SOCK_MODE_NAGLE))   /* Nagle mode off */
01921        rc = TCP_SEND (s);
01922     else
01923     {
01924       /* Transmit if first segment or reached min (socket_MSS,MSS).
01925        */
01926       if (s->tx_datalen == len ||
01927           s->tx_datalen >= min(s->max_seg,_mss))
01928            rc = TCP_SEND (s);
01929       else rc = TCP_SENDSOON (s);
01930     }
01931     if (rc < 0)
01932        return (-1);
01933   }
01934   return (len);
01935 }
01936
01937
01943 static _tcp_Socket *tcp_findseq (const in_Header *ip, const tcp_Header *tcp)
01944 {
01945   _tcp_Socket *s;
01946   DWORD        dst_host = intel (ip->destination);
01947   DWORD        ack_num  = intel (tcp->acknum);
01948   WORD         dst_port = intel16 (tcp->dstPort);
01949
01950   SIO_TRACE (("tcp_findseq"));
01951
01952   for (s = _tcp_allsocs; s; s = s->next)
01953   {
01954     if (s->hisport != 0       &&
01955         dst_host == s->myaddr &&
01956         dst_port == s->myport &&
01957         ack_num  == s->send_next+1)
01958       break;
01959   }
01960   return (s);
01961 }
01962
01966 static void tcp_sockreset (_tcp_Socket *s, BOOL proxy)
01967 {
01968   const char *str = proxy ? "Proxy reset connection"
01969                           : "Remote reset connection";
01970
01971   SIO_TRACE (("tcp_sockreset"));
01972
01973   if (debug_on)
01974      outsnl (_LANG(str));
01975
01976   if (s->state == tcp_StateSYNREC)
01977        STAT (tcpstats.tcps_conndrops++); /* embryonic connection drop */
01978   else STAT (tcpstats.tcps_drops++);
01979
01980   if (s->state != tcp_StateCLOSED && s->state != tcp_StateLASTACK)
01981       s->rx_datalen = 0;
01982
01983   s->missed_seq[0] = s->missed_seq[1] = 0; /* discard buffered out-of-order */
01984
01985   s->tx_datalen = 0;   /* Empty Tx buffer */
01986
01987   if (s->locflags & LF_IS_SERVER)
01988   {
01989     CLR_PEER_MAC_ADDR (s);
01990     s->cwindow  = 1;
01991     s->rtt_time = 0UL;
01992     s->unhappy  = FALSE;
01993     s->hisport  = 0;
01994     s->hisaddr  = 0UL;
01995     s->locflags &= ~(LF_WINUPDATE | LF_KEEPALIVE | LF_GOT_FIN | LF_GOT_ICMP);
01996
01997     s->datatimer   = 0UL;
01998     s->inactive_to = 0;
01999     s->timeout     = 0;
02000     s->karn_count  = 0;
02001     s->state       = tcp_StateLISTEN;
02002     TCP_TRACE_MSG (("tcp_sockreset(): continue to LISTEN\n"));
02003   }
02004   else
02005   {
02006     s->err_msg = _LANG (str);
02007     s->state   = tcp_StateCLOSED;
02008     s->ip_type = 0;      /* 2001.1.18 - make it fail tcp_tick() */
02009
02010 #if defined(USE_BSD_API)
02011     if (_bsd_socket_hook)
02012       (*_bsd_socket_hook) (BSO_RST_CALLBACK, s);
02013 #endif
02014     _tcp_unthread (s, TRUE);
02015   }
02016 }
02017
02022 static void tcp_no_arp (_tcp_Socket *s)
02023 {
02024   SIO_TRACE (("tcp_no_arp"));
02025
02026   s->err_msg = _LANG ("No ARP reply");
02027   STAT (ip4stats.ips_noroute++);
02028
02029 #if defined(USE_BSD_API)
02030   if (_bsd_socket_hook)
02031   {
02032     Socket *sock = (Socket*) (*_bsd_socket_hook) (BSO_FIND_SOCK, s);
02033
02034     if (sock)  /* do a "read-wakeup" on the SOCK_STREAM socket */
02035     {
02036       sock->so_state |= SS_ISDISCONNECTING;
02037       sock->so_error = EHOSTUNREACH; /* !! Or ETIMEDOUT? */
02038     }
02039   }
02040 #endif
02041 }
02042
02047 static BOOL tcp_checksum (const in_Header *ip, const tcp_Header *tcp, int len)
02048 {
02049   tcp_PseudoHeader ph = { 0,0,0,0,0,0 };
02050
02051   SIO_TRACE (("tcp_checksum"));
02052
02053   ph.src      = ip->source;
02054   ph.dst      = ip->destination;
02055   ph.protocol = TCP_PROTO;
02056   ph.length   = intel16 (len);
02057   ph.checksum = CHECKSUM (tcp, len);
02058
02059   if (CHECKSUM(&ph,sizeof(ph)) != 0xFFFF)
02060   {
02061     STAT (tcpstats.tcps_rcvbadsum++);
02062     TCP_CONSOLE_MSG (1, (_LANG("Bad tcp checksum. ")));
02063     TCP_TRACE_MSG (("Bad tcp checksum\n"));
02064     return (FALSE);
02065   }
02066   return (TRUE);
02067 }
02068
02073 static void tcp_rtt_win (_tcp_Socket *s)
02074 {
02075   DWORD timeout;
02076
02077   SIO_TRACE (("tcp_rtt_win"));
02078
02079   /* update our retransmission stuff (Karn algorithm)
02080    */
02081   if (s->karn_count == 2)    /* Wake up from slow-start */
02082   {
02083     TCP_CONSOLE_MSG (2, ("Finally got it safely zapped from %ld to ???\n",
02084                      s->send_una));
02085   }
02086   else if (s->vj_last)     /* We expect an immediate response */
02087   {
02088     long  dT;      /* Time (msec) since last (re)transmission */
02089     DWORD now;
02090
02091     chk_timeout (0UL);          /* Update date/date_ms */
02092     now = set_timeout (0);
02093
02094 #if 0
02095     if (s->ts_echo && s->ts_echo >= s->ts_sent)
02096        dT = get_timediff (s->ts_echo, s->ts_sent) >> 1;
02097     else
02098 #else
02099        dT = get_timediff (now, s->vj_last);
02100 #endif
02101
02102     if (dT >= 0)
02103     {
02104       dT -= (DWORD)(s->vj_sa >> 3);
02105       s->vj_sa += dT;
02106
02107       if (dT < 0)
02108           dT = -dT;
02109
02110       dT -= (s->vj_sd >> 2);
02111       s->vj_sd += dT;               /* vj_sd = RTTVAR, rtt variance */
02112
02113       if (s->vj_sa > tcp_MAX_VJSA)  /* vj_sa = SRTT, smoothed RTT */
02114           s->vj_sa = tcp_MAX_VJSA;
02115       if (s->vj_sd > tcp_MAX_VJSD)
02116           s->vj_sd = tcp_MAX_VJSD;
02117     }
02118
02119     /* only recompute RTT hence RTO after success
02120      */
02121     s->rto = tcp_RTO_BASE + (((s->vj_sa >> 2) + (s->vj_sd)) >> 1);
02122
02123     tcp_rtt_add (s, s->rto, _mtu);
02124
02125     TCP_CONSOLE_MSG (2, ("RTO %u  sa %lu  sd %lu  cwindow %u"
02126                      "  wwindow %u  unacked %ld\n",
02127                      s->rto, s->vj_sa, s->vj_sd, s->cwindow,
02128                      s->wwindow, s->send_una));
02129   }
02130
02131   s->karn_count = 0;
02132   if (s->wwindow != 255)
02133   {
02136 #if 0
02137     if (s->cwindow * s->max_seg < s->send_ssthresh)
02138         s->cwindow++;
02139 #else
02140
02141     /* A. Iljasov (iljasov@oduurl.ru) suggested this pre-increment
02142      */
02143     if (++s->wwindow >= s->cwindow)
02144     {
02145       if (s->cwindow != 255)
02146           s->cwindow++;
02147       s->wwindow = 0;    /* mdurkin -- added 95.05.02 */
02148     }
02149 #endif
02150   }
02151
02152   /* Restart RTT timer or postpone retransmission based on
02153    * calculated RTO. Make sure date/date_ms variables are updated
02154    * close to midnight.
02155    */
02156   chk_timeout (0UL);
02157   timeout = set_timeout (s->rto + tcp_RTO_ADD);
02158
02159   if (s->rtt_time == 0UL || cmp_timers(s->rtt_time,timeout) < 0)
02160       s->rtt_time = timeout;
02161
02162   s->datatimer = 0UL; /* resetting tx-timer, EE 99.08.23 */
02163 }
02164
02168 static void tcp_upd_win (_tcp_Socket *s, unsigned line)
02169 {
02170   UINT winfree = s->max_rx_data - (UINT)s->rx_datalen;
02171
02172   SIO_TRACE (("tcp_upd_win"));
02173
02174   if (winfree < s->max_seg/2)
02175   {
02176     _tcp_send (s, __FILE__, line);  /* update window now */
02177     TCP_CONSOLE_MSG (2, ("tcp_upd_win(%d): win-free %u\n", line, winfree));
02178   }
02179 }
02180
02189 static __inline int tcp_opt_maxsegment (const _tcp_Socket *s, BYTE *opt)
02190 {
02191   *opt++ = TCPOPT_MAXSEG;    /* option: MAXSEG,length,MSS */
02192   *opt++ = 4;
02193   *(WORD*) opt = intel16 ((WORD)s->max_seg);
02194   return (4);
02195 }
02196
02202 static __inline int tcp_opt_timestamp (_tcp_Socket *s, BYTE *opt, DWORD ts_echo)
02203 {
02204   DWORD ts_now = set_timeout (0) - start_time;  /* TSval */
02205   BYTE *start  = opt;
02206
02207   *opt++ = TCPOPT_NOP;     /* NOP,NOP,TIMESTAMP,length,TSval,TSecho */
02208   *opt++ = TCPOPT_NOP;     /*         ---------- = 10 ------------- */
02209   *opt++ = TCPOPT_TIMESTAMP;
02210   *opt++ = 10;
02211   *(DWORD*) opt = intel (ts_now);
02212   opt += sizeof(ts_now);
02213   *(DWORD*) opt = intel (ts_echo);
02214   opt += sizeof(ts_echo);
02215   s->ts_sent = ts_now;      /* remember TSval */
02216   return (opt - start);     /* 20 bytes */
02217 }
02218
02219 #if defined(USE_TCP_MD5)
02220
02223 static BYTE *sign_opt;
02224
02225 static __inline int tcp_opt_md5_sign (BYTE *opt)
02226 {
02227   *opt++ = TCPOPT_SIGNATURE;  /* option: 19,length,MD5-signature,NOP,NOP */
02228   *opt++ = 2+TCPOPT_SIGN_LEN;
02229   sign_opt = opt;             /* remember for finalise_md5_sign() */
02230   opt += TCPOPT_SIGN_LEN;
02231   *opt++ = TCPOPT_NOP;
02232   *opt++ = TCPOPT_NOP;
02233   return (4+TCPOPT_SIGN_LEN);
02234 }
02235
02236 static __inline void finalise_md5_sign (const in_Header *ip,
02237                                         const tcp_Header *tcp,
02238                                         WORD tcp_len, const char *secret)
02239 {
02240   if (secret && sign_opt)
02241      make_md5_signature (ip, tcp, tcp_len, secret, sign_opt);
02242   sign_opt = NULL;
02243 }
02244 #endif
02245
02246
02247 #if defined(NOT_USED_YET)
02248
02251 static __inline int tcp_opt_padding (BYTE *opt, int len)
02252 {
02253   int pad = len % 4;
02254
02255   if (pad > 0)
02256      *opt++ = TCPOPT_NOP;
02257   if (pad > 1)
02258      *opt++ = TCPOPT_NOP;
02259   if (pad > 2)
02260      *opt++ = TCPOPT_NOP;
02261   if (pad > 3)
02262      *opt++ = TCPOPT_NOP;
02263   return (pad);
02264 }
02265
02266 static __inline int tcp_opt_winscale (const _tcp_Socket *s, BYTE *opt)
02267 {
02268   *opt++ = TCPOPT_WINDOW;    /* option: WINDOW,length,wscale */
02269   *opt++ = 3;
02270   *opt   = s->tx_wscale;
02271   return (4);
02272 }
02273
02274 static __inline int tcp_opt_sack_ok (const _tcp_Socket *s, BYTE *opt)
02275 {
02276   *opt++ = TCPOPT_SACKOK;
02277   *opt++ = 2;
02278   *opt++ = TCPOPT_NOP;
02279   *opt++ = TCPOPT_NOP;
02280   return (4);
02281 }
02282
02283 static __inline int tcp_opt_sack (const _tcp_Socket *s, BYTE *opt,
02284                                   const struct SACK_list *sack)
02285 {
02286   int i, len = 2 + 8 * sack->num_blk;
02287
02288   *opt++ = TCPOPT_SACK;       /* option: SACK,length,left,right,.. */
02289   *opt++ = len;
02290   for (i = 0; i < sack->num_blk; i++)
02291   {
02292     *(DWORD*) opt = intel (sack->list[i].left_edge);
02293     opt += sizeof(DWORD);
02294     *(DWORD*) opt = intel (sack->list[i].right_edge);
02295     opt += sizeof(DWORD);
02296   }
02297   return (len + tcp_opt_padding(opt,len));
02298 }
02299 #endif  /* NOT_USED_YET */
02300
02301
02305 static __inline int tcp_options (_tcp_Socket *s, BYTE *opt, BOOL is_syn)
02306 {
02307   int len = 0;
02308
02309   if (s->locflags & LF_NOOPT)   /* we suppress options */
02310      return (0);
02311
02312   if (is_syn)
02313   {
02314     len = tcp_opt_maxsegment (s, opt);
02315
02316     if (tcp_opt_ts)
02317        len += tcp_opt_timestamp (s, opt+len, 0UL);
02318 #if 0
02319     if (s->locflags & LF_REQ_SCALE)
02320        len += tcp_opt_winscale (s, opt+len);
02321     if (tcp_opt_sack)
02322        len += tcp_opt_sack_ok (s, opt+len);
02323 #endif
02324   }
02325   else if (tcp_opt_ts &&
02326            !(s->flags & (tcp_FlagFIN|tcp_FlagRST)) &&
02327            (s->locflags & LF_USE_TSTAMP))
02328   {
02329     /* We got a TS option in a previous SYN or SYN-ACK.
02330      * Echo it if "tcp.opt.ts = 1" and not sending a FIN/RST.
02331      */
02332     len = tcp_opt_timestamp (s, opt, s->ts_recent);
02333     s->locflags &= ~LF_USE_TSTAMP;  /* don't echo this again */
02334   }
02335
02336 #if defined(USE_TCP_MD5)
02337   if (s->secret)
02338      len += tcp_opt_md5_sign (opt+len);
02339 #endif
02340
02341   WATT_ASSERT (len == 0 || (len % 4) == 0);
02342   return (len);
02343 }
02344
02349 int _tcp_send (_tcp_Socket *s, char *file, unsigned line)
02350 {
02351   struct tcp_pkt *pkt;
02352
02353 #if defined(USE_IPV6)
02354   struct tcp6_pkt   *pkt6;
02355   struct in6_Header *ip6 = NULL;
02356 #endif
02357
02358   BOOL         tx_ok;
02359   BYTE        *data;             /* where to copy user's data */
02360   mac_address *dst;
02361   in_Header   *ip = NULL;
02362   tcp_Header  *tcp;
02363   int          send_tot_len = 0; /* count of data length we've sent */
02364   int          send_data_len;    /* how much data in this segment */
02365   int          start_data;       /* where data starts in tx-buffer */
02366   int          send_tot_data;    /* total amount of data to send */
02367   int          tcp_len;          /* total length of TCP segment */
02368   int          opt_len;          /* total length of TCP options */
02369   int          pkt_num;          /* 0 .. s->cwindow-1 */
02370   int          rtt;
02371
02372   SIO_TRACE (("_tcp_send"));
02373
02374   s->recent = 0;
02375   dst = (_pktserial ? NULL : &s->his_ethaddr);
02376
02377 #if defined(USE_IPV6)
02378   if (s->is_ip6)
02379   {
02380     pkt6 = (struct tcp6_pkt*) _eth_formatpacket (dst, IP6_TYPE);
02381     ip6  = &pkt6->in;
02382     tcp  = &pkt6->tcp;
02383   }
02384   else
02385 #endif
02386   {
02387     pkt = (struct tcp_pkt*) _eth_formatpacket (dst, IP4_TYPE);
02388     ip  = &pkt->in;
02389     tcp = &pkt->tcp;
02390   }
02391
02392   data = (BYTE*) (tcp+1);   /* data starts here if no options */
02393
02394   if (s->karn_count == 2)   /* doing slow-start */
02395   {
02396     send_tot_data = min (s->tx_datalen, s->window);
02397     start_data = 0;
02398   }
02399   else
02400   {
02401     /* Morten Terstrup <MorTer@dk-online.dk> found this signed bug
02402      */
02403     int size = min (s->tx_datalen, s->window);
02404
02405     send_tot_data = size - s->send_una;
02406     if (send_tot_data < 0)
02407         send_tot_data = 0;
02408     start_data = s->send_una;   /* relative tx_data[] */
02409   }
02410
02411   /* step through our packets
02412    */
02413   for (pkt_num = 0; pkt_num < s->cwindow; pkt_num++)
02414   {
02415 #if 1
02416     if (s->safetysig != SAFETY_TCP || s->safetytcp != SAFETY_TCP)
02417     {
02418       outsnl (_LANG("Error in _tcp_send()"));
02419       s->safetysig = s->safetytcp = SAFETY_TCP;
02420       return (0);
02421     }
02422 #else
02423     WATT_ASSERT (s->safetysig == SAFETY_TCP);  /* hard to find GoAhead bug! */
02424     WATT_ASSERT (s->safetytcp == SAFETY_TCP);
02425 #endif
02426
02427     /* make tcp header
02428      */
02429     tcp->srcPort  = intel16 (s->myport);
02430     tcp->dstPort  = intel16 (s->hisport);
02431     tcp->seqnum   = intel (s->send_next + start_data); /* unacked - no longer send_tot_len */
02432     tcp->acknum   = intel (s->recv_next);
02433
02434     s->adv_win    = s->max_rx_data - s->rx_datalen; /* advertised recv window */
02435     tcp->window   = intel16 ((WORD)s->adv_win);
02436     tcp->flags    = (BYTE) s->flags;
02437     tcp->unused   = 0;
02438     tcp->checksum = 0;
02439     tcp->urgent   = 0;
02440
02441     /* Insert any TCP options after header.
02442      */
02443     if (pkt_num == 0 && (s->flags & tcp_FlagSYN) == tcp_FlagSYN)
02444     {
02445       opt_len = tcp_options (s, data, TRUE);
02446       send_data_len = 0;   /* no data, only options */
02447     }
02448     else
02449     {
02450       int data_free;
02451
02452       opt_len   = tcp_options (s, data, FALSE);
02453       data_free = s->max_seg - opt_len;
02454       if (data_free < 0)
02455           data_free = 0;
02456       send_data_len = min (send_tot_data, data_free);
02457     }
02458
02459     tcp_len = sizeof(*tcp) + opt_len;  /* TCP header length */
02460     data   += opt_len;
02461     tcp->offset = tcp_len/4;           /* # of 32-bit dwords */
02462
02463     if (send_data_len > 0)             /* non-SYN packets with data */
02464     {
02465       tcp_len += send_data_len;
02466       if (s->tx_queuelen)
02467            memcpy (data, s->tx_queue+start_data, send_data_len);
02468       else memcpy (data, s->tx_data +start_data, send_data_len);
02469     }
02470
02471     if (s->locflags & LF_NOPUSH)
02472        tcp->flags &= ~tcp_FlagPUSH;
02473
02474 #if defined(USE_TCP_MD5)
02475     finalise_md5_sign (ip, tcp, tcp_len-sizeof(*tcp), s->secret);
02476 #endif
02477
02478     /* Send using _ip?_output()
02479      */
02480 #if defined(USE_IPV6)
02481     if (s->is_ip6)
02482     {
02483       memcpy (&ip6->source, &s->my6addr, sizeof(ip6->source));
02484       memcpy (&ip6->destination, &s->his6addr, sizeof(ip6->destination));
02485       tcp->checksum = _ip6_checksum (ip6, IP6_NEXT_TCP, tcp, tcp_len);
02486       tx_ok = _ip6_output (ip6, &ip6->source, &ip6->destination, IP6_NEXT_TCP,
02487                            tcp_len, 0, s, file, line) != 0;
02488     }
02489     else
02490 #endif
02491     {
02492       tcp_PseudoHeader ph = { 0,0,0,0,0,0 };
02493
02494       ph.src      = intel (s->myaddr);
02495       ph.dst      = intel (s->hisaddr);
02496       ph.protocol = TCP_PROTO;
02497       ph.length   = intel16 (tcp_len);
02498       ph.checksum = CHECKSUM (tcp, tcp_len);
02499       tcp->checksum = ~CHECKSUM (&ph, sizeof(ph));
02500
02501       tx_ok = _ip4_output (ip, ph.src, ph.dst, TCP_PROTO,
02502                            s->ttl, s->tos, 0, tcp_len, s, file, line) != 0;
02503     }
02504
02505     if (!tx_ok)
02506     {
02507       TCP_SENDSOON (s);
02508       return (-1);
02509     }
02510
02511     /* do next packet
02512      */
02513     if (send_data_len > 0)
02514     {
02515       send_tot_len  += send_data_len;
02516       start_data    += send_data_len;   /* new start of data */
02517       send_tot_data -= send_data_len;   /* total data remaining */
02518     }
02519     if (send_tot_data <= 0)
02520     {
02521       pkt_num++;
02522       break;
02523     }
02524   }
02525
02526   s->send_una = start_data;  /* relative start of tx_data[] buffer */
02527
02528   TCP_CONSOLE_MSG (2, ("tcp_send (called from %s/%u): sent %u bytes in %u "
02529                    "packets with (%ld) unacked. SND.NXT %lu\n",
02530                    file, line, send_tot_len, pkt_num, s->send_una,
02531                    s->send_next));
02532
02533   s->vj_last = 0UL;
02534   if (s->karn_count == 2)
02535   {
02536     if (s->rto)
02537          s->rto = (s->rto * 3) / 2;  /* increase by 50% */
02538     else s->rto = 2*tcp_RTO_ADD;     /* !!was 4 tick */
02539   }
02540   else
02541   {
02542     /* vj_last nonzero if we expect an immediate response
02543      */
02544     if (s->unhappy || s->tx_datalen)
02545         s->vj_last = set_timeout (0);
02546     s->karn_count = 0;
02547   }
02548
02549   /* Determine when a retransmission should be sent
02550    */
02551   rtt = s->rto + tcp_RTO_ADD;
02552
02553   s->rtt_time = set_timeout (rtt);
02554
02555   if (send_tot_len > 0)
02556      s->rtt_lasttran = s->rtt_time;
02557
02558   return (send_tot_len);
02559 }
02560
02565 int _tcp_send_reset (_tcp_Socket *s, const in_Header *his_ip,
02566                      const tcp_Header *org_tcp, const char *file, unsigned line)
02567 {
02568   tcp_PseudoHeader  ph;
02569
02570   #include <sys/packon.h>
02571
02572   struct ip4_packet {
02573          in_Header  ip;
02574          tcp_Header tcp;
02575        } *ip4_pkt = NULL;
02576
02577 #if defined(USE_IPV6)
02578   struct ip6_packet {
02579          in6_Header ip;
02580          tcp_Header tcp;
02581        } *ip6_pkt = NULL;
02582 #endif
02583
02584   #include <sys/packoff.h>
02585
02586   BYTE         flags;
02587   tcp_Header  *tcp;
02588   BOOL         is_ip4 = (his_ip->ver == 4);
02589   DWORD        acknum, seqnum;
02590   WORD         tcp_len;
02591
02592   if (tcp_RST_TIME)   /* tcp_RST_TIME = 0: always send RST */
02593   {
02594     static DWORD next_RST_time = 0UL;
02595
02596     if (next_RST_time && !chk_timeout(next_RST_time))
02597        return (-1);
02598
02599     next_RST_time = set_timeout (tcp_RST_TIME);
02600   }
02601
02602   flags = org_tcp->flags;
02603   if (flags == 0 ||           /* ignore if no flags set */
02604       (flags & tcp_FlagRST))  /* or RST set */
02605      return (-1);
02606
02607   if ((flags & (tcp_FlagSYN|tcp_FlagACK)) == tcp_FlagSYN) /* SYN only */
02608   {
02609     acknum = intel (org_tcp->seqnum) + 1;
02610     seqnum = 0;
02611     flags  = tcp_FlagACK;
02612   }
02613   else if (flags & tcp_FlagACK)
02614   {
02615     seqnum = intel (org_tcp->acknum);
02616     acknum = 0;
02617     flags  = 0;
02618   }
02619   else
02620   {
02621     const in6_Header *his_ip6 = (const in6_Header*) his_ip;
02622     int   len, ofs = org_tcp->offset << 2;
02623
02624     if (is_ip4)
02625          len = intel16 (his_ip->length) - in_GetHdrLen (his_ip);
02626     else len = intel16 (his_ip6->len);
02627
02628     acknum = intel (org_tcp->seqnum) + (len - ofs);
02629     seqnum = 0;
02630     flags  = 0;
02631   }
02632
02633 #if defined(USE_IPV6)
02634   if (!is_ip4)
02635   {
02636     ip6_pkt = (struct ip6_packet*) _eth_formatpacket (MAC_SRC(his_ip),
02637                                                       IP6_TYPE);
02638     tcp = &ip6_pkt->tcp;
02639   }
02640   else
02641 #endif
02642   {
02643     ip4_pkt = (struct ip4_packet*) _eth_formatpacket (MAC_SRC(his_ip),
02644                                                       IP4_TYPE);
02645     tcp = &ip4_pkt->tcp;
02646   }
02647
02648   /* tcp header
02649    */
02650   tcp_len       = sizeof(*tcp);
02651   tcp->srcPort  = org_tcp->dstPort;
02652   tcp->dstPort  = org_tcp->srcPort;
02653   tcp->seqnum   = intel (seqnum);
02654   tcp->acknum   = intel (acknum);
02655   tcp->window   = 0;     /* non-zero means "BSD derived" */
02656   tcp->flags    = (flags & tcp_FlagMASK) | tcp_FlagRST;
02657   tcp->unused   = 0;
02658   tcp->checksum = 0;
02659   tcp->urgent   = 0;
02660
02661 #if defined(USE_TCP_MD5)
02662   if (is_ip4 && s && s->secret)
02663   {
02664     tcp_len += tcp_opt_md5_sign ((BYTE*)(tcp+1));
02665     finalise_md5_sign (&ip4_pkt->ip, tcp, 0, s->secret);
02666   }
02667 #endif
02668
02669   tcp->offset = tcp_len / 4;
02670
02671 #if defined(USE_IPV6)
02672   if (!is_ip4)
02673   {
02674     in6_Header *ip6 = &ip6_pkt->ip;
02675
02676     memcpy (&ip6->source, &in6addr_my_ip, sizeof(ip6->source));
02677     memcpy (&ip6->destination, ((in6_Header*)his_ip)->source, sizeof(ip6->destination));
02678     tcp->checksum = 0;
02679     tcp->checksum = _ip6_checksum (ip6, IP6_NEXT_TCP, tcp, tcp_len);
02680
02681     return _ip6_output (ip6, &ip6->source, &ip6->destination,
02682                         IP6_NEXT_TCP, tcp_len, 0, s, file, line);
02683   }
02684 #endif
02685
02686   memset (&ph, 0, sizeof(ph));
02687   ph.src      = his_ip->destination;
02688   ph.dst      = his_ip->source;
02689   ph.protocol = TCP_PROTO;
02690   ph.length   = intel16 (tcp_len);
02691   ph.checksum = CHECKSUM (tcp, tcp_len);
02692
02693   tcp->checksum = ~CHECKSUM (&ph, sizeof(ph));
02694
02695   return _ip4_output (&ip4_pkt->ip, ph.src, ph.dst, TCP_PROTO,
02696                       s ? s->ttl : _default_ttl, his_ip->tos, 0,
02697                       tcp_len, s, file, line);
02698 }
02699
02708 int _tcp_keepalive (_tcp_Socket *tcp)
02709 {
02710   DWORD ack, seq;
02711   BYTE  kc;
02712   int   rc;
02713
02714   SIO_TRACE (("_tcp_keepalive"));
02715
02716   if (tcp->ip_type != TCP_PROTO || tcp->state < tcp_StateSYNSENT ||
02717       tcp->tx_datalen > 0)
02718      return (0);
02719
02720   ack = tcp->recv_next;
02721   seq = tcp->send_next;
02722   kc  = tcp->karn_count;
02723
02724   tcp->recv_next  = tcp->send_next;
02725   tcp->send_next  = tcp->send_next + tcp->send_una - 1;
02726   tcp->flags      = tcp_FlagACK;
02727   tcp->karn_count = 2;
02728   tcp->tx_datalen = 1;   /* BSD 4.2 requires data to respond to a keepalive */
02729   tcp->tx_data[0] = '0';
02730   rc = TCP_SEND (tcp);
02731
02732   tcp->tx_datalen = 0;
02733   tcp->recv_next  = ack;
02734   tcp->send_next  = seq;
02735   tcp->karn_count = kc;
02736   tcp->locflags  &= ~LF_KEEPALIVE;
02737
02738   STAT (tcpstats.tcps_keepprobe++);
02739   STAT (tcpstats.tcps_keeptimeo++);
02740   return (rc);
02741 }
02742
02743 int sock_keepalive (sock_type *s)
02744 {
02745   return _tcp_keepalive (&s->tcp);
02746 }
02747 #endif  /* !USE_UDP_ONLY */
02748
02749
02758 #define TCP_H_SM_BINARY           0x01
02759 #define TCP_H_SM_ASCII            0x02
02760 #define TCP_H_SM_UDP_MODE_CHK     0x04
02761 #define TCP_H_SM_UDP_MODE_NOCHK   0x08
02762 #define TCP_H_SM_TCP_MODE_NAGLE   0x10
02763 #define TCP_H_SM_TCP_MODE_NONAGLE 0x20
02764 #define TCP_H_SM_MASK             0x3F
02765
02766 WORD sock_mode (sock_type *s, WORD mode)
02767 {
02768   if (s->tcp.ip_type == TCP_PROTO || s->tcp.ip_type == UDP_PROTO)
02769   {
02770     int old_nagle  = (s->tcp.sockmode & SOCK_MODE_NAGLE);
02771     int old_bmode  = (s->tcp.sockmode & SOCK_MODE_BINARY);
02772     int old_udpchk = (s->udp.sockmode &= SOCK_MODE_UDPCHK);
02773
02774     mode &= TCP_H_SM_MASK;
02775     if (mode == 0)
02776        return (s->tcp.sockmode & SOCK_MODE_MASK);
02777
02778     s->tcp.sockmode &= ~SOCK_MODE_MASK; /* turn all bits off */
02779
02780     if (mode & TCP_H_SM_BINARY)
02781        s->tcp.sockmode |= SOCK_MODE_BINARY;
02782     else if (mode & TCP_H_SM_ASCII)
02783        s->tcp.sockmode &= ~SOCK_MODE_BINARY;
02784     else
02785        s->tcp.sockmode |= old_bmode;
02786
02787     if (s->tcp.ip_type == UDP_PROTO)
02788     {
02789       if (mode & TCP_H_SM_UDP_MODE_CHK)
02790          s->udp.sockmode |= SOCK_MODE_UDPCHK;
02791       else if (mode & TCP_H_SM_UDP_MODE_NOCHK)
02792          s->udp.sockmode &= ~SOCK_MODE_UDPCHK;
02793       else
02794          s->udp.sockmode |= old_udpchk;
02795       return (s->udp.sockmode);
02796     }
02797
02798     if (mode & TCP_H_SM_TCP_MODE_NAGLE)
02799        s->tcp.sockmode |= SOCK_MODE_NAGLE;
02800     else if (mode & TCP_H_SM_TCP_MODE_NONAGLE)
02801        s->tcp.sockmode &= ~SOCK_MODE_NAGLE;
02802     else
02803        s->tcp.sockmode |= old_nagle;
02804     return (s->tcp.sockmode);
02805   }
02806   return (0);
02807 }
02808
02813 void (*sock_yield (_tcp_Socket *s, void (*fn)(void)))(void)
02814 {
02815   void (*old)(void);
02816
02817   if (s)
02818   {
02819     old = s->usr_yield;
02820     s->usr_yield = fn;
02821   }
02822   else
02823   {
02824     old = system_yield;
02825     system_yield = fn;
02826   }
02827   return (old);
02828 }
02829
02833 void sock_abort (sock_type *s)
02834 {
02835   SIO_TRACE (("sock_abort"));
02836
02837   switch (s->tcp.ip_type)
02838   {
02839 #if !defined(USE_UDP_ONLY)
02840     case TCP_PROTO:
02841          TCP_ABORT (&s->tcp);
02842          break;
02843 #endif
02844     case UDP_PROTO:
02845          udp_close (&s->udp);
02846          break;
02847     case IP4_TYPE:
02848          s->raw.ip_type = 0;
02849          s->raw.used    = 0;
02850          break;
02851   }
02852 }
02853
02854 #if defined(USE_BSD_API)
02855
02858 static int raw_read (_raw_Socket *raw, BYTE *buf, int maxlen)
02859 {
02860   int len = 0;
02861
02862   SIO_TRACE (("raw_read"));
02863
02864   if (raw->used)
02865   {
02866     int   hlen = in_GetHdrLen (&raw->ip);
02867     BYTE *data = (BYTE*)&raw->ip + hlen;
02868
02869     len = intel16 (raw->ip.length) - hlen;
02870     len = min (len, maxlen);
02871     memcpy (buf, data, len);
02872     raw->used = 0;
02873   }
02874   return (len);
02875 }
02876 #endif
02877
02884 int sock_read (sock_type *s, BYTE *buf, int maxlen)
02885 {
02886   int count = 0;
02887
02888   SIO_TRACE (("sock_read"));
02889
02890   do
02891   {
02892     int len = 0;
02893     int raw = 0;
02894
02895     switch (s->udp.ip_type)
02896     {
02897 #if !defined(USE_UDP_ONLY)
02898       case TCP_PROTO:
02899            len = tcp_read (&s->tcp, buf, maxlen);
02900            break;
02901 #endif
02902       case UDP_PROTO:
02903            len = udp_read (&s->udp, buf, maxlen);
02904            break;
02905
02906 #if defined(USE_BSD_API)
02907       case IP4_TYPE:
02908            raw = TRUE;
02909            len = raw_read (&s->raw, buf, maxlen);
02910            break;
02911 #endif
02912     }
02913
02914     if (len < 1)
02915     {
02916       if (!tcp_tick(s) || len < 0)
02917          break;
02918     }
02919     else
02920     {
02921       count  += len;
02922       buf    += len;
02923       maxlen -= len;
02924     }
02925     if (maxlen > 0 && !raw && s->tcp.usr_yield) /* yield only when room */
02926       (*s->tcp.usr_yield)();                    /* 99.07.01 EE */
02927   }
02928   while (maxlen);
02929   return (count);
02930 }
02931
02936 int sock_fastread (sock_type *s, BYTE *buf, int len)
02937 {
02938   SIO_TRACE (("sock_fastread"));
02939
02940   if (s->udp.ip_type == UDP_PROTO)
02941      return udp_read (&s->udp, buf, len);
02942
02943 #if !defined(USE_UDP_ONLY)
02944   if (s->tcp.ip_type == TCP_PROTO || s->tcp.rx_datalen > 0)
02945      return tcp_read (&s->tcp, buf, len);
02946 #endif
02947
02948 #if defined(USE_BSD_API)
02949   if (s->raw.ip_type == IP4_TYPE)
02950      return raw_read (&s->raw, buf, len);
02951 #endif
02952
02953   return (-1);
02954 }
02955
02956
02965 int sock_write (sock_type *s, const BYTE *data, int len)
02966 {
02967   size_t chunk;
02968   size_t remain  = len;
02969   int    written = 0;
02970
02971   SIO_TRACE (("sock_write"));
02972
02973   while (remain > 0)
02974   {
02975     switch (s->udp.ip_type)
02976     {
02977 #if !defined(USE_UDP_ONLY)
02978       case TCP_PROTO:
02979            s->tcp.flags |= tcp_FlagPUSH;
02980            written = tcp_write (&s->tcp, data, remain);
02981            break;
02982 #endif
02983       case UDP_PROTO:
02984            chunk   = min (_mtu - UDP_OVERHEAD, remain);
02985            written = udp_write (&s->udp, data, chunk);
02986            break;
02987
02988 #if defined(USE_BSD_API)
02989       case IP4_TYPE:
02990       case IP6_TYPE:
02991            return (0);   /* not supported yet */
02992 #endif
02993       default:           /* EE 99.06.14 */
02994 #if defined(USE_DEBUG)
02995            dbug_printf ("sock_write() called with unknown proto %04Xh\n",
02996                         s->udp.ip_type);
02997 #endif
02998            return (0);
02999     }
03000
03001     if (written < 0)
03002     {
03003       s->udp.err_msg = _LANG ("Tx Error");
03004       return (0);
03005     }
03006     data   += written;
03007     remain -= written;
03008
03009     if (s->udp.usr_yield)
03010       (*s->udp.usr_yield)();
03011
03012     if (!tcp_tick(s))
03013        return (0);  /* !! should be 'len - remain' ? */
03014   }
03015   return (len);
03016 }
03017
03022 int sock_fastwrite (sock_type *s, const BYTE *data, int len)
03023 {
03024   SIO_TRACE (("sock_fastwrite"));
03025
03026   switch (s->udp.ip_type)
03027   {
03028     case UDP_PROTO:
03029          len = min ((int)(_mtu - UDP_OVERHEAD), len);
03030          len = udp_write (&s->udp, data, len);
03031          return (len < 0 ? 0 : len);
03032
03033 #if !defined(USE_UDP_ONLY)
03034     case TCP_PROTO:
03035          len = tcp_write (&s->tcp, data, len);
03036          return (len < 0 ? 0 : len);
03037 #endif
03038   }
03039   return (0);
03040 }
03041
03048 int sock_enqueue (sock_type *s, const BYTE *data, int len)
03049 {
03050   SIO_TRACE (("sock_enqueue"));
03051
03052   if (len <= 0)
03053      return (0);
03054
03055   if (s->udp.ip_type == UDP_PROTO)
03056   {
03057     int written = 0;
03058     int total   = 0;
03059     do
03060     {
03061       len = min ((int)(_mtu - UDP_OVERHEAD), len);
03062       written = udp_write (&s->udp, data, len);
03063       if (written < 0)
03064       {
03065         s->udp.err_msg = _LANG ("Tx Error");
03066         break;
03067       }
03068       data  += written;
03069       len   -= written;
03070       total += written;
03071     }
03072     while (len > 0);
03073     return (total);
03074   }
03075
03076 #if !defined(USE_UDP_ONLY)
03077   if (s->tcp.ip_type == TCP_PROTO)
03078   {
03079     s->tcp.tx_queue    = data;
03080     s->tcp.tx_queuelen = len;
03081     s->tcp.tx_datalen  = len;
03082     return TCP_SEND (&s->tcp);
03083   }
03084 #endif
03085   return (0);
03086 }
03087
03088 #if !defined(USE_UDP_ONLY)
03089
03092 void sock_noflush (sock_type *s)
03093 {
03094   SIO_TRACE (("sock_noflush"));
03095
03096   if (s->tcp.ip_type == TCP_PROTO)
03097   {
03098     s->tcp.flags &= ~tcp_FlagPUSH;
03099     s->tcp.sockmode |= SOCK_MODE_LOCAL;
03100   }
03101 }
03102
03107 void sock_flush (sock_type *s)
03108 {
03109   SIO_TRACE (("sock_flush"));
03110
03111   if (s->tcp.ip_type == TCP_PROTO)
03112   {
03113     _tcp_Socket *tcp = &s->tcp;
03114
03115     tcp->sockmode &= ~SOCK_MODE_LOCAL;
03116     if (tcp->tx_datalen > 0)
03117     {
03118       tcp->flags |= tcp_FlagPUSH;
03119       if (s->tcp.send_una == 0)  /* !! S. Lawson - only if data not moving */
03120          TCP_SEND (tcp);
03121     }
03122   }
03123 }
03124
03128 void sock_flushnext (sock_type *s)
03129 {
03130   SIO_TRACE (("sock_flushnext"));
03131
03132   if (s->tcp.ip_type == TCP_PROTO)
03133   {
03134     s->tcp.flags |= tcp_FlagPUSH;
03135     s->tcp.sockmode &= ~SOCK_MODE_LOCAL;
03136   }
03137 }
03138 #endif  /* !USE_UDP_ONLY */
03139
03143 int sock_close (sock_type *s)
03144 {
03145   SIO_TRACE (("sock_close"));
03146
03147   switch (s->tcp.ip_type)
03148   {
03149     case UDP_PROTO:
03150          udp_close (&s->udp);
03151          break;
03152
03153 #if !defined(USE_UDP_ONLY)
03154     case TCP_PROTO:
03155          _tcp_close (&s->tcp);
03156          tcp_tick (s);
03157          break;
03158 #endif
03159   }
03160   return (0);
03161 }
03162
03167 static struct {
03168        void (*func)(void);
03169        BOOL   running;       /* to prevent reentry */
03170      } daemon [MAX_DAEMONS];
03171
03176 static void run_daemons (void)
03177 {
03178   int i;
03179
03180   for (i = 0; i < DIM(daemon); i++)
03181       if (daemon[i].func && !daemon[i].running)
03182       {
03183         TCP_CONSOLE_MSG (3, ("Running daemon %d (%p)\n", i, daemon[i].func));
03184         daemon[i].running = TRUE;
03185         (*daemon[i].func)();
03186         daemon[i].running = FALSE;
03187       }
03188 }
03189
03193 int addwattcpd (void (*func)(void))
03194 {
03195   int i;
03196
03197   for (i = 0; i < DIM(daemon); i++)
03198       if (!daemon[i].func)
03199       {
03200         daemon[i].func    = func;
03201         daemon[i].running = FALSE;
03202         return (1);
03203       }
03204   return (0);    /* didn't find a free slot */
03205 }
03206
03210 int delwattcpd (void (*func)(void))
03211 {
03212   int i;
03213
03214   for (i = 0; i < MAX_DAEMONS; i++)
03215       if (func == daemon[i].func)
03216       {
03217         daemon[i].func    = NULL;
03218         daemon[i].running = FALSE;
03219         return (1);
03220       }
03221   return (0);    /* didn't find the daemon */
03222 }
03223
03224 #if !defined(USE_UDP_ONLY)
03225
03238 static struct tcp_rtt rtt_cache [RTTCACHE];
03239
03240 void tcp_rtt_add (const _tcp_Socket *s, UINT rto, UINT MTU)
03241 {
03242   struct tcp_rtt *rtt;
03243   DWORD  addr = s->hisaddr;
03244
03245   SIO_TRACE (("tcp_rtt_add"));
03246
03247   if (~addr & ~sin_mask)  /* 0.0.0.0 or broadcast addresses? */
03248      return;
03249
03250   rtt = &rtt_cache [(WORD)addr % RTTCACHE];
03251
03252   /* Cache-slot is vacant or we're updating previous RTO
03253    * for same peer
03254    */
03255   if (!rtt->ip || rtt->ip == addr)
03256   {
03257     rtt->ip  = addr;
03258     rtt->rto = rto;
03259     rtt->MTU = MTU;
03260     STAT (tcpstats.tcps_cachedrtt++);
03261   }
03262 }
03263
03264 BOOL tcp_rtt_get (const _tcp_Socket *s, UINT *rto, UINT *MTU)
03265 {
03266   struct tcp_rtt *rtt = &rtt_cache [(WORD)s->hisaddr % RTTCACHE];
03267
03268   SIO_TRACE (("tcp_rtt_get"));
03269
03270   STAT (tcpstats.tcps_segstimed++);
03271
03272   if (s->hisaddr && rtt->ip == s->hisaddr && rtt->rto > 0)
03273   {
03274 #if defined(USE_DEBUG) && !defined(_MSC_VER) /* MSC6 crashes below */
03275     dbug_printf ("\nRTT-cache: host %s: %ss\n\n",
03276                  _inet_ntoa(NULL, rtt->ip), time_str(rtt->rto));
03277 #endif
03278
03279     STAT (tcpstats.tcps_usedrtt++);
03280     if (rto)
03281        *rto = rtt->rto;
03282     if (MTU)
03283        *MTU = rtt->MTU;
03284     return (TRUE);
03285   }
03286   return (FALSE);
03287 }
03288
03289 void tcp_rtt_clr (const _tcp_Socket *s)
03290 {
03291   struct tcp_rtt *rtt = &rtt_cache [(WORD)s->hisaddr % RTTCACHE];
03292
03293   if (s->hisaddr && rtt->ip == s->hisaddr)
03294   {
03295     rtt->ip  = 0;
03296     rtt->rto = 0;
03297     rtt->MTU = 0;
03298   }
03299 }
03300 #endif /* !USE_UDP_ONLY */
Generated on Wed Jan 25 15:42:38 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/PCTCP.H Source File

SRC/PCTCP.H

Go to the documentation of this file.
00001
00003 #ifndef _w32_PCTCP_H
00004 #define _w32_PCTCP_H
00005
00010 #define tcp_TIMEOUT       13000UL            /* timeout during a connection */
00011 #define tcp_LONGTIMEOUT  (1000UL*sock_delay) /* timeout for open */
00012 #define tcp_LASTACK_TIME  10000     /* timeout in the LASTACK state added AGW 5th Jan 2001 */
00013
00014 #define DEF_OPEN_TO       1000UL    /* # of msec in tcp-open (<=3s; RFC1122) */
00015 #define DEF_CLOSE_TO      1000UL    /* # of msec for CLOSEWT state */
00016 #define DEF_RTO_ADD       100UL     /* # of msec delay in RTT increment */
00017 #define DEF_RTO_BASE      10UL      /* # of msec in RTO recalculation */
00018 #define DEF_RTO_SCALE     64        /* RTO scale factor in _tcp_sendsoon() */
00019 #define DEF_RST_TIME      100UL     /* # of msec before sending RST */
00020 #define DEF_RETRAN_TIME   10UL      /* do retransmit logic every 10ms */
00021 #define DEF_RECV_WIN     (16*1024)  /* default receive window, 16kB */
00022 #define MAX_DAEMONS       20        /* max # of background daemons */
00023 #define DAEMON_PERIOD     500       /* run daemons every 500msec */
00024
00025
00026 /*
00027  * S. Lawson - define a short TIME_WAIT timeout. It should be from
00028  * .5 to 4 minutes (2MSL) but it's not really practical for us.
00029  * 2 secs will hopefully handle the case where ACK must be retransmitted,
00030  * but can't protect future connections on the same port from old packets.
00031  */
00032 #define tcp_TIMEWT_TO 2000UL
00033
00034 #ifndef __NETINET_TCP_SEQ_H
00035
00043   #define SEQ_LT(a,b)            ((long)((a) - (b)) < 0)
00044   #define SEQ_LEQ(a,b)           ((long)((a) - (b)) <= 0)
00045   #define SEQ_GT(a,b)            ((long)((a) - (b)) > 0)
00046   #define SEQ_GEQ(a,b)           ((long)((a) - (b)) >= 0)
00047   #define SEQ_BETWEEN(seq,lo,hi) ((seq - lo) <= (hi - lo))
00048                               /* (SEG_GEQ(seq,lo) && SEG_LEQ(seq,hi)) */
00049 #endif
00050
00057 #define INIT_SEQ()  intel (Random(1,0xFFFFFFFF)) /* intel (set_timeout(1)) */
00058
00062 #define DEF_MAX_VJSA    60000U
00063 #define DEF_MAX_VJSD    20000U
00064 #define INIT_VJSA       220
00065
00069 #define TCPOPT_EOL        0
00070 #define TCPOPT_NOP        1
00071 #define TCPOPT_MAXSEG     2
00072 #define TCPOPT_WINDOW     3
00073 #define TCPOPT_SACK_PERM  4
00074 #define TCPOPT_SACK       5
00075 #define TCPOPT_ECHO       6
00076 #define TCPOPT_ECHOREPLY  7
00077 #define TCPOPT_TIMESTAMP  8
00078 #define TCPOPT_CC         11
00079 #define TCPOPT_CCNEW      12
00080 #define TCPOPT_CCECHO     13
00081 #define TCPOPT_CHKSUM_REQ 14
00082 #define TCPOPT_CHKSUM_DAT 15
00083 #define TCPOPT_SIGNATURE  19
00084 #define   TCPOPT_SIGN_LEN 16
00085
00086 #define TCP_MAX_WINSHIFT  14
00093 #define MSS_MAX     (_mtu - TCP_OVERHEAD)
00094 #define MSS_MIN     (576 - TCP_OVERHEAD)
00095 #define MSS_REDUCE  20   /* do better than this (exponentially decrease) */
00096
00097 #define my_ip_addr      NAMESPACE (my_ip_addr)
00098 #define sin_mask        NAMESPACE (sin_mask)
00099 #define block_tcp       NAMESPACE (block_tcp)
00100 #define block_udp       NAMESPACE (block_udp)
00101 #define block_ip        NAMESPACE (block_ip)
00102 #define block_icmp      NAMESPACE (block_icmp)
00103 #define use_rand_lport  NAMESPACE (use_rand_lport)
00104
00105 #define hostname        NAMESPACE (hostname)
00106 #define _mtu            NAMESPACE (_mtu)
00107 #define _mss            NAMESPACE (_mss)
00108 #define mtu_discover    NAMESPACE (mtu_discover)
00109 #define mtu_blackhole   NAMESPACE (mtu_blackhole)
00110 #define tcp_nagle       NAMESPACE (tcp_nagle)
00111 #define tcp_keep_idle   NAMESPACE (tcp_keep_idle)
00112 #define tcp_keep_intvl  NAMESPACE (tcp_keep_intvl)
00113 #define tcp_max_idle    NAMESPACE (tcp_max_idle)
00114 #define tcp_opt_ts      NAMESPACE (tcp_opt_ts)
00115 #define tcp_opt_sack    NAMESPACE (tcp_opt_sack)
00116 #define tcp_opt_wscale  NAMESPACE (tcp_opt_wscale)
00117 #define tcp_recv_win    NAMESPACE (tcp_recv_win)
00118
00119 W32_DATA unsigned _mtu, _mss;
00120 W32_DATA DWORD    my_ip_addr;
00121 W32_DATA DWORD    sin_mask;
00122 W32_DATA BOOL     block_tcp;
00123 W32_DATA BOOL     block_udp;
00124 W32_DATA BOOL     block_icmp;
00125 W32_DATA BOOL     block_ip;
00126 W32_DATA unsigned tcp_keep_idle, tcp_keep_intvl, tcp_max_idle;
00127 W32_DATA char     hostname [MAX_HOSTLEN+1];
00128
00129 extern BOOL mtu_discover;
00130 extern BOOL mtu_blackhole;
00131 extern BOOL use_rand_lport;
00132 extern BOOL tcp_nagle;
00133 extern BOOL tcp_opt_ts;
00134 extern BOOL tcp_opt_sack;
00135 extern BOOL tcp_opt_wscale;
00136
00137 extern _tcp_Socket *_tcp_allsocs;
00138 extern _udp_Socket *_udp_allsocs;
00139
00140 /* Same as in <tcp.h>
00141  */
00142 #define sock_wait_established(s,seconds,fn,statusptr) \
00143         do {                                          \
00144            if (_ip_delay0 (s,seconds,fn,statusptr))   \
00145               goto sock_err;                          \
00146         } while (0)
00147
00148 #define sock_wait_input(s,seconds,fn,statusptr)       \
00149         do {                                          \
00150            if (_ip_delay1 (s,seconds,fn,statusptr))   \
00151               goto sock_err;                          \
00152         } while (0)
00153
00154 #define sock_wait_closed(s,seconds,fn,statusptr)      \
00155         do {                                          \
00156            if (_ip_delay2(s,seconds,fn,statusptr))    \
00157               goto sock_err;                          \
00158         } while (0)
00159
00160 #define sock_tick(s, statusptr)                       \
00161         do {                                          \
00162            if (!tcp_tick(s)) {                        \
00163               if (statusptr) *statusptr = 1;          \
00164               goto sock_err;                          \
00165            }                                          \
00166         } while (0)
00167
00168
00169 extern void _udp_cancel (const in_Header*, int, int, const char *, const void *);
00170 extern void _tcp_cancel (const in_Header*, int, int, const char *, const void *);
00171
00172 extern void _tcp_close    (_tcp_Socket *s);
00173 extern void  tcp_rtt_add  (const _tcp_Socket *s, UINT rto, UINT MTU);
00174 extern void  tcp_rtt_clr  (const _tcp_Socket *s);
00175 extern BOOL  tcp_rtt_get  (const _tcp_Socket *s, UINT *rto, UINT *MTU);
00176
00177 extern int   tcp_established (const _tcp_Socket *s);
00178 extern int  _tcp_send        (_tcp_Socket *s, char *file, unsigned line);
00179 extern int  _tcp_sendsoon    (_tcp_Socket *s, char *file, unsigned line);
00180 extern int  _tcp_keepalive   (_tcp_Socket *s);
00181
00182 extern void tcp_Retransmitter (BOOL force);
00183
00184 extern _udp_Socket *_udp_handler  (const in_Header *ip, BOOL broadcast);
00185 extern _tcp_Socket *_tcp_handler  (const in_Header *ip, BOOL broadcast);
00186 extern _tcp_Socket *_tcp_unthread (_tcp_Socket *s, BOOL free_tx);
00187 extern _tcp_Socket *_tcp_abort    (_tcp_Socket *s, const char *file, unsigned line);
00188 extern int          _tcp_send_reset (_tcp_Socket *s, const in_Header *ip,
00189                                      const tcp_Header *tcp, const char *file,
00190                                      unsigned line);
00191
00192 #define TCP_SEND(s)     _tcp_send     (s, __FILE__, __LINE__)
00193 #define TCP_SENDSOON(s) _tcp_sendsoon (s, __FILE__, __LINE__)
00194 #define TCP_ABORT(s)    _tcp_abort    (s, __FILE__, __LINE__)
00195
00196 #define TCP_SEND_RESET(s, ip, tcp) \
00197        _tcp_send_reset(s, ip, tcp, __FILE__, __LINE__)
00198
00199 /*
00200  * Public API
00201  */
00202 W32_DATA unsigned tcp_OPEN_TO;  /* these are really not publics (but tcpinfo needs them) */
00203 W32_DATA unsigned tcp_CLOSE_TO;
00204 W32_DATA unsigned tcp_RTO_ADD;
00205 W32_DATA unsigned tcp_RTO_BASE;
00206 W32_DATA unsigned tcp_RTO_SCALE;
00207 W32_DATA unsigned tcp_RST_TIME;
00208 W32_DATA unsigned tcp_RETRAN_TIME;
00209 W32_DATA unsigned tcp_MAX_VJSA;
00210 W32_DATA unsigned tcp_MAX_VJSD;
00211 W32_DATA DWORD    tcp_recv_win;
00212
00213 W32_FUNC WORD tcp_tick   (sock_type *s);
00214 W32_FUNC int  tcp_open   (_tcp_Socket *s, WORD lport, DWORD ina, WORD port, ProtoHandler handler);
00215 W32_FUNC int  tcp_listen (_tcp_Socket *s, WORD lport, DWORD ina, WORD port, ProtoHandler handler, WORD timeout);
00216 W32_FUNC int  udp_open   (_udp_Socket *s, WORD lport, DWORD ina, WORD port, ProtoHandler handler);
00217 W32_FUNC int  udp_listen (_udp_Socket *s, WORD lport, DWORD ina, WORD port, ProtoHandler handler);
00218 W32_FUNC void udp_SetTTL (_udp_Socket *s, BYTE ttl);
00219
00220 W32_FUNC void   sock_abort     (sock_type *s);
00221 W32_FUNC int    sock_read      (sock_type *s, BYTE *dp, int len);
00222 W32_FUNC int    sock_fastread  (sock_type *s, BYTE *dp, int len);
00223 W32_FUNC int    sock_write     (sock_type *s, const BYTE *dp, int len);
00224 W32_FUNC int    sock_fastwrite (sock_type *s, const BYTE *dp, int len);
00225 W32_FUNC int    sock_enqueue   (sock_type *s, const BYTE *dp, int len);
00226 W32_FUNC void   sock_noflush   (sock_type *s);
00227 W32_FUNC void   sock_flush     (sock_type *s);
00228 W32_FUNC void   sock_flushnext (sock_type *s);
00229 W32_FUNC BYTE   sock_putc      (sock_type *s, BYTE c);
00230 W32_FUNC int    sock_getc      (sock_type *s);
00231 W32_FUNC int    sock_puts      (sock_type *s, const BYTE *dp);
00232 W32_FUNC int    sock_gets      (sock_type *s, BYTE *dp, int n);
00233 W32_FUNC WORD   sock_dataready (sock_type *s);
00234 W32_FUNC int    sock_close     (sock_type *s);
00235 W32_FUNC void (*sock_yield     (_tcp_Socket *s, void (*fn)(void))) (void);
00236 W32_FUNC WORD   sock_mode      (sock_type *s, WORD mode);
00237 W32_FUNC int    sock_sselect   (const sock_type *s, int state);
00238 W32_FUNC int    sock_keepalive (sock_type *s);
00239 W32_FUNC int    addwattcpd     (void (*p)(void));
00240 W32_FUNC int    delwattcpd     (void (*p)(void));
00241
00242 W32_FUNC int MS_CDECL sock_printf (sock_type *s, const char *fmt, ...)
00243                       ATTR_PRINTF (2,3);
00244
00245 W32_FUNC int MS_CDECL sock_scanf (sock_type *s, const char *fmt, ...)
00246                       ATTR_SCANF (2,3);
00247
00248 #define SET_ERR_MSG(s, msg) \
00249         do { \
00250           if (!s->err_msg && msg) \
00251              s->err_msg = StrLcpy (s->err_buf, msg, sizeof(s->err_buf)); \
00252         } while (0)
00253
00258 struct tcp_rtt {
00259        DWORD  ip;
00260        UINT   rto;
00261        UINT   MTU;
00262      };
00263
00264 #define RTTCACHE  16
00267 #if defined(USE_BSD_API)
00268   /*
00269    * Operations for the '_bsd_socket_hook'.
00270    */
00271   enum BSD_SOCKET_OPS {
00272        BSO_FIND_SOCK = 1,   /* return a 'Socket*' from '_tcp_Socket*' */
00273        BSO_SYN_CALLBACK,    /* called on SYN received */
00274        BSO_RST_CALLBACK,    /* called on RST received */
00275        BSO_IP4_RAW,         /* called on IPv4 input. */
00276        BSO_IP6_RAW,         /* called on IPv6 input. */
00277        BSO_DEBUG,           /* called to perform SO_DEBUG stuff */
00278      };
00279
00280   extern void * (MS_CDECL *_bsd_socket_hook) (enum BSD_SOCKET_OPS op, ...);
00281 #endif
00282
00283
00284 /* In ports.c
00285  */
00286 extern WORD  init_localport  (void);
00287 extern WORD  find_free_port  (WORD oldport, BOOL sleep_msl);
00288 extern int   grab_localport  (WORD port);
00289 extern int   reuse_localport (WORD port);
00290 extern int   maybe_reuse_localport (_tcp_Socket *s);
00291
00292 /* In sock_in.c
00293  */
00294 W32_FUNC void  ip_timer_init    (sock_type *s, unsigned);
00295 W32_FUNC int   ip_timer_expired (const sock_type *s);
00296 W32_FUNC int  _ip_delay0        (sock_type *, int, UserHandler, int *);
00297 W32_FUNC int  _ip_delay1        (sock_type *, int, UserHandler, int *);
00298 W32_FUNC int  _ip_delay2        (sock_type *, int, UserHandler, int *);
00299 W32_FUNC int   sock_timeout     (sock_type *, int);
00300 W32_FUNC int   sock_established (sock_type *);
00301
00302 #endif
Generated on Wed Jan 25 15:42:38 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/POLL.C Source File

SRC/POLL.C

Go to the documentation of this file.
00001
00005 /*  BSD sockets functionality for Waterloo TCP/IP
00006  *
00007  *  Copyright (c) 1997-2002 Gisle Vanem <giva@bgnett.no>
00008  *
00009  *  Redistribution and use in source and binary forms, with or without
00010  *  modification, are permitted provided that the following conditions
00011  *  are met:
00012  *  1. Redistributions of source code must retain the above copyright
00013  *     notice, this list of conditions and the following disclaimer.
00014  *  2. Redistributions in binary form must reproduce the above copyright
00015  *     notice, this list of conditions and the following disclaimer in the
00016  *     documentation and/or other materials provided with the distribution.
00017  *  3. All advertising materials mentioning features or use of this software
00018  *     must display the following acknowledgement:
00019  *       This product includes software developed by Gisle Vanem
00020  *       Bergen, Norway.
00021  *
00022  *  THIS SOFTWARE IS PROVIDED BY ME (Gisle Vanem) AND CONTRIBUTORS ``AS IS''
00023  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00024  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00025  *  ARE DISCLAIMED.  IN NO EVENT SHALL I OR CONTRIBUTORS BE LIABLE FOR ANY
00026  *  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00027  *  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00028  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00029  *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00030  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00031  *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00032  *
00033  *  Version
00034  *
00035  *  1.0 : Sep 3, 1999 : G. Vanem
00036  *
00037  *  This function is not in BSD, but Linux-specific (to aid
00038  *  porting Linux applications to Watt-32).
00039  *
00040  *  poll() taken from HTTP-tunnel:
00041  *
00042  *  Copyright (C) 1999 Lars Brinkhoff <lars@nocrew.org>.
00043  *
00044  */
00045
00046 #include <sys/poll.h>
00047 #include "socket.h"
00048
00049 #if defined(USE_BSD_API)
00050
00051 #undef read
00052 #undef write
00053 #undef except
00054
00055 #ifdef __HIGHC__     /* set warning for stack-usage */
00056 #pragma stack_size_warn (16000)    /* ~3*MAX_SOCKETS */
00057 #endif
00058
00059 int poll (struct pollfd *p, int num, int timeout)
00060 {
00061   struct timeval tv;
00062   fd_set read  [NUM_SOCK_FDSETS];
00063   fd_set write [NUM_SOCK_FDSETS];
00064   fd_set except[NUM_SOCK_FDSETS];
00065   int    i, n, ret;
00066
00067   memset (read, 0, sizeof(read));
00068   memset (write, 0, sizeof(write));
00069   memset (except, 0, sizeof(except));
00070
00071   SOCK_DEBUGF (("\npoll: num %d, to %d", num, timeout));
00072   SOCK_ENTER_SCOPE();
00073
00074   if (num > MAX_SOCKETS)
00075   {
00076     SOCK_DEBUGF ((", EINVAL"));
00077     SOCK_ERRNO (EINVAL);
00078     return (-1);
00079   }
00080
00081   n = -1;
00082   for (i = 0; i < num; i++)
00083   {
00084     if (p[i].fd < 0)
00085        continue;
00086     if (p[i].events & POLLIN)
00087        FD_SET (p[i].fd, &read[0]);
00088     if (p[i].events & POLLOUT)
00089        FD_SET (p[i].fd, &write[0]);
00090     if (p[i].events & POLLERR)
00091        FD_SET (p[i].fd, &except[0]);
00092     if (p[i].fd > n)
00093        n = p[i].fd;
00094   }
00095
00096   if (n == -1)
00097      ret = 0;
00098
00099   else if (timeout < 0)
00100      ret = select_s (n+1, read, write, except, NULL);
00101
00102   else
00103   {
00104     tv.tv_sec  = timeout / 1000;
00105     tv.tv_usec = 1000 * (timeout % 1000);
00106     ret = select_s (n+1, read, write, except, &tv);
00107   }
00108
00109   for (i = 0; ret >= 0 && i < num; i++)
00110   {
00111     p[i].revents = 0;
00112     if (FD_ISSET (p[i].fd, &read[0]))
00113        p[i].revents |= POLLIN;
00114     if (FD_ISSET (p[i].fd, &write[0]))
00115        p[i].revents |= POLLOUT;
00116     if (FD_ISSET (p[i].fd, &except[0]))
00117        p[i].revents |= POLLERR;
00118   }
00119
00120   SOCK_DEBUGF (("\nrc %d", ret));
00121   SOCK_LEAVE_SCOPE();
00122   return (ret);
00123 }
00124 #endif /* USE_BSD_API */
Generated on Wed Jan 25 15:42:38 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/PORTS.C Source File

SRC/PORTS.C

Go to the documentation of this file.
00001
00008 #include <stdio.h>
00009 #include <stdlib.h>
00010 #include <limits.h>
00011
00012 #include "copyrigh.h"
00013 #include "wattcp.h"
00014 #include "strings.h"
00015 #include "misc.h"
00016 #include "pctcp.h"
00017
00018 #if (DOSX)
00019   #define MAX_PORT  USHRT_MAX
00020 #else
00021   #define MAX_PORT  5000
00022 #endif
00023
00024 #define MIN_PORT    1025
00025 #define NUM_FD_SETS (1 + (MAX_PORT / (8*sizeof(fd_set))))
00026
00027 int    use_rand_lport = TRUE;
00028 static fd_set *lport_inuse;
00029
00033 static void exit_localport (void)
00034 {
00035   if (!_watt_fatal_error && lport_inuse)
00036      free (lport_inuse);
00037   lport_inuse = NULL;
00038 }
00039
00046 WORD init_localport (void)
00047 {
00048   size_t size = sizeof(fd_set) * NUM_FD_SETS;
00049
00050   lport_inuse = calloc (size, 1);
00051   if (!lport_inuse)
00052      return (0);
00053
00054   RUNDOWN_ADD (exit_localport, 303);
00055   return (MAX_PORT);
00056 }
00057
00058 /*
00059  * Return unused local port
00060  *  - port = 0 -> normal port,
00061  *  - port = 1 -> special port (513-1023)
00062  *
00063  * `linger' is set if port shall be matched against "sleeping" ports.
00064  * Local tcp-ports should not be reused 60sec (2*MSL?) after they have
00065  * been closed. Note this is NOT related to sock_delay.
00066  */
00067 WORD find_free_port (WORD port, BOOL linger)
00068 {
00069   WORD p, lo_port, hi_port;
00070
00071   if (port > 0 && port < USHRT_MAX)    /* return port as-is */
00072      return (port);
00073
00074   if (port == 0)
00075   {
00076     if (use_rand_lport)
00077          lo_port = Random (MIN_PORT, 1500);
00078     else lo_port = MIN_PORT;
00079   }
00080   else
00081     lo_port = 513;
00082
00083   hi_port = MAX_PORT;   /* our empherical max-port */
00084
00085   for (p = lo_port; p < hi_port; p++)
00086   {
00087     if (linger && FD_ISSET(p,lport_inuse)) /* inuse, try next */
00088        continue;
00089
00090     if (_udp_allsocs)
00091     {
00092       const _udp_Socket *udp = _udp_allsocs;
00093
00094       while (udp->next && udp->myport != p)
00095              udp = udp->next;
00096       if (udp->myport == p)
00097          continue;
00098     }
00099 #if !defined(USE_UDP_ONLY)
00100     if (_tcp_allsocs)
00101     {
00102       const _tcp_Socket *tcp = _tcp_allsocs;
00103
00104       while (tcp->next && tcp->myport != p)
00105              tcp = tcp->next;
00106       if (tcp->myport == p)
00107          continue;
00108     }
00109 #endif
00110     break;
00111   }
00112   FD_SET (p, lport_inuse);
00113   return (p);
00114 }
00115
00116 #if defined(USE_BSD_API)
00117 /*
00118  * Set the "lport_inuse" bit for a local port.
00119  * 'port' is in host order.
00120  * Returns original state or -1 if port above our range.
00121  */
00122 int grab_localport (WORD port)
00123 {
00124   int rc;
00125
00126 #if (MAX_PORT < USHRT_MAX)
00127   if (port > MAX_PORT)
00128      return (-1);
00129 #endif
00130
00131   if (!lport_inuse)
00132      return (-1);
00133
00134   rc = FD_ISSET (port, lport_inuse);
00135   FD_SET (port, lport_inuse);
00136   return (rc);
00137 }
00138 #endif
00139
00140 /*
00141  * Clear the "lport_inuse" bit for a local port.
00142  * 'port' is in host order. Port 0 is not considered a port.
00143  * Returns original state or -1 if port above our range.
00144  */
00145 int reuse_localport (WORD port)
00146 {
00147   int rc;
00148
00149 #if (MAX_PORT < USHRT_MAX)
00150   if (port > MAX_PORT)
00151      return (-1);
00152 #endif
00153
00154   if (!lport_inuse)
00155      return (-1);
00156
00157   rc = FD_ISSET (port, lport_inuse);
00158   FD_CLR (port, lport_inuse);
00159   return (rc);
00160 }
00161
00162 #if !defined(USE_UDP_ONLY)
00163 /*
00164  * Reuse local port now if not owned by a STREAM-socket.
00165  * Otherwise let socket daemon free local port when linger period
00166  * expires. We don't care about rapid reuse of local ports associated
00167  * with DGRAM-sockets.
00168  */
00169 int maybe_reuse_localport (_tcp_Socket *s)
00170 {
00171 #if defined(USE_BSD_API)
00172   if (!_bsd_socket_hook || !(*_bsd_socket_hook)(BSO_FIND_SOCK,s))
00173      return reuse_localport (s->myport);
00174   return (0);
00175 #else
00176   return reuse_localport (s->myport);
00177 #endif
00178 }
00179 #endif /* USE_UDP_ONLY */
Generated on Wed Jan 25 15:42:38 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/POWERPAK.C Source File

SRC/POWERPAK.C

Go to the documentation of this file.
00001
00015 #include <stdio.h>
00016 #include <stdlib.h>
00017 #include <string.h>
00018
00019 #include "wattcp.h"
00020 #include "printk.h"
00021 #include "misc.h"
00022 #include "wdpmi.h"
00023 #include "powerpak.h"
00024
00025 #if (DOSX & POWERPAK) && defined(BORLAND386)
00026
00027 extern int _ostype;
00028
00029 /* Don't include <windows.h> because of conflicting types etc.
00030  */
00031 #define WINAPI __stdcall __import
00032
00033 extern void * WINAPI GetModuleHandleA (const char *module);
00034 extern void * WINAPI GetProcAddress (void *module, const char *func);
00035
00036 /* these are missing in Win32, damn...
00037  */
00038 static UINT (WINAPI* _AllocSelector) (UINT);
00039 static UINT (WINAPI* _FreeSelector) (UINT);
00040
00041 BOOL powerpak_init (void)
00042 {
00043   void *mod;
00044
00045   if (_ostype == 2)  /* plain DOS */
00046      return (TRUE);
00047
00048   mod = GetModuleHandleA ("kernel32.dll");
00049   if (!mod)
00050      return (FALSE);
00051
00052   _AllocSelector = (UINT (WINAPI*)(UINT)) GetProcAddress (mod, "AllocSelector");
00053   _FreeSelector  = (UINT (WINAPI*)(UINT)) GetProcAddress (mod, "FreeSelector");
00054   return (_AllocSelector && _FreeSelector);
00055 }
00056
00057 WORD dpmi_create_dos_selector (void)
00058 {
00059   WORD sel;
00060
00061   if (_ostype != 2)   /* Not plain DOS */
00062      return (*_AllocSelector) (0);
00063
00064   __dpmi_errno = 0;
00065   _EAX = 0;       /* DPMI 0: create selector */
00066   _ECX = 1;
00067   geninterrupt (0x31);
00068   if (_FLAGS & CARRY_BIT)
00069   {
00070     __dpmi_errno = _AX;
00071     return (0);
00072   }
00073   sel = _AX;
00074   _EAX = 8;       /* DPMI 8: set limit 1MByte */
00075   _BX = sel;
00076   _CX = 0x0F;
00077   _DX = 0xFFFF;
00078   geninterrupt (0x31);
00079   if (_FLAGS & CARRY_BIT)
00080   {
00081     __dpmi_errno = _AX;
00082     return (0);
00083   }
00084   return (sel);
00085 }
00086
00087 int dpmi_free_dos_selector (WORD sel)
00088 {
00089   if (_ostype != 2)  /* Not plain DOS */
00090      return (*_FreeSelector) (sel);
00091
00092   __dpmi_errno = 0;
00093   _EAX = 1;
00094   _BX  = sel;
00095   geninterrupt (0x31);
00096   if (_FLAGS & CARRY_BIT)
00097   {
00098     __dpmi_errno = _AX;
00099     return (0);
00100   }
00101   return (1);
00102 }
00103
00104 void ReadRealMem (void *dst, REALPTR rp, unsigned size)
00105 {
00106   DWORD lin = (RP_SEG(rp) << 4) + RP_OFF(rp);
00107
00108   __asm {
00109     push ds
00110     push edi
00111     push esi
00112     mov  ds, _watt_dos_ds
00113     mov  esi, lin
00114     mov  edi, dst
00115     mov  ecx, size
00116     shr  ecx, 2
00117     cld
00118     db   0F3h, 0A5h   /* rep movsd */
00119     mov  ecx, size
00120     and  ecx, 3
00121     rep  movsb        /* move rest */
00122     pop  esi
00123     pop  edi
00124     pop  ds
00125   }
00126 }
00127
00128 void WriteRealMem (REALPTR rp, const void *src, int size)
00129 {
00130   DWORD lin = (RP_SEG(rp) << 4) + RP_OFF(rp);
00131
00132   __asm {
00133     push es
00134     push edi
00135     push esi
00136     mov  es, _watt_dos_ds
00137     mov  edi, lin
00138     mov  esi, src
00139     mov  ecx, size
00140     shr  ecx, 2
00141     cld
00142     db   0F3h, 0A5h   /* rep movsd */
00143     mov  ecx, size
00144     and  ecx, 3
00145     rep  movsb        /* move rest */
00146     pop  esi
00147     pop  edi
00148     pop  es
00149   }
00150 }
00151
00152 BYTE _farpeekb (WORD sel, DWORD ofs)
00153 {
00154   __asm {
00155     push es
00156     mov  ax, sel
00157     mov  edx, ofs
00158     mov  es, ax
00159     mov  al, es:[edx]
00160     pop  es
00161   }
00162   return (_AL);
00163 }
00164
00165 WORD _farpeekw (WORD sel, DWORD ofs)
00166 {
00167   __asm {
00168     push es
00169     mov  ax, sel
00170     mov  edx, ofs
00171     mov  es, ax
00172     mov  ax, es:[edx]
00173     pop  es
00174   }
00175   return (_AX);
00176 }
00177
00178 DWORD _farpeekl (WORD sel, DWORD ofs)
00179 {
00180   __asm {
00181     push es
00182     mov  ax, sel
00183     mov  edx, ofs
00184     mov  es, ax
00185     mov  eax, es:[edx]
00186     pop  es
00187   }
00188   return (_EAX);
00189 }
00190
00191 void _farpokeb (WORD sel, DWORD ofs, BYTE val)
00192 {
00193   __asm {
00194     push es
00195     mov  ax, sel
00196     mov  edx, ofs
00197     mov  es, ax
00198     mov  al, val
00199     mov  es:[edx], al
00200     pop  es
00201   }
00202 }
00203
00204 void _farpokew (WORD sel, DWORD ofs, WORD val)
00205 {
00206   __asm {
00207     push es
00208     mov  ax, sel
00209     mov  edx, ofs
00210     mov  es, ax
00211     mov  ax, val
00212     mov  es:[edx], ax
00213     pop  es
00214   }
00215 }
00216
00217 void _farpokel (WORD sel, DWORD ofs, DWORD val)
00218 {
00219   __asm {
00220     push es
00221     mov  ax, sel
00222     mov  edx, ofs
00223     mov  es, ax
00224     mov  eax, val
00225     mov  es:[edx], eax
00226     pop  es
00227   }
00228 }
00229
00230 int dpmi_getvect (int intr, WORD *sel, DWORD *ofs)
00231 {
00232   __asm {
00233     push ebx
00234     push es
00235     mov  ah, 0x35
00236     mov  al, byte ptr intr
00237     int  0x21
00238     mov  ax, es
00239     pop  es
00240     mov  edx, sel
00241     mov  [edx], ax
00242     mov  edx, ofs
00243     mov  [edx], ebx
00244     pop  ebx
00245   }
00246   return (1);
00247 }
00248
00249 int dpmi_setvect (int intr, WORD sel, DWORD ofs)
00250 {
00251   __asm {
00252     push ds
00253     mov  edx, ofs
00254     mov  ax, sel
00255     mov  ds, ax
00256     mov  ah, 0x25
00257     mov  al, byte ptr intr
00258     int  0x21
00259     pop  ds
00260   }
00261   return (1);
00262 }
00263
00264 #if !defined(USE_FAST_PKT)
00265
00266 /* Some code below borrowed from djgpp, some heavily modified */
00267
00268 /* Copyright (C) 1999 DJ Delorie, see COPYING.DJ for details */
00269 /* Copyright (C) 1998 DJ Delorie, see COPYING.DJ for details */
00270 /* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
00271 /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
00272
00273 /* This code really can't be nested since the RMCB structure isn't copied,
00274  * so the stack check isn't really useful.  But someone may fix it someday.
00275  * On entry CS is known to be ours, ES is probably ours (since we passed it),
00276  * SS:ESP is locked 4K stack.  ES:EDI is regs structure, DS:ESI is RM SS:SP.
00277  * Do NOT enable interrupts in the user routine.  Thanks to ctm@ardi.com for
00278  * the improvements.  C. Sandmann 3/95
00279  */
00280
00281 #define FILL  0x00
00282
00283 static BYTE wrapper_code[] = {
00284 /* 00 */ 0x06,                          /*     push    es               */
00285 /* 01 */ 0x1E,                          /*     push    ds               */
00286 /* 02 */ 0x06,                          /*     push    es               */
00287 /* 03 */ 0x1F,                          /*     pop     ds               */
00288 /* 04 */ 0x66, 0xB8,                    /*     mov ax,                  */
00289 /* 06 */ FILL, FILL,                    /*         _our_selector        */
00290 /* 08 */ 0x8E, 0xD8,                    /*     mov ds, ax               */
00291 /* 0A */ 0xFF, 0x05,                    /*     incl                     */
00292 /* 0C */ FILL, FILL, FILL, FILL,        /*          _call_count         */
00293 /* 10 */ 0x83, 0x3D,                    /*     cmpl                     */
00294 /* 12 */ FILL, FILL, FILL, FILL,        /*         _in_this_handler     */
00295 /* 16 */ 0x00,                          /*         $0                   */
00296 /* 17 */ 0x75,                          /*     jne                      */
00297 /* 18 */ 0x33,                          /*         out                  */
00298 /* 19 */ 0xC6, 0x05,                    /*     movb                     */
00299 /* 1B */ FILL, FILL, FILL, FILL,        /*         _in_this_handler     */
00300 /* 1F */ 0x01,                          /*         $1                   */
00301 /* 20 */ 0x8E, 0xC0,                    /*     mov es, ax               */
00302 /* 22 */ 0x8E, 0xE0,                    /*     mov fs, ax               */
00303 /* 24 */ 0x8E, 0xE8,                    /*     mov gs, ax               */
00304 /* 26 */ 0xBB,                          /*     mov ebx,                 */
00305 /* 27 */ FILL, FILL, FILL, FILL,        /*         _local_stack         */
00306 /* 2B */ 0xFC,                          /*     cld                      */
00307 /* 2C */ 0x89, 0xE1,                    /*     mov ecx, esp             */
00308 /* 2E */ 0x8C, 0xD2,                    /*     mov dx, ss               */
00309 /* 30 */ 0x8E, 0xD0,                    /*     mov ss, ax               */
00310 /* 32 */ 0x89, 0xDC,                    /*     mov esp, ebx             */
00311 /* 34 */ 0x52,                          /*     push edx                 */
00312 /* 35 */ 0x51,                          /*     push ecx                 */
00313 /* 36 */ 0x56,                          /*     push esi                 */
00314 /* 37 */ 0x57,                          /*     push edi                 */
00315 /* 38 */ 0xE8,                          /*     call                     */
00316 /* 39 */ FILL, FILL, FILL, FILL,        /*         _rmcb                */
00317 /* 3D */ 0x5F,                          /*     pop edi                  */
00318 /* 3E */ 0x5E,                          /*     pop esi                  */
00319 /* 3F */ 0x58,                          /*     pop eax                  */
00320 /* 40 */ 0x5B,                          /*     pop ebx                  */
00321 /* 41 */ 0x8E, 0xD3,                    /*     mov ss, bx               */
00322 /* 43 */ 0x89, 0xC4,                    /*     mov esp, eax             */
00323 /* 45 */ 0xC6, 0x05,                    /*     movb                     */
00324 /* 47 */ FILL, FILL, FILL, FILL,        /*         _in_this_handler     */
00325 /* 4B */ 0x00,                          /*         $0                   */
00326 /* 4C */ 0x1F,                          /* out:pop ds                   */
00327 /* 4D */ 0x07,                          /*     pop es                   */
00328 /* 4E */ 0x8B, 0x06,                    /*     mov eax,[esi]            */
00329 /* 50 */ 0x26, 0x89, 0x47,0x2A,         /*     mov es:[edi+42],eax      */
00330 /* 54 */ 0x66, 0x26, 0x83,0x47,0x2E,4,  /* add     es:[edi+46],0x4      */
00331          0xCF                           /* iret                         */
00332        };
00333
00334 #define RMCB_STACK_SIZE (4*1024)
00335
00336 static REALPTR alloc_callback (void (*callback)(void), REAL_regs *regs)
00337 {
00338   __asm {   /* I had to use assembly here because int386x() crashed */
00339     mov  __dpmi_errno, 0
00340     push es
00341     push ds
00342     push edi
00343     push esi
00344     mov  ax, ds
00345
00346     mov  edi, regs
00347     mov  es, ax         /* ES:EDI = DS:regs */
00348
00349     mov  ax, cs
00350     mov  ds, ax
00351     mov  esi, callback  /* DS:ESI = CS:callback */
00352
00353     mov  ax, 303h
00354     int  31h
00355     pop  esi
00356     pop  edi
00357     pop  ds
00358     pop  es
00359     jc   fail:
00360   }
00361   return (_CX << 16) + _DX;
00362
00363 fail:
00364   __dpmi_errno = _AX;
00365   return (0);
00366 }
00367
00368 REALPTR dpmi_alloc_callback_retf (DPMI_callback *cb)
00369 {
00370   REALPTR rmcb;
00371   BYTE   *wrapper = calloc (sizeof(wrapper_code) + RMCB_STACK_SIZE, 1);
00372   BYTE   *stack   = wrapper + sizeof(wrapper_code);
00373
00374   if (!wrapper)
00375      return (0);
00376
00377   memcpy (wrapper, wrapper_code, sizeof(wrapper_code));
00378
00379   if (!dpmi_lock_region(&cb->rm_regs, sizeof(cb->rm_regs)) ||
00380       !dpmi_lock_region(wrapper, sizeof(wrapper_code) + RMCB_STACK_SIZE))
00381   {
00382     fprintf (stderr, "dpmi_lock_region: DPMI error %04Xh\n", __dpmi_errno);
00383     free (wrapper);
00384     free (stack);
00385     return (0);
00386   }
00387
00388   *(short*)(wrapper+0x06) = _DS;
00389   *(long*) (wrapper+0x0C) = (long) stack + 8;
00390   *(long*) (wrapper+0x12) = (long) stack + 4;
00391   *(long*) (wrapper+0x1B) = (long) stack + 4;
00392   *(long*) (wrapper+0x27) = (long) stack + RMCB_STACK_SIZE; /* !! was -4 */
00393   *(long*) (wrapper+0x39) = (long) cb->pm_func - ((long)wrapper + 0x3D);
00394   *(long*) (wrapper+0x47) = (long) stack + 4;
00395
00396   rmcb = alloc_callback ((void(*)(void))wrapper, &cb->rm_regs);
00397   if (!rmcb)
00398   {
00399     free (wrapper);
00400     fprintf (stderr, "dpmi_alloc_callback: DPMI error %04Xh\n", __dpmi_errno);
00401     return (0);
00402   }
00403   cb->wrapper = wrapper;
00404   cb->rm_addr = rmcb;
00405   return (1);
00406 }
00407
00408 int dpmi_free_callback_retf (DPMI_callback *cb)
00409 {
00410   union REGS r;
00411
00412   if (!cb || !cb->wrapper)
00413      return (0);
00414
00415   free (cb->wrapper);
00416   cb->wrapper = NULL;
00417   cb->pm_func = NULL;
00418
00419   __dpmi_errno = 0;
00420   r.w.ax = 0x304;
00421   r.w.cx = RP_SEG (cb->rm_addr);
00422   r.w.dx = RP_OFF (cb->rm_addr);
00423   int386 (0x31, &r, &r);
00424   if (r.w.cflag & 1)
00425   {
00426     __dpmi_errno = r.w.ax;
00427     return (0);
00428   }
00429   return (1);
00430 }
00431 #endif   /* USE_FAST_PKT */
00432 #endif   /* (DOSX & POWERPAK) && BORLAND386 */
00433
Generated on Wed Jan 25 15:42:38 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/POWERPAK.H Source File

SRC/POWERPAK.H

Go to the documentation of this file.
00001
00003 #ifndef _w32_POWERPAK_H
00004 #define _w32_POWERPAK_H
00005
00006 #if (DOSX & POWERPAK) && defined(BORLAND386)
00007
00008 #undef  REALPTR
00009 #define REALPTR             DWORD  /* segment in upper 16 bits */
00010 #define RP_SET(rp,ofs,seg)  (rp = ((DWORD)(seg) << 16) + (ofs))
00011 #define RP_OFF(rp)          (WORD)((DWORD)(rp) & 0xFFFF)
00012 #define RP_SEG(rp)          (WORD)((DWORD)(rp) >> 16)
00013 #define PokeRealWord(rp,x)  WriteRealMem (rp, &(x), sizeof(WORD))
00014
00015 #include <sys/packon.h>
00016
00017 typedef struct {
00018         DWORD  r_di;
00019         DWORD  r_si;
00020         DWORD  r_bp;
00021         DWORD  reserved;
00022         DWORD  r_bx;
00023         DWORD  r_dx;
00024         DWORD  r_cx;
00025         DWORD  r_ax;
00026         WORD   r_flags;
00027         WORD   r_es, r_ds, r_fs, r_gs;
00028         WORD   r_ip, r_cs, r_sp, r_ss;
00029       } REAL_regs;
00030
00031 #include <sys/packoff.h>
00032
00033 typedef struct {
00034         void    (*pm_func)(void);
00035         BYTE     *wrapper;
00036         REALPTR   rm_addr;
00037         REAL_regs rm_regs;
00038       } DPMI_callback;
00039
00040 extern BOOL    powerpak_init (void);
00041
00042 extern WORD    dpmi_create_dos_selector (void);
00043 extern int     dpmi_free_dos_selector   (WORD sel);
00044 extern int     dpmi_delete_memory_alias (void);
00045 extern DWORD   dpmi_create_memory_alias (DWORD addr, DWORD len);
00046 extern REALPTR dpmi_alloc_callback_retf (DPMI_callback *cb);
00047 extern int     dpmi_free_callback_retf  (DPMI_callback *cb);
00048
00049 extern int     dpmi_getvect (int intr, WORD *sel, DWORD *ofs);
00050 extern int     dpmi_setvect (int intr, WORD  sel, DWORD  ofs);
00051
00052 extern void    ReadRealMem  (void *buf, REALPTR rp, unsigned len);
00053 extern void    WriteRealMem (REALPTR rp, const void *src, int size);
00054
00055 extern BYTE   _farpeekb (WORD sel, DWORD ofs);
00056 extern WORD   _farpeekw (WORD sel, DWORD ofs);
00057 extern DWORD  _farpeekl (WORD sel, DWORD ofs);
00058 extern void   _farpokeb (WORD sel, DWORD ofs, BYTE val);
00059 extern void   _farpokew (WORD sel, DWORD ofs, WORD val);
00060 extern void   _farpokel (WORD sel, DWORD ofs, DWORD val);
00061
00062 #endif
00063 #endif
Generated on Wed Jan 25 15:42:38 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/PPP.C Source File

SRC/PPP.C

Go to the documentation of this file.
00001
00026 #include <stdio.h>
00027 #include <stdlib.h>
00028 #include <string.h>
00029 #include <ctype.h>
00030 #include <time.h>
00031 #include <limits.h>
00032 #include <netinet/in.h>
00033
00034 #include "wattcp.h"
00035 #include "misc.h"
00036 #include "strings.h"
00037 #include "pcdbug.h"
00038 #include "pcqueue.h"
00039 #include "pcconfig.h"
00040 #include "pcarp.h"
00041 #include "pcsed.h"
00042 #include "pcpkt.h"
00043 #include "pctcp.h"
00044 #include "ip4_in.h"
00045 #include "netaddr.h"
00046 #include "pppoe.h"
00047 #include "ppp.h"
00048
00049 #if defined(USE_PPPOE)
00050
00051 #define INITIAL_TIMEOUT 2
00052 #define MAX_TERMINATE   2
00053 #define MAX_CONFIGURE   10
00054 #define MAX_FAILURE     5
00055 #define MAX_TIMEOUT     8
00056
00057
00058 static DWORD remote_ip_base = 0x0A000000;
00059 static DWORD remote_ip_mask = 0xFF000000;
00060 static int   debug = 0;
00061
00062
00063 static struct ppp_state mystate;
00064
00065 static void ipcp_addr_req (struct ppp_state *state,
00066                            struct ppp_xcp *xcp, const struct xcp_type *tp,
00067                            const BYTE *buf, int len);
00068
00069 static void ipcp_addr_nak (struct ppp_state *state,
00070                            struct ppp_xcp *xcp, const struct xcp_type *tp,
00071                            const BYTE *buf, int len);
00072
00073 static void ipcp_addr_show (struct ppp_state *state,
00074                             struct ppp_xcp *xcp, const struct xcp_type *tp,
00075                             const BYTE *buf, int len);
00076
00077 static void send_event (struct ppp_state *state, struct ppp_xcp *xcp,
00078                         enum ppp_event event);
00079
00080 static void change_phase (struct ppp_state *state, enum ppp_phase phase);
00081
00082
00083 static const struct xcp_type lcp_types[] = {
00084                              { NULL, -1, 0, 0, 0, 0, NULL, NULL, NULL }
00085                            };
00086
00087 static const struct xcp_type ipcp_types[] = {
00088                              { "IP-Address", 3, 1, 6, 6, 0, ipcp_addr_req,
00089                                ipcp_addr_nak, ipcp_addr_show },
00090                              { NULL, -1, 0, 0, 0, 0, NULL, NULL, NULL }
00091                            };
00092
00093
00094 /* Dispatch table from RFC 1661
00095  */
00096 static const struct ppp_dispatch {
00097        enum xcp_state   next;
00098        enum xcp_action  act[3];
00099      } ppp_dispatch[10][16] = {
00100
00101     { /* stInitial */
00102       /* evUp */    { stClosed,   { acNull, acNull, acNull } },
00103       /* evDown */  { stNoChange, { acNull, acNull, acNull } },
00104       /* evOpen */  { stStarting, { acTls,  acNull, acNull } },
00105       /* evClose */ { stClosed,   { acNull, acNull, acNull } },
00106       /* evTOp */   { stNoChange, { acNull, acNull, acNull } },
00107       /* evTOm */   { stNoChange, { acNull, acNull, acNull } },
00108       /* evRCRp */  { stNoChange, { acNull, acNull, acNull } },
00109       /* evRCRm */  { stNoChange, { acNull, acNull, acNull } },
00110       /* evRCA */   { stNoChange, { acNull, acNull, acNull } },
00111       /* evRCN */   { stNoChange, { acNull, acNull, acNull } },
00112       /* evRTR */   { stNoChange, { acNull, acNull, acNull } },
00113       /* evRTA */   { stNoChange, { acNull, acNull, acNull } },
00114       /* evRUC */   { stNoChange, { acNull, acNull, acNull } },
00115       /* evRXJp */  { stNoChange, { acNull, acNull, acNull } },
00116       /* evRXJm */  { stNoChange, { acNull, acNull, acNull } },
00117       /* evRXR */   { stNoChange, { acNull, acNull, acNull } },
00118     },
00119     { /* stStarting */
00120       /* evUp */    { stReqSent,  { acIrc,  acScr,  acNull } },
00121       /* evDown */  { stNoChange, { acNull, acNull, acNull } },
00122       /* evOpen */  { stStarting, { acNull, acNull, acNull } },
00123       /* evClose */ { stInitial,  { acTlf,  acNull, acNull } },
00124       /* evTOp */   { stNoChange, { acNull, acNull, acNull } },
00125       /* evTOm */   { stNoChange, { acNull, acNull, acNull } },
00126       /* evRCRp */  { stNoChange, { acNull, acNull, acNull } },
00127       /* evRCRm */  { stNoChange, { acNull, acNull, acNull } },
00128       /* evRCA */   { stNoChange, { acNull, acNull, acNull } },
00129       /* evRCN */   { stNoChange, { acNull, acNull, acNull } },
00130       /* evRTR */   { stNoChange, { acNull, acNull, acNull } },
00131       /* evRTA */   { stNoChange, { acNull, acNull, acNull } },
00132       /* evRUC */   { stNoChange, { acNull, acNull, acNull } },
00133       /* evRXJp */  { stNoChange, { acNull, acNull, acNull } },
00134       /* evRXJm */  { stNoChange, { acNull, acNull, acNull } },
00135       /* evRXR */   { stNoChange, { acNull, acNull, acNull } },
00136     },
00137     { /* stClosed */
00138       /* evUp */    { stNoChange, { acNull, acNull, acNull } },
00139       /* evDown */  { stInitial,  { acNull, acNull, acNull } },
00140       /* evOpen */  { stReqSent,  { acIrc,  acScr,  acNull } },
00141       /* evClose */ { stClosed,   { acNull, acNull, acNull } },
00142       /* evTOp */   { stNoChange, { acNull, acNull, acNull } },
00143       /* evTOm */   { stNoChange, { acNull, acNull, acNull } },
00144       /* evRCRp */  { stClosed,   { acSta,  acNull, acNull } },
00145       /* evRCRm */  { stClosed,   { acSta,  acNull, acNull } },
00146       /* evRCA */   { stClosed,   { acSta,  acNull, acNull } },
00147       /* evRCN */   { stClosed,   { acSta,  acNull, acNull } },
00148       /* evRTR */   { stClosed,   { acSta,  acNull, acNull } },
00149       /* evRTA */   { stClosed,   { acNull, acNull, acNull } },
00150       /* evRUC */   { stClosed,   { acScj,  acNull, acNull } },
00151       /* evRXJp */  { stClosed,   { acNull, acNull, acNull } },
00152       /* evRXJm */  { stClosed,   { acTlf,  acNull, acNull } },
00153       /* evRXR */   { stClosed,   { acNull, acNull, acNull } },
00154     },
00155     { /* stStopped */
00156       /* evUp */    { stNoChange, { acNull, acNull, acNull } },
00157       /* evDown */  { stStarting, { acTls,  acNull, acNull } },
00158       /* evOpen */  { stStopped,  { acNull, acNull, acNull } },
00159       /* evClose */ { stClosed,   { acNull, acNull, acNull } },
00160       /* evTOp */   { stNoChange, { acNull, acNull, acNull } },
00161       /* evTOm */   { stNoChange, { acNull, acNull, acNull } },
00162       /* evRCRp */  { stAckSent,  { acIrc,  acScr,  acSca  } },
00163       /* evRCRm */  { stReqSent,  { acIrc,  acScr,  acScn  } },
00164       /* evRCA */   { stStopped,  { acSta,  acNull, acNull } },
00165       /* evRCN */   { stStopped,  { acSta,  acNull, acNull } },
00166       /* evRTR */   { stStopped,  { acSta,  acNull, acNull } },
00167       /* evRTA */   { stStopped,  { acNull, acNull, acNull } },
00168       /* evRUC */   { stStopped,  { acScj,  acNull, acNull } },
00169       /* evRXJp */  { stStopped,  { acNull, acNull, acNull } },
00170       /* evRXJm */  { stStopped,  { acTlf,  acNull, acNull } },
00171       /* evRXR */   { stStopped,  { acNull, acNull, acNull } },
00172     },
00173     { /* stClosing */
00174       /* evUp */    { stNoChange, { acNull, acNull, acNull } },
00175       /* evDown */  { stInitial,  { acNull, acNull, acNull } },
00176       /* evOpen */  { stStopping, { acNull, acNull, acNull } },
00177       /* evClose */ { stClosing,  { acNull, acNull, acNull } },
00178       /* evTOp */   { stClosing,  { acStr,  acNull, acNull } },
00179       /* evTOm */   { stClosed,   { acTlf,  acNull, acNull } },
00180       /* evRCRp */  { stClosing,  { acNull, acNull, acNull } },
00181       /* evRCRm */  { stClosing,  { acNull, acNull, acNull } },
00182       /* evRCA */   { stClosing,  { acNull, acNull, acNull } },
00183       /* evRCN */   { stClosing,  { acNull, acNull, acNull } },
00184       /* evRTR */   { stClosing,  { acSta,  acNull, acNull } },
00185       /* evRTA */   { stClosed,   { acTlf,  acNull, acNull } },
00186       /* evRUC */   { stClosing,  { acScj,  acNull, acNull } },
00187       /* evRXJp */  { stClosing,  { acNull, acNull, acNull } },
00188       /* evRXJm */  { stClosed,   { acTlf,  acNull, acNull } },
00189       /* evRXR */   { stClosing,  { acNull, acNull, acNull } },
00190     },
00191     { /* stStopping */
00192       /* evUp */    { stNoChange, { acNull, acNull, acNull } },
00193       /* evDown */  { stInitial,  { acNull, acNull, acNull } },
00194       /* evOpen */  { stStopping, { acNull, acNull, acNull } },
00195       /* evClose */ { stClosing,  { acNull, acNull, acNull } },
00196       /* evTOp */   { stStopping, { acStr,  acNull, acNull } },
00197       /* evTOm */   { stStopped,  { acTlf,  acNull, acNull } },
00198       /* evRCRp */  { stStopping, { acNull, acNull, acNull } },
00199       /* evRCRm */  { stStopping, { acNull, acNull, acNull } },
00200       /* evRCA */   { stStopping, { acNull, acNull, acNull } },
00201       /* evRCN */   { stStopping, { acNull, acNull, acNull } },
00202       /* evRTR */   { stStopping, { acSta,  acNull, acNull } },
00203       /* evRTA */   { stStopped,  { acTlf,  acNull, acNull } },
00204       /* evRUC */   { stStopping, { acScj,  acNull, acNull } },
00205       /* evRXJp */  { stStopping, { acNull, acNull, acNull } },
00206       /* evRXJm */  { stStopped,  { acTlf,  acNull, acNull } },
00207       /* evRXR */   { stStopping, { acNull, acNull, acNull } },
00208     },
00209     { /* stReqSent */
00210       /* evUp */    { stNoChange, { acNull, acNull, acNull } },
00211       /* evDown */  { stStarting, { acNull, acNull, acNull } },
00212       /* evOpen */  { stReqSent,  { acNull, acNull, acNull } },
00213       /* evClose */ { stClosing,  { acIrc,  acStr,  acNull } },
00214       /* evTOp */   { stReqSent,  { acScr,  acNull, acNull } },
00215       /* evTOm */   { stStopped,  { acTlf,  acNull, acNull } },
00216       /* evRCRp */  { stAckSent,  { acSca,  acNull, acNull } },
00217       /* evRCRm */  { stReqSent,  { acScn,  acNull, acNull } },
00218       /* evRCA */   { stAckRcvd,  { acIrc,  acNull, acNull } },
00219       /* evRCN */   { stReqSent,  { acIrc,  acScr,  acNull } },
00220       /* evRTR */   { stReqSent,  { acSta,  acNull, acNull } },
00221       /* evRTA */   { stReqSent,  { acNull, acNull, acNull } },
00222       /* evRUC */   { stReqSent,  { acScj,  acNull, acNull } },
00223       /* evRXJp */  { stReqSent,  { acNull, acNull, acNull } },
00224       /* evRXJm */  { stStopped,  { acTlf,  acNull, acNull } },
00225       /* evRXR */   { stReqSent,  { acNull, acNull, acNull } },
00226     },
00227     { /* stAckRcvd */
00228       /* evUp */    { stNoChange, { acNull, acNull, acNull } },
00229       /* evDown */  { stStarting, { acNull, acNull, acNull } },
00230       /* evOpen */  { stAckRcvd,  { acNull, acNull, acNull } },
00231       /* evClose */ { stClosing,  { acIrc,  acStr,  acNull } },
00232       /* evTOp */   { stReqSent,  { acScr,  acNull, acNull } },
00233       /* evTOm */   { stStopped,  { acTlf,  acNull, acNull } },
00234       /* evRCRp */  { stOpened,   { acSca,  acTlu,  acNull } },
00235       /* evRCRm */  { stAckRcvd,  { acScn,  acNull, acNull } },
00236       /* evRCA */   { stReqSent,  { acScr,  acNull, acNull } },
00237       /* evRCN */   { stReqSent,  { acScr,  acNull, acNull } },
00238       /* evRTR */   { stReqSent,  { acSta,  acNull, acNull } },
00239       /* evRTA */   { stReqSent,  { acNull, acNull, acNull } },
00240       /* evRUC */   { stAckRcvd,  { acScj,  acNull, acNull } },
00241       /* evRXJp */  { stReqSent,  { acNull, acNull, acNull } },
00242       /* evRXJm */  { stStopped,  { acTlf,  acNull, acNull } },
00243       /* evRXR */   { stAckRcvd,  { acNull, acNull, acNull } },
00244     },
00245     { /* stAckSent */
00246       /* evUp */    { stNoChange, { acNull, acNull, acNull } },
00247       /* evDown */  { stStarting, { acNull, acNull, acNull } },
00248       /* evOpen */  { stAckSent,  { acNull, acNull, acNull } },
00249       /* evClose */ { stClosing,  { acIrc,  acStr,  acNull } },
00250       /* evTOp */   { stAckSent,  { acScr,  acNull, acNull } },
00251       /* evTOm */   { stStopped,  { acTlf,  acNull, acNull } },
00252       /* evRCRp */  { stAckSent,  { acSca,  acNull, acNull } },
00253       /* evRCRm */  { stReqSent,  { acScn,  acNull, acNull } },
00254       /* evRCA */   { stOpened,   { acIrc,  acTlu,  acNull } },
00255       /* evRCN */   { stAckSent,  { acIrc,  acScr,  acNull } },
00256       /* evRTR */   { stReqSent,  { acSta,  acNull, acNull } },
00257       /* evRTA */   { stAckSent,  { acNull, acNull, acNull } },
00258       /* evRUC */   { stAckSent,  { acScj,  acNull, acNull } },
00259       /* evRXJp */  { stAckSent,  { acNull, acNull, acNull } },
00260       /* evRXJm */  { stStopped,  { acTlf,  acNull, acNull } },
00261       /* evRXR */   { stAckSent,  { acNull, acNull, acNull } },
00262     },
00263     { /* stOpened */
00264       /* evUp */    { stNoChange, { acNull, acNull, acNull } },
00265       /* evDown */  { stStarting, { acTld,  acNull, acNull } },
00266       /* evOpen */  { stOpened,   { acNull, acNull, acNull } },
00267       /* evClose */ { stClosing,  { acTld,  acIrc,  acStr  } },
00268       /* evTOp */   { stNoChange, { acNull, acNull, acNull } },
00269       /* evTOm */   { stNoChange, { acNull, acNull, acNull } },
00270       /* evRCRp */  { stAckSent,  { acTld,  acScr,  acSca  } },
00271       /* evRCRm */  { stReqSent,  { acTld,  acScr,  acScn  } },
00272       /* evRCA */   { stReqSent,  { acTld,  acScr,  acNull } },
00273       /* evRCN */   { stReqSent,  { acTld,  acScr,  acNull } },
00274       /* evRTR */   { stStopping, { acTld,  acZrc,  acSta  } },
00275       /* evRTA */   { stReqSent,  { acTld,  acScr,  acNull } },
00276       /* evRUC */   { stOpened,   { acScj,  acNull, acNull } },
00277       /* evRXJp */  { stOpened,   { acNull, acNull, acNull } },
00278       /* evRXJm */  { stStopping, { acTld,  acIrc,  acStr  } },
00279       /* evRXR */   { stOpened,   { acSer,  acNull, acNull } },
00280     }
00281   };
00282
00283
00284 #if defined(USE_DEBUG)
00285
00286 static const char *ph_str[] = {
00287                   "Dead", "Establish", "Authenticate",
00288                   "Network", "Terminate"
00289                 };
00290
00291 static const char *ev_str[] = {
00292                   "Up", "Down", "Open", "Close", "TO+", "TO-",
00293                   "RCR+", "RCR-", "RCA", "RCN", "RTR", "RTA",
00294                   "RUC", "RXJ+", "RXJ-", "RXR"
00295                 };
00296
00297 static const char *st_str[] = {
00298                   "Initial", "Starting", "Closed", "Stopped",
00299                   "Closing", "Stopping", "Req-Sent", "Ack-Rcvd",
00300                   "Ack-Sent", "Opened", "No-Change"
00301                 };
00302
00303 static const char *ac_str[] = {
00304                   "Null", "irc", "scr", "tls", "tlf", "str", "sta",
00305                   "sca", "scn", "scj", "tld", "tlu", "zrc", "ser"
00306                 };
00307
00308 /*
00309  * Display contents of buffer
00310  */
00311 static void buffer_print (const char *verb, const BYTE *buf, int len)
00312 {
00313   int i, j;
00314
00315   (*_printf) ("%s %d bytes:\n", verb, len);
00316
00317   for (i = 0; i < len; i += 16)
00318   {
00319     (*_printf) ("  %04X: ", i);
00320     for (j = i; j < len && j < i + 16; j++)
00321         (*_printf) (" %02X", buf[j]);
00322     (*_printf) ("\n");
00323   }
00324 }
00325
00326 /*
00327  * Print text string safely.
00328  */
00329 static void safe_string (const BYTE *bp, int len)
00330 {
00331   (*_printf) ("\"");
00332
00333   while (--len >= 0)
00334   {
00335     char buf[2];
00336     int  chr = *bp++;
00337
00338     buf[0] = chr;
00339     buf[1] ='\0';
00340     if (isascii(chr) && isprint(chr))
00341          (*_printf) (buf);
00342     else (*_printf) ("\\%03o", chr);
00343   }
00344
00345   (*_printf) ("\"");
00346 }
00347
00348 /*
00349  * Show all options in negotiation message.
00350  */
00351 static void option_show (const struct ppp_state *state,
00352                          const struct ppp_xcp *xcp,
00353                          const BYTE *bp, int rlen)
00354 {
00355   while (rlen > 0)
00356   {
00357     const struct xcp_type *tp;
00358     int   i;
00359
00360     (*_printf) (" ");
00361     if (rlen < 2)
00362     {
00363       (*_printf) ("[trail %02X]\n", bp[0]);
00364       break;
00365     }
00366     if (bp[1] > rlen)
00367     {
00368       (*_printf) ("[trunc %02X %d>%d]\n", bp[0], bp[1], rlen);
00369       break;
00370     }
00371     for (tp = xcp->types; tp->type != -1; tp++)
00372         if (tp->type == bp[0])
00373           break;
00374
00375     if (tp->show)
00376     {
00377       /* Valid option; use defined printing routine
00378        */
00379       (*tp->show) ((struct ppp_state*)state, (struct ppp_xcp*)xcp,
00380                    tp, bp + 2, bp[1]);
00381     }
00382     else
00383     {
00384       /* Undefined option; just dump contents.
00385        */
00386       if (tp->name == NULL)
00387            (*_printf) ("%02X:", bp[0]);
00388       else (*_printf) ("%s:", tp->name);
00389       for (i = 2; i < bp[1]; i++)
00390           (*_printf) ("%02X", bp[i]);
00391     }
00392     i = bp[1];
00393     if (i < 2)
00394         i = 2;
00395     rlen -= i;
00396     bp   += i;
00397   }
00398 }
00399
00400 /*
00401  * Show a negotiation packet.
00402  * Assumes 'bp' points to the code number (after PPP Protocol ID).
00403  */
00404 static void show_packet (const char *inout, const struct ppp_state *state,
00405                          const struct ppp_xcp *xcp, const BYTE *bp, int len)
00406 {
00407   static const char *code_str[] = {
00408                     "Vendor", "Configure-Request", "Configure-Ack",
00409                     "Configure-Nak", "Configure-Reject", "Terminate-Request",
00410                     "Terminate-Ack", "Code-Reject", "Protocol-Reject",
00411                     "Echo-Request", "Echo-Reply", "Discard-Request"
00412                   };
00413   int code   = *bp++;
00414   int id     = *bp++;
00415   int length = intel16 (*(WORD*)bp);
00416
00417   bp += 2;
00418   if (len > length)
00419       len = length;
00420   len -= PPP_HDRLEN;
00421
00422   (*_printf) ("%s %s ", inout, xcp->name);
00423   if (code < DIM(code_str) && code_str[code])
00424        (*_printf) ("%s", code_str[code]);
00425   else (*_printf) ("code:%d", code);
00426
00427   (*_printf) (" ID:%d", id);
00428   if ((code == CODE_CONF_ACK || code == CODE_CONF_NAK ||
00429        code == CODE_CONF_REJ || code == CODE_TERM_ACK ||
00430        code == CODE_ECHO_REP) && id != xcp->ident)
00431      (*_printf) (" **ERR**");
00432   (*_printf) (" len:%d", length);
00433
00434   switch (code)
00435   {
00436     case CODE_CONF_REQ:
00437     case CODE_CONF_ACK:
00438     case CODE_CONF_NAK:
00439     case CODE_CONF_REJ:
00440          option_show (state, xcp, bp, len);
00441          break;
00442     case CODE_TERM_REQ:
00443     case CODE_TERM_ACK:
00444          if (len > 0)
00445          {
00446            (*_printf) (" ");
00447            safe_string (bp, len);
00448          }
00449          break;
00450     case CODE_CODE_REJ:
00451          (*_printf) (" code %d", *bp);
00452          break;
00453     case CODE_PROTO_REJ:
00454          (*_printf) (" protocol %02X%02X", bp[0], bp[1]);
00455          break;
00456     case CODE_ECHO_REQ:
00457     case CODE_ECHO_REP:
00458     case CODE_DISCARD_REQ:
00459          if (len >= 4)
00460             (*_printf) (" magic %02X%02X%02X%02X", bp[0], bp[1], bp[2], bp[3]);
00461          if (len > 4)
00462          {
00463            (*_printf) (" ");
00464            safe_string (bp+4, len-4);
00465          }
00466          break;
00467   }
00468   (*_printf) ("\n");
00469 }
00470
00471 #undef  PRINTF
00472 #define PRINTF(lvl,arg)    do {                 \
00473                              if (debug >= lvl)  \
00474                                 (*_printf) arg; \
00475                            } while (0)
00476 #else
00477   #undef  PRINTF
00478   #define PRINTF(lvl,arg)  ((void)0)
00479 #endif  /* USE_DEBUG */
00480
00481
00482 /*
00483  * Write packet to PPPoE session. Display contents if debugging.
00484  */
00485 static void ppp_write (const struct ppp_state *state,
00486                        const struct ppp_xcp *xcp,
00487                        const BYTE *buf, int len)
00488 {
00489   WATT_ASSERT (state);
00490   WATT_ASSERT (xcp);
00491
00492 #if defined(USE_DEBUG)
00493   if (debug > 3)
00494      buffer_print ("Transmitting", buf, len);
00495
00496   if (debug > 2)
00497   {
00498     int retv = buf[0] == 0xFF ? 2 : 0;
00499     retv += buf[retv] & 1 ? 1 : 2;
00500     show_packet ("SENT", state, xcp, buf + retv, len - retv);
00501   }
00502 #endif
00503   pppoe_send_sess (NULL /*\todo state->sock */, buf, len);
00504
00505   ARGSUSED (state);
00506   ARGSUSED (xcp);
00507 }
00508
00509 /*
00510  * Insert PPP protocol field.
00511  */
00512 static __inline BYTE *setup_acpf (BYTE *buf, WORD proto)
00513 {
00514   *(WORD*)buf = intel16 (proto);
00515   return (buf + 2);
00516 }
00517
00518 /*
00519  * Set up buffer for a new message (Configure-Request, Protocol-Reject,
00520  * Echo-Request, or Discard-Request).
00521  */
00522 static BYTE *code_id (struct ppp_state *state, struct ppp_xcp *xcp, int code)
00523 {
00524   BYTE *buf = setup_acpf (state->outbuffer, xcp->proto);
00525
00526   *buf++ = code;
00527   *buf++ = ++xcp->ident;
00528   *buf++ = 0;
00529   *buf++ = 4;
00530   return (buf);
00531 }
00532
00533 /*
00534  * Set up buffer for a reply to a previous message (Configure-Ack,
00535  * Configure-Nak, Configure-Reject, Echo-Reply).
00536  */
00537 static BYTE *code_reply (struct ppp_state *state, struct ppp_xcp *xcp, int code)
00538 {
00539   BYTE *buf = setup_acpf (state->outbuffer, xcp->proto);
00540
00541   *buf++ = code;
00542   *buf++ = state->inbuffer[3]; /* ident */
00543   *buf++ = 0;
00544   *buf++ = 4;
00545   return (buf);
00546 }
00547
00548 /*
00549  * Find a given option in the list for an XCP.
00550  */
00551 static struct option_state *find_option (const struct ppp_xcp *xcp, int type)
00552 {
00553   const struct xcp_type *tp;
00554
00555   for (tp = xcp->types; tp->type != -1; tp++)
00556       if (tp->type == type)
00557          return (xcp->opts + (tp - xcp->types));
00558   return (NULL);
00559 }
00560
00561 /*
00562  * Loop over all known options and insert into a Configure-Request
00563  * being built.
00564  */
00565 static void create_request (struct ppp_state *state, struct ppp_xcp *xcp)
00566 {
00567   struct xcp_type     *tp;
00568   struct option_state *os;
00569   BYTE  *bp, *obp;
00570
00571   obp = bp = code_id (state, xcp, CODE_CONF_REQ);
00572   for (tp = xcp->types, os = xcp->opts; tp->type != -1; tp++, os++)
00573   {
00574     if (os->state == osUnusable)
00575        continue;
00576
00577     if (!tp->flag && os->my_value == tp->default_value)
00578        continue;
00579
00580     bp[0] = (BYTE) tp->type;
00581     bp[1] = tp->minlen;
00582     if (tp->minlen > 2)
00583        bp[2] = (BYTE) (os->my_value >> (8 * (tp->minlen - 3))) & 0xFF;
00584     if (tp->minlen > 3)
00585        bp[3] = (BYTE) (os->my_value >> (8 * (tp->minlen - 4))) & 0xFF;
00586     if (tp->minlen > 4)
00587        bp[4] = (BYTE) (os->my_value >> (8 * (tp->minlen - 5))) & 0xFF;
00588     if (tp->minlen > 5)
00589        bp[5] = (BYTE) os->my_value;
00590     bp += bp[1];
00591   }
00592   *(WORD*) (obp-2) = intel16 (bp-obp+4);
00593   state->up = bp;
00594 }
00595
00596 /*
00597  * We've gotten a Configure-Request we like (RCR+), so we're agreeing
00598  * with the peer.  Set up to send Configure-Ack.
00599  */
00600 static void copy_peer_values (const struct ppp_state *state, struct ppp_xcp *xcp)
00601 {
00602   struct option_state *os;
00603   const struct xcp_type *tp;
00604   const BYTE  *bp;
00605   int   rlen;
00606   DWORD val;
00607
00608   for (tp = xcp->types, os = xcp->opts; tp->type != -1; tp++, os++)
00609       os->peer_value = tp->default_value;
00610   bp   = state->bp;
00611   rlen = state->mlen;
00612   while (rlen > 0)
00613   {
00614     for (tp = xcp->types; tp->type != -1; tp++)
00615         if (tp->type == bp[0])
00616            break;
00617
00618     os  = xcp->opts + (tp - xcp->types);
00619     val = bp[2];
00620     if (bp[1] > 3)
00621        val = (val << 8) + bp[3];
00622     if (bp[1] > 4)
00623        val = (val << 8) + bp[4];
00624     if (bp[1] > 5)
00625        val = (val << 8) + bp[5];
00626     os->peer_value = val;
00627     rlen -= bp[1];
00628     bp   += bp[1];
00629   }
00630 }
00631
00632 /*
00633  * Perform RFC 1661 actions as indicated by state machine.
00634  */
00635 static void dispatch_action (struct ppp_state *state, struct ppp_xcp *xcp,
00636                              enum xcp_action act)
00637 {
00638   BYTE *bp;
00639
00640   if (act == acNull)
00641      return;
00642
00643   PRINTF (2, ("%s action %s (%d)\n", xcp->name, ac_str[act], act));
00644
00645   switch (act)
00646   {
00647     case acNull:
00648          break;
00649
00650     case acIrc:
00651          xcp->restart = state->phase == phTerminate ? MAX_TERMINATE : MAX_CONFIGURE;
00652          state->timeout_period = INITIAL_TIMEOUT;
00653          break;
00654
00655     case acScr:
00656          if (xcp->restart > 0)
00657          {
00658            xcp->restart--;
00659            create_request (state, xcp);
00660            ppp_write (state, xcp, state->outbuffer, state->up - state->outbuffer);
00661          }
00662          xcp->timeout = time (NULL) + state->timeout_period;
00663          break;
00664
00665     case acTls:
00666          if (xcp == &state->xcps[XCP_IPCP])
00667               send_event (state, &state->xcps[XCP_LCP], evOpen);
00668          else change_phase (state, phEstablish);
00669          break;
00670
00671     case acTlf:
00672          if (xcp == &state->xcps[XCP_IPCP])
00673               send_event (state, &state->xcps[XCP_LCP], evClose);
00674          else change_phase (state, phTerminate);
00675          break;
00676
00677     case acStr:
00678          if (xcp->restart > 0)
00679          {
00680            xcp->restart--;
00681            bp = code_id (state, xcp, CODE_TERM_REQ);
00682            ppp_write (state, xcp, state->outbuffer, bp - state->outbuffer);
00683          }
00684          xcp->timeout = time (NULL) + state->timeout_period;
00685          break;
00686
00687     case acSta:
00688          bp = code_reply (state, xcp, CODE_TERM_ACK);
00689          ppp_write (state, xcp, state->outbuffer, bp - state->outbuffer);
00690          break;
00691
00692     case acSca:
00693          copy_peer_values (state, xcp);
00694          state->inbuffer[2] = CODE_CONF_ACK;
00695          ppp_write (state, xcp, state->inbuffer, state->mlen +
00696                     (state->bp - state->inbuffer));
00697          break;
00698
00699     case acScn:
00700          if (xcp->naks_sent++ >= MAX_FAILURE)
00701             state->outbuffer[4] = CODE_CONF_REJ;
00702          /* fall-through */
00703
00704     case acScj:
00705          ppp_write (state, xcp, state->outbuffer, state->up - state->outbuffer);
00706          break;
00707
00708     case acTld:
00709          if (xcp == &state->xcps[XCP_LCP])
00710               change_phase (state, phTerminate);
00711          else PRINTF (0, ("IPCP down!\n"));
00712          break;
00713
00714     case acTlu:
00715          if (xcp == &state->xcps[XCP_LCP])
00716             change_phase (state, phAuthenticate);
00717          else
00718          {
00719            struct option_state *os = find_option (xcp, 3);
00720            DWORD  addr = intel (os->my_value);
00721
00722            my_ip_addr = addr;
00723            PRINTF (0, ("IPCP up!  Local address %s, ",
00724                    _inet_ntoa(NULL,addr)));
00725            addr = intel (os->peer_value);
00726            _arp_kill_gateways();
00727            _arp_add_gateway (NULL, addr);
00728            PRINTF (0, ("remote %s\n", _inet_ntoa(NULL,addr)));
00729          }
00730          xcp->restart = MAX_CONFIGURE;
00731          xcp->timeout = 0;
00732          break;
00733
00734     case acZrc:
00735          xcp->restart = 0;
00736          state->timeout_period = INITIAL_TIMEOUT;
00737          break;
00738
00739     case acSer:
00740          state->inbuffer[2] = CODE_ECHO_REP;
00741          *(long*) (state->inbuffer + 6) = intel (state->mymagic);
00742          ppp_write (state, xcp, state->inbuffer, state->mlen +
00743                     (state->bp - state->inbuffer));
00744          break;
00745   }
00746 }
00747
00748 /*
00749  * Issue event into XCP state machine -- go to next state and
00750  * invoke associated actions.
00751  */
00752 static void send_event (struct ppp_state *state, struct ppp_xcp *xcp,
00753                         enum ppp_event event)
00754 {
00755   const struct ppp_dispatch *dp = &ppp_dispatch [xcp->state][event];
00756
00757   if (dp->next == stNoChange)
00758   {
00759     PRINTF (2, ("%s got illegal %s event (%d) in %s state (%d)\n"
00760                 "\t(RFC 1661 section 4.4)\n",
00761                 xcp->name, ev_str[event], event, st_str[xcp->state],
00762                 xcp->state));
00763   }
00764   else
00765   {
00766     PRINTF (2, ("%s got %s event (%d) in %s state (%d), next is %s state (%d)\n",
00767                 xcp->name, ev_str[event], event, st_str[xcp->state],
00768                 xcp->state, st_str[dp->next], dp->next));
00769     xcp->state = dp->next;
00770   }
00771   dispatch_action (state, xcp, dp->act[0]);
00772   dispatch_action (state, xcp, dp->act[1]);
00773   dispatch_action (state, xcp, dp->act[2]);
00774 }
00775
00776 /*
00777  * Change overall link phase.  Central routine helps with
00778  * debugging.
00779  */
00780 static void change_phase (struct ppp_state *state, enum ppp_phase phase)
00781 {
00782   PRINTF (2, ("Current PPP phase is %s, switching to %s\n",
00783               ph_str[state->phase], ph_str[phase]));
00784
00785   switch (phase)
00786   {
00787     case phEstablish:
00788          if (state->phase == phDead)
00789             send_event (state, &state->xcps[XCP_LCP], evUp);
00790          break;
00791     case phAuthenticate:
00792          break;
00793     case phNetwork:
00794          if (state->phase == phAuthenticate)
00795             send_event (state, &state->xcps[XCP_IPCP], evUp);
00796          break;
00797     case phTerminate:
00798          send_event (state, &state->xcps[XCP_IPCP], evDown);
00799          break;
00800     case phDead:
00801          break;
00802   }
00803   state->phase = phase;
00804   if (phase == phAuthenticate)
00805      change_phase (state, phNetwork); /* XXX - no auth yet */
00806 }
00807
00808 /*
00809  * Check for time-outs
00810  */
00811 static void check_timeouts (void)
00812 {
00813   time_t now;
00814   int    i;
00815
00816   if (mystate.timeout_period < MAX_TIMEOUT)
00817       mystate.timeout_period <<= 1;
00818   now = time (NULL);
00819
00820   for (i = 0; i < DIM(mystate.xcps); i++)
00821   {
00822     if (mystate.xcps[i].timeout && now >= mystate.xcps[i].timeout)
00823     {
00824       mystate.xcps[i].timeout = 0;
00825
00826       /* Hack -- send with same ID on timeout.
00827        */
00828       if (mystate.xcps[i].restart > 0)
00829           mystate.xcps[i].ident--;
00830
00831       PRINTF (4, ("Sending TO%c to %s\n",
00832                   mystate.xcps[i].restart > 0 ? '+' : '-',
00833                   mystate.xcps[i].name));
00834
00835       send_event (&mystate, mystate.xcps+i,
00836                   mystate.xcps[i].restart > 0 ? evTOp : evTOm);
00837     }
00838   }
00839 }
00840
00844 void ppp_input (const BYTE *inbuffer, WORD len)
00845 {
00846   struct ppp_state *state = &mystate;
00847   int    i;
00848   WORD   proto;
00849
00850   state->inbuffer = (BYTE*) inbuffer;
00851
00852 #if defined(USE_DEBUG)
00853   if (debug > 3)
00854      buffer_print ("Received", state->inbuffer, len);
00855 #endif
00856
00857 #if 0   /* no proto-compression used in PPPoE */
00858   if (state->inbuffer[0] & 0x1)
00859   {
00860     proto = state->inbuffer[0];
00861     state->inbuffer++;
00862     len--;
00863   }
00864   else if (state->inbuffer[1] & 0x1)
00865   {
00866     proto = intel16 (*(WORD*)state->inbuffer);
00867     state->inbuffer += 2;
00868     len -=2;
00869   }
00870   else
00871   {
00872     proto = intel16 (*(WORD*)state->inbuffer);
00873     PRINTF (0, ("Bad protocol field %04X\n", proto));
00874     return;
00875   }
00876 #else
00877   proto = intel16 (*(WORD*)state->inbuffer);
00878   state->inbuffer += 2;
00879   len -= 2;
00880 #endif
00881
00882   if (proto == PPP_IP)
00883   {
00884     _ip4_handler ((const in_Header*)state->inbuffer, FALSE);
00885     return;
00886   }
00887
00888   /* Find XCP (IPCP/LCP) for indicated protocol
00889    */
00890   for (i = 0; i < DIM(state->xcps); i++)
00891       if (state->xcps[i].proto == proto)
00892          break;
00893
00894   if (i >= DIM(state->xcps))
00895   {
00896     /* Generate LCP Protocol-Reject for unknown things.
00897      */
00898     PRINTF (0, ("Unknown protocol 0x%04X\n", proto));
00899
00900     if (state->xcps[XCP_LCP].state == stOpened)
00901     {
00902       BYTE *bp = code_id (state, &state->xcps[XCP_LCP], CODE_PROTO_REJ);
00903
00904       i = sizeof(state->outbuffer) - (bp - state->outbuffer);
00905       if (len > i)
00906           len = i;
00907       memcpy (bp, state->inbuffer-2, len);
00908       len += bp - state->outbuffer;
00909       *(WORD*) (state->outbuffer+2) = intel16 (len-4);
00910       ppp_write (state, &state->xcps[XCP_LCP], state->outbuffer, len);
00911     }
00912     return;
00913   }
00914
00915   state->bp   = state->inbuffer;
00916   state->mlen = len;
00917   (*state->xcps[i].deliver) (state, state->xcps + i);
00918 }
00919
00920 /*
00921  * Add current option to list of options to be sent in Configure-Reject.
00922  */
00923 static void set_reject (struct ppp_state *state, struct ppp_xcp *xcp,
00924                         const BYTE *bp)
00925 {
00926   int i;
00927
00928   if (state->parse_state == psBad)
00929      return;
00930
00931   /* If this is the first reject for this packet, then set up.
00932    */
00933   if (state->parse_state != psRej)
00934   {
00935     state->up = code_reply (state, xcp, CODE_CONF_REJ);
00936     state->parse_state = psRej;
00937   }
00938
00939   /* Handle malformed options; make sure we don't send anything illegal
00940    * to the peer (even if he's sending us junk).
00941    */
00942   i = bp[1];
00943   if (i < 2)
00944       i = 2;
00945   memcpy (state->up, bp, i);
00946   state->up[1] = i;
00947   state->up += i;
00948 }
00949
00950 /*
00951  * Add current option to list of options to be sent in Configure-Nak.
00952  */
00953 static void set_nak (struct ppp_state *state, struct ppp_xcp *xcp, int type,
00954                      int len, const BYTE *bp)
00955 {
00956   /* If we're rejecting, then no point in doing naks.
00957    */
00958   if (state->parse_state == psBad || state->parse_state == psRej)
00959      return;
00960
00961   /* If this is the first nak for this packet, then set up.
00962    */
00963   if (state->parse_state != psNak)
00964   {
00965     state->up = code_reply (state, xcp, CODE_CONF_NAK);
00966     state->parse_state = psNak;
00967   }
00968   *state->up++ = type;
00969   *state->up++ = len;
00970   while (--len > 1)
00971     *state->up++ = *bp++;
00972 }
00973
00974 /*
00975  * Check Configure-Request options from peer against list of
00976  * known, valid, and desired options.
00977  */
00978 static int validate_request (struct ppp_state *state, struct ppp_xcp *xcp)
00979 {
00980   const struct xcp_type *tp;
00981   const BYTE  *bp;
00982   int   rlen, i;
00983
00984   state->parse_state = psOK;
00985   rlen = state->mlen;
00986   bp = state->bp;
00987
00988   while (rlen > 0)
00989   {
00990     if (rlen < 2 || bp[1] > rlen)
00991     {
00992       state->parse_state = psBad;
00993       break;
00994     }
00995     for (tp = xcp->types; tp->type != -1; tp++)
00996         if (tp->type == bp[0])
00997            break;
00998
00999     if (tp->type == -1)
01000        set_reject (state, xcp, bp);
01001     else if (bp[1] < tp->minlen)
01002        set_nak (state, xcp, tp->type, tp->minlen, bp + 2);
01003     else if (bp[1] > tp->maxlen)
01004        set_nak (state, xcp, tp->type, tp->maxlen, bp + 2);
01005     else if (tp->validate_req)
01006        (*tp->validate_req) (state, xcp, tp, bp + 2, bp[1]);
01007
01008     i = bp[1];
01009     if (i < 2)
01010         i = 2;
01011     rlen -= i;
01012     bp  += i;
01013   }
01014   if (state->parse_state == psNak || state->parse_state == psRej)
01015   {
01016     i = (state->up - state->outbuffer) - 4;
01017     state->outbuffer[6] = (i >> 8) & 0xFF;
01018     state->outbuffer[7] = i & 0xFF;
01019   }
01020   return (state->parse_state == psOK);
01021 }
01022
01023 /*
01024  * Process options in a Configure-{Ack,Nak,Reject}.
01025  */
01026 static void process_rcx (struct ppp_state *state, struct ppp_xcp *xcp, BYTE code)
01027 {
01028   struct option_state *os;
01029   const struct xcp_type *tp;
01030   int    rlen, i, val;
01031   BYTE  *bp;
01032
01033   rlen = state->mlen;
01034   bp   = state->bp;
01035
01036   while (rlen > 0)
01037   {
01038     if (rlen < 2 || bp[1] > rlen)
01039        break;
01040
01041     for (tp = xcp->types; tp->type != -1; tp++)
01042         if (tp->type == bp[0])
01043            break;
01044
01045     if (tp->type != -1)
01046     {
01047       os = xcp->opts + (tp - xcp->types);
01048       if (code == CODE_CONF_REJ)
01049          os->state = osUnusable;
01050       else if (code == CODE_CONF_ACK || tp->validate_nak == NULL)
01051       {
01052         if (bp[1] > 6 || bp[1] <= 2)
01053            os->my_value = tp->default_value;
01054         else
01055         {
01056           val = bp[2];
01057           if (bp[1] > 3)
01058              val = (val << 8) + bp[3];
01059           if (bp[1] > 4)
01060              val = (val << 8) + bp[4];
01061           if (bp[1] > 5)
01062              val = (val << 8) + bp[5];
01063           os->my_value = val;
01064         }
01065       }
01066       else
01067         (*tp->validate_nak) (state, xcp, tp, bp + 2, bp[1]);
01068     }
01069     if ((i = bp[1]) < 2)
01070        i = 2;
01071     rlen -= i;
01072     bp += i;
01073   }
01074 }
01075
01076 /*
01077  * Standard negotiation entry point.  This is assigned as the
01078  * 'delivery' function for control protocols, like LCP and IPCP.
01079  */
01080 static void std_negotiation (struct ppp_state *state, struct ppp_xcp *xcp)
01081 {
01082   BYTE code, id;
01083   WORD proto;
01084   int  i, length;
01085
01086   /* Validate overall message length
01087    */
01088   if (state->mlen < 4)
01089   {
01090     PRINTF (0, ("Malformed negotiation message; %d < 4\n", state->mlen));
01091     return;
01092   }
01093
01094   code   = *state->bp++;
01095   id     = *state->bp++;
01096   length = intel16 (*(WORD*)&state->bp);
01097   if (length > state->mlen)
01098   {
01099     PRINTF (0, ("Truncated negotiation message; %d > %d\n",
01100                 length, state->mlen));
01101     return;
01102   }
01103   if (length < state->mlen)
01104   {
01105     PRINTF (0, ("Trimmed negotiation message; %d < %d\n",
01106                 length, state->mlen));
01107     state->mlen = length;
01108   }
01109   state->bp   += 2;
01110   state->mlen -= 4;
01111
01112 #if defined(USE_DEBUG)
01113   if (debug > 2)
01114      show_packet ("RCVD", state, xcp, state->bp-4, state->mlen+4);
01115 #endif
01116
01117   /* Now switch out on received code number
01118    */
01119   switch (code)
01120   {
01121     case CODE_CONF_REQ:
01122          /* If request is good, then RCR+, if bad, then RCR-
01123           */
01124          if (validate_request (state, xcp))
01125               send_event (state, xcp, evRCRp);
01126          else send_event (state, xcp, evRCRm);
01127          break;
01128
01129     case CODE_CONF_ACK:
01130          /* Configure-Ack ID number must match last sent.
01131           */
01132          if (id == xcp->ident)
01133          {
01134            /* Should validate contents against last req sent, but we don't.
01135             */
01136            process_rcx (state, xcp, code);
01137            send_event (state, xcp, evRCA);
01138          }
01140          break;
01141
01142     case CODE_CONF_NAK:
01143     case CODE_CONF_REJ:
01144          /* Configure-Nak/Reject ID number must match last sent.
01145           */
01146          if (id == xcp->ident)
01147          {
01148            process_rcx (state, xcp, code);
01149            send_event (state, xcp, evRCN);
01150          }
01151          break;
01152
01153     case CODE_TERM_REQ:
01154          send_event (state, xcp, evRTR);
01155          break;
01156
01157     case CODE_TERM_ACK:
01158          if (id == xcp->ident)
01159             send_event (state, xcp, evRTA);
01160          break;
01161
01162     case CODE_CODE_REJ:
01163          code = *state->bp++;
01164
01165          /* Peer cannot reject well-known code numbers.
01166           */
01167          if (code && code < CODE_ECHO_REQ)
01168          {
01169            PRINTF (0, ("Invalid code reject for %d\n", code));
01170            send_event (state, xcp, evRXJm);
01171          }
01172          else
01173            send_event (state, xcp, evRXJp);
01174          break;
01175
01176     case CODE_PROTO_REJ:
01177          proto = intel16 (*(WORD*)&state->bp);
01178
01179          /* Peer cannot reject LCP!
01180           */
01181          if (proto == state->xcps[XCP_LCP].proto)
01182          {
01183            PRINTF (0, ("Peer protocol-rejected LCP itself!\n"));
01184            send_event (state, &state->xcps[XCP_LCP], evRXJm);
01185          }
01186          else
01187          {
01188            send_event (state, xcp, evRXJp);
01189            for (i = 0; i < DIM(state->xcps); i++)
01190                if (state->xcps[i].proto == proto)
01191                   state->xcps[i].state = stInitial;
01192          }
01193          break;
01194
01195     case CODE_ECHO_REQ:
01196          /* send a reply here. */
01197          send_event (state, xcp, evRXR);
01198          break;
01199
01200     case CODE_DISCARD_REQ:
01201          send_event (state, xcp, evRXR);
01202          break;
01203
01204     case CODE_ECHO_REP:
01205          /* ID number in Echo-Reply must match last echo sent.
01206           */
01207          if (id == xcp->ident)
01208             send_event (state, xcp, evRXR);
01209          break;
01210
01211     default:
01212          state->bp -= 4;
01213          send_event (state, xcp, evRUC);
01214          break;
01215   }
01216 }
01217
01218 /*
01219  * Initialize an XCP (LCP or NCP).
01220  */
01221 static void init_xcp (const char *name, struct ppp_xcp *xcp,
01222                       void (*deliver) (struct ppp_state *state,
01223                                        struct ppp_xcp *xcp),
01224                       const struct xcp_type *types, int ntypes, WORD proto)
01225 {
01226   struct option_state *os;
01227
01228   xcp->name    = name;
01229   xcp->state   = stInitial;
01230   xcp->restart = 0;
01231   xcp->timeout = 0;
01232   xcp->deliver = deliver;
01233   xcp->types   = (struct xcp_type*)types;
01234   xcp->proto   = proto;
01235
01236   /* If no options, then no vector to store negotiated values.
01237    */
01238   if (ntypes <= 0)
01239   {
01240     xcp->opts = NULL;
01241     return;
01242   }
01243   /* Otherwise, allocate vector and initialize options
01244    */
01245   os = xcp->opts = (struct option_state*) calloc (ntypes, sizeof(*os));
01246
01247   while (--ntypes >= 0)
01248   {
01249     os->my_value = os->peer_value = types->default_value;
01250     os->state    = osUsable;
01251     os++;
01252     types++;
01253   }
01254 }
01255
01256 /*
01257  * Handle Configure-Request from peer.  If it's in the range we think
01258  * it should be, then do nothing (allow Configure-Ack).  Otherwise,
01259  * send Configure-Nak with something more appropriate.
01260  */
01261 static void ipcp_addr_req (struct ppp_state *state,
01262                            struct ppp_xcp *xcp,
01263                            const struct xcp_type *tp,
01264                            const BYTE *buf, int len)
01265 {
01266   struct option_state *os;
01267   BYTE   lbuf[4];
01268   DWORD  addr = intel (*(DWORD*)buf);
01269
01270   os = xcp->opts + (tp - xcp->types);
01271   if (addr != os->my_value && (addr & remote_ip_mask) == remote_ip_base)
01272      return;
01273
01274   addr = xcp->opts [tp-xcp->types].peer_value;
01275   *(DWORD*) &lbuf = intel (addr);
01276   set_nak (state, xcp, tp->type, tp->minlen, lbuf);
01277   ARGSUSED (len);
01278 }
01279
01280 /*
01281  * Got a Configure-Nak of our address.  Just change; we're flexible.
01282  */
01283 static void ipcp_addr_nak (struct ppp_state *state,
01284                            struct ppp_xcp *xcp,
01285                            const struct xcp_type *tp,
01286                            const BYTE *buf, int len)
01287 {
01288   xcp->opts [tp-xcp->types].my_value = intel (*(DWORD*)buf);
01289   ARGSUSED (state);
01290   ARGSUSED (len);
01291 }
01292
01293 /*
01294  * Show IP address.
01295  */
01296 static void ipcp_addr_show (struct ppp_state *state,
01297                             struct ppp_xcp *xcp, const struct xcp_type *tp,
01298                             const BYTE *buf, int len)
01299 {
01300   PRINTF (0, ("%s", _inet_ntoa(NULL, intel(*(DWORD*)buf))));
01301   ARGSUSED (state);
01302   ARGSUSED (xcp);
01303   ARGSUSED (tp);
01304   ARGSUSED (buf);
01305   ARGSUSED (len);
01306 }
01307
01308 /*
01309  * Set local value (for Configure-Request).
01310  */
01311 static void set_option_value_lcl (struct ppp_xcp *xcp, int type, int value)
01312 {
01313   struct option_state *os = find_option (xcp, type);
01314
01315   if (os)
01316      os->my_value = value;
01317 }
01318
01319 /*
01320  * Set desired value for peer (we'll Configure-Nak with this).
01321  */
01322 static void set_option_value_rem (struct ppp_xcp *xcp, int type, int value)
01323 {
01324   struct option_state *os = find_option (xcp, type);
01325
01326   if (os)
01327      os->peer_value = value;
01328 }
01329
01330 void ppp_start (int dbg_level)
01331 {
01332   struct ppp_state *state = &mystate;
01333
01334   debug = dbg_level;
01335
01336   /* Initialize PPP state machine and add LCP and IPCP.
01337    */
01338   state->phase          = phDead;
01339   state->timeout_period = INITIAL_TIMEOUT;
01340   state->mymagic        = Random (0, UINT_MAX);
01341
01342   init_xcp ("LCP", &state->xcps[XCP_LCP], std_negotiation,
01343             lcp_types, DIM(lcp_types) - 1, PPP_LCP);
01344
01345   init_xcp ("IPCP", &state->xcps[XCP_IPCP], std_negotiation,
01346             ipcp_types, DIM(ipcp_types) - 1, PPP_IPCP);
01347
01348   set_option_value_lcl (&state->xcps[XCP_IPCP], 3, 0x0A000000 + (rand() % 1000));
01349   set_option_value_rem (&state->xcps[XCP_IPCP], 3, 0x0A00000A + (rand() % 1000));
01350
01351   /* Tell LCP to open
01352    */
01353   send_event (state, &state->xcps[XCP_IPCP], evOpen);
01354
01355   /* Add handler for checking timeouts (via tcp_tick)
01356    */
01357   addwattcpd (check_timeouts);
01358 }
01359
01360 #endif /* USE_PPPOE */
01361
Generated on Wed Jan 25 15:42:38 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/PPP.H Source File

SRC/PPP.H

Go to the documentation of this file.
00001
00003 #ifndef _w32_PPP_H
00004 #define _w32_PPP_H
00005
00006 #include <time.h>
00007 #include <sys/socket.h>     /* <sys/wtypes.h> */
00008 #include <net/ppp_defs.h>   /* PPP_MRU etc. */
00009
00010 void ppp_start (int debug);
00011 void ppp_input (const BYTE *inbuf, WORD len);
00012
00013
00014 /* Standard link phases
00015  */
00016 enum ppp_phase {
00017      phDead, phEstablish, phAuthenticate,
00018      phNetwork, phTerminate
00019    };
00020
00021 /* Standard set of events
00022  */
00023 enum ppp_event {
00024      evUp, evDown, evOpen, evClose, evTOp,
00025      evTOm, evRCRp, evRCRm, evRCA, evRCN,
00026      evRTR, evRTA, evRUC, evRXJp, evRXJm, evRXR
00027    };
00028
00029 /* Standard negotiation states
00030  */
00031 enum xcp_state {
00032      stInitial, stStarting, stClosed, stStopped,
00033      stClosing, stStopping, stReqSent, stAckRcvd,
00034      stAckSent, stOpened, stNoChange
00035    };
00036
00037 /* Standard set of actions
00038  */
00039 enum xcp_action {
00040      acNull, acIrc, acScr, acTls, acTlf, acStr, acSta,
00041      acSca, acScn, acScj, acTld, acTlu, acZrc, acSer
00042    };
00043
00044 /* Standard message code numbers
00045  */
00046 #define CODE_CONF_REQ     1
00047 #define CODE_CONF_ACK     2
00048 #define CODE_CONF_NAK     3
00049 #define CODE_CONF_REJ     4
00050 #define CODE_TERM_REQ     5
00051 #define CODE_TERM_ACK     6
00052 #define CODE_CODE_REJ     7
00053 #define CODE_PROTO_REJ    8
00054 #define CODE_ECHO_REQ     9
00055 #define CODE_ECHO_REP    10
00056 #define CODE_DISCARD_REQ 11
00057
00058
00059 struct ppp_xcp;
00060 struct ppp_state;
00061 struct xcp_type;
00062
00063 typedef void (*xcp_func) (struct ppp_state *state,
00064                           struct ppp_xcp *xcp,
00065                           const struct xcp_type *tp,
00066                           const BYTE *buf, int len);
00067
00068 typedef void (*ppp_func) (struct ppp_state *state,
00069                           struct ppp_xcp *xcp);
00070
00071 /* Basic information about an option.
00072  */
00073 struct xcp_type {
00074        char    *name;            /* Printable name */
00075        short    type;            /* option number (-1 to end) */
00076        short    flag;            /* set to ignore default value */
00077        BYTE     minlen;          /* minimum overall length */
00078        BYTE     maxlen;          /* maximum overall length */
00079        DWORD    default_value;   /* default */
00080        xcp_func validate_req;
00081        xcp_func validate_nak;
00082        xcp_func show;
00083      };
00084
00085 enum os_state {
00086      osUsable,
00087      osUnusable
00088    };
00089
00090 struct option_state {
00091        DWORD    my_value;             /* sent in Configure-Request */
00092        DWORD    peer_value;           /* last received */
00093        enum os_state state;           /* flag for rejects */
00094      };
00095
00096 struct ppp_xcp {
00097        const char          *name;     /* name of control protocol */
00098        enum xcp_state       state;    /* state machine */
00099        int                  restart;  /* standard restart count */
00100        time_t               timeout;  /* standard restart timer */
00101        int                  naks_sent;/* consecutive naks sent */
00102        ppp_func             deliver;  /* handler */
00103        struct xcp_type     *types;    /* option types supported here */
00104        struct option_state *opts;     /* current negotiation state */
00105        WORD                 proto;    /* PPP protocol ID */
00106        BYTE                 ident;    /* current ID number */
00107      };
00108
00109 enum parse_state {
00110      psOK, psNak,
00111      psRej, psBad
00112    };
00113
00114 struct ppp_state {
00115        enum ppp_phase   phase;        /* link phase */
00116        enum parse_state parse_state;  /* request parsing state */
00117        struct ppp_xcp   xcps[2];      /* installed XCPs */
00118 #define XCP_LCP  0
00119 #define XCP_IPCP 1
00120        int    timeout_period;         /* value for restart timer */
00121        int    mlen;                   /* packet length */
00122        DWORD  mymagic, hismagic;      /* magic numbers (for echo) */
00123        BYTE  *bp, *up;                /* pointers to packet buffers */
00124        BYTE  *inbuffer;
00125        BYTE   outbuffer [PPP_MRU];
00126      };
00127
00128 #endif  /* _w32_PPP_H */
Generated on Wed Jan 25 15:42:38 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/PPPOE.C Source File

SRC/PPPOE.C

Go to the documentation of this file.
00001
00038 #include <stdio.h>
00039 #include <stdlib.h>
00040 #include <string.h>
00041 #include <time.h>
00042
00043 #include "wattcp.h"
00044 #include "misc.h"
00045 #include "timer.h"
00046 #include "strings.h"
00047 #include "language.h"
00048 #include "pcconfig.h"
00049 #include "pcdbug.h"
00050 #include "pcqueue.h"
00051 #include "pctcp.h"
00052 #include "pcsed.h"
00053 #include "pcpkt.h"
00054 #include "pppoe.h"
00055 #include "ppp.h"
00056
00057 #if defined(USE_PPPOE)
00058
00059 enum States {
00060      StateNone = 0,
00061      StateDiscovery,
00062      StateSession
00063    };
00064
00065 static void (*prev_hook) (const char*, const char*) = NULL;
00066
00067 static BOOL        got_PADO;
00068 static BOOL        got_PADS;
00069 static BOOL        got_PADT;
00070 static BOOL        got_PADM;
00071 static WORD        session = 0;
00072 static enum States state   = StateNone;
00073 static mac_address ac_macAddr;  /* Access Consentrator's (AC) MAC address */
00074
00075 static struct {
00076        int  enable;
00077        int  trace;
00078        int  timeout;
00079        int  retries;
00080        int  lcpEchoInterval;
00081        char serviceName [MAX_VALUELEN+1];
00082        char userName [MAX_VALUELEN+1];
00083        char password [MAX_VALUELEN+1];
00084      } cfg = { 0, 0, 1, 3, 60, "", "", "" };
00085
00086 static int pppoe_send_disc (int code);
00087
00088 static void pppoe_config (const char *name, const char *value)
00089 {
00090   static const struct config_table pppoe_cfg[] = {
00091        { "ENABLE",      ARG_ATOI,   (void*)&cfg.enable          },
00092        { "TRACE",       ARG_ATOI,   (void*)&cfg.trace           },
00093        { "TIMEOUT",     ARG_ATOI,   (void*)&cfg.timeout         },
00094        { "RETRIES",     ARG_ATOI,   (void*)&cfg.retries         },
00095        { "LCP_ECHO",    ARG_ATOI,   (void*)&cfg.lcpEchoInterval },
00096        { "SERVICENAME", ARG_STRCPY, (void*)&cfg.serviceName     },
00097        { "USER",        ARG_STRCPY, (void*)&cfg.userName        },
00098        { "PASSWD",      ARG_STRCPY, (void*)&cfg.password        },
00099        { NULL,          0,          NULL                        }
00100      };
00101   if (!parse_config_table(&pppoe_cfg[0], "PPPOE.", name, value) && prev_hook)
00102      (*prev_hook) (name, value);
00103 }
00104
00109 static BOOL pppoe_wait (int wait_code)
00110 {
00111   DWORD timer = set_timeout (1000 * cfg.timeout);
00112
00113   while (1)
00114   {
00115     tcp_tick (NULL);
00116
00117     if ((wait_code == PPPOE_CODE_PADO && got_PADO) ||
00118         (wait_code == PPPOE_CODE_PADS && got_PADS))
00119     {
00120 #if defined(USE_DEBUG)
00121       if (cfg.trace)
00122          (*_printf) ("PPPoE: got %s\n", pppoe_get_code(wait_code));
00123 #endif
00124       return (TRUE);
00125     }
00126     if (chk_timeout(timer))
00127        break;
00128   }
00129   return (FALSE);
00130 }
00131
00136 static BOOL pppoe_discovery (void)
00137 {
00138   int loop;
00139
00140   for (loop = 1; loop <= cfg.retries; loop++)
00141   {
00142     if (!pppoe_send_disc(PPPOE_CODE_PADI))  /* send Init packet */
00143        return (FALSE);
00144
00145     if (pppoe_wait(PPPOE_CODE_PADO))        /* wait for Offer */
00146        break;
00147   }
00148   if (loop > cfg.retries)
00149      return (FALSE);
00150
00151   for (loop = 1; loop <= cfg.retries; loop++)
00152   {
00153     if (!pppoe_send_disc(PPPOE_CODE_PADR))  /* send Request */
00154        return (FALSE);
00155
00156     if (pppoe_wait(PPPOE_CODE_PADS))        /* wait for Session-confirm */
00157        break;
00158   }
00159   return (loop <= cfg.retries);
00160 }
00161
00165 void pppoe_init (void)
00166 {
00167   prev_hook = usr_init;
00168   usr_init  = pppoe_config;
00169   state     = StateDiscovery;
00170   got_PADO  = got_PADS = got_PADT = FALSE;
00171   memcpy (ac_macAddr, _eth_brdcast, sizeof(ac_macAddr));
00172 }
00173
00174
00183 int pppoe_start (void)
00184 {
00185   if (!cfg.enable || _pktdevclass != PDCLASS_ETHER)
00186      return (1);
00187
00188   if (!pppoe_discovery())
00189      return (0);
00190
00191 #undef  MSS_MAX
00192 #define MSS_MAX (PPPOE_MAX_DATA - TCP_OVERHEAD)
00193   _mss = min (_mss, MSS_MAX);
00194
00195   /* If not already clamped by user/pktdrvr, set MTU == 1492
00196    */
00197   if (_mtu > PPPOE_MAX_DATA)
00198       _mtu = PPPOE_MAX_DATA;
00199
00200   state = StateSession;
00201   ppp_start (cfg.trace);
00202   return (1);
00203 }
00204
00208 void pppoe_exit (void)
00209 {
00210   if (!cfg.enable || state != StateNone)
00211      return;
00212
00213   pppoe_send_disc (PPPOE_CODE_PADT);
00214   session = 0;
00215   state   = StateNone;
00216   memcpy (ac_macAddr, _eth_brdcast, sizeof(ac_macAddr));
00217 }
00218
00222 int pppoe_handler (const pppoe_Packet *pkt)
00223 {
00224   const BYTE *buf;
00225   const void *src;
00226   const void *dst;
00227   WORD  proto, len;
00228   BOOL  bcast, delivered = FALSE;
00229
00230   if (pkt->type != 1 || pkt->ver != 1)
00231      return (0);
00232
00233   src   = MAC_SRC (pkt);
00234   dst   = MAC_DST (pkt);
00235   proto = MAC_TYP (pkt);
00236   bcast = !memcmp (dst, _eth_brdcast, _eth_mac_len);
00237
00238   if (proto == PPPOE_SESS_TYPE && state == StateSession)
00239   {
00240     if (pkt->code    == PPPOE_CODE_SESS &&
00241         pkt->session == session         && !bcast &&
00242         !memcmp(dst, _eth_addr, _eth_mac_len) &&  /* to us? */
00243         !memcmp(src, ac_macAddr, _eth_mac_len))
00244     {
00245       len = intel16 (pkt->length);
00246       buf = &pkt->data[0];
00247       ppp_input (buf, len);    /* assume ppp_input() traces it */
00248       delivered = TRUE;
00249     }
00250   }
00251   else if (!bcast && proto == PPPOE_DISC_TYPE && state == StateDiscovery)
00252   {
00253     if (pkt->code == PPPOE_CODE_PADO)          /* Offer (can this be bcast?) */
00254     {
00255       got_PADO = TRUE;
00256       memcpy (ac_macAddr, src, _eth_mac_len);
00257     }
00258     else if (pkt->code == PPPOE_CODE_PADT &&  /* Terminate */
00259              pkt->session == session)
00260     {
00261       if (cfg.trace)
00262          outsnl (_LANG("PPPoE: session terminated"));
00263       got_PADT = TRUE;
00264       session  = 0;
00265     }
00266     else if (pkt->code == PPPOE_CODE_PADS)    /* Session-confirmation */
00267     {
00268       got_PADS = TRUE;
00269       session  = pkt->session;
00270     }
00271     else if (pkt->code == PPPOE_CODE_PADM)    /* Message (what to do?) */
00272     {
00273       got_PADM = TRUE;
00274     }
00275   }
00276   if (!delivered)
00277      DEBUG_RX (NULL, pkt);
00278   return (1);
00279 }
00280
00285 BOOL pppoe_is_up (const void *dest)
00286 {
00287 #if 1
00288   if (!cfg.enable || memcmp(dest,ac_macAddr,_eth_mac_len))
00289      return (FALSE);
00290   return (session != 0 && !got_PADT);
00291 #else
00292   session = 0xAA55;
00293   return (TRUE);       /* test */
00294 #endif
00295 }
00296
00300 static WORD build_pad (struct pppoe_Packet *pkt, WORD code)
00301 {
00302   BYTE *tags = &pkt->data[0];
00303
00304   if (code == PPPOE_CODE_PADI || code == PPPOE_CODE_PADR)
00305   {
00306     WORD srv_len = 0;
00307
00308     *(WORD*) tags = PPPOE_TAG_SERVICE_NAME;
00309     tags += 2;
00310     if (cfg.serviceName[0])
00311     {
00312       srv_len = strlen (cfg.serviceName);
00313       srv_len = min (srv_len, sizeof(pkt->data)-2-PPPOE_TAG_HDR_SIZE);
00314       memcpy (tags+2, cfg.serviceName, srv_len);
00315     }
00316     *(WORD*) tags = intel16 (srv_len);
00317
00318     /* Insert PPPOE_TAG_END_LIST ?
00319      */
00320     return (srv_len + PPPOE_TAG_HDR_SIZE);
00321   }
00322   *(WORD*)tags = 0;  /* No tags */
00323   return (0);
00324 }
00325
00330 static int pppoe_send_disc (int code)
00331 {
00332   pppoe_Packet *pkt;
00333   WORD          len;
00334
00335   pkt = (pppoe_Packet*) _eth_formatpacket (&ac_macAddr[0], PPPOE_DISC_TYPE);
00336   len = build_pad (pkt, code);
00337
00338   pkt->ver     = 1;
00339   pkt->type    = 1;
00340   pkt->code    = code;
00341   pkt->session = session;
00342   pkt->length  = intel16 (len);
00343
00344 #if defined(USE_DEBUG)
00345   if (cfg.trace)
00346      (*_printf) ("PPPOE: sending %s\n", pppoe_get_code(code));
00347 #endif
00348
00349   return _eth_send (len + PPPOE_HDR_SIZE, NULL, __FILE__, __LINE__);
00350 }
00351
00355 int pppoe_send_sess (const void *sock, const BYTE *buf, WORD len)
00356 {
00357   pppoe_Packet *pkt;
00358
00359   pkt = (pppoe_Packet*) _eth_formatpacket (&ac_macAddr[0], PPPOE_SESS_TYPE);
00360
00361   pkt->ver     = 1;
00362   pkt->type    = 1;
00363   pkt->code    = PPPOE_CODE_SESS;
00364   pkt->session = session;
00365   pkt->length  = intel16 (len);
00366
00367   memcpy (pkt->data, buf, len);
00368   return _eth_send (len + PPPOE_HDR_SIZE, sock, __FILE__, __LINE__);
00369 }
00370
00375 void *pppoe_mac_format (union link_Packet *tx)
00376 {
00377   pppoe_Packet *pppoe = (pppoe_Packet*) tx->eth.data;
00378
00379   memcpy (&tx->eth.head.destination[0], ac_macAddr, sizeof(mac_address));
00380   memcpy (&tx->eth.head.source[0], _eth_addr, sizeof(mac_address));
00381
00382   tx->eth.head.type = PPPOE_SESS_TYPE;
00383   pppoe->ver     = 1;
00384   pppoe->type    = 1;
00385   pppoe->code    = PPPOE_CODE_SESS;
00386   pppoe->session = session;
00387   _pkt_ip_ofs    = sizeof(eth_Header) + PPPOE_HDR_SIZE + 2; /* !! see _eth_send() */
00388   *(WORD*) &pppoe->data[0] = intel16 (PPP_IP);
00389   return (void*) &pppoe->data[2];
00390 }
00391 #endif /* USE_PPPOE */
00392
Generated on Wed Jan 25 15:42:38 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/PPPOE.H Source File

SRC/PPPOE.H

Go to the documentation of this file.
00001
00003 #ifndef _w32_PPPOE_H
00004 #define _w32_PPPOE_H
00005
00006 #define PPPOE_CODE_PADI  0x09    /* Active Discovery Initiation */
00007 #define PPPOE_CODE_PADO  0x07    /* Active Discovery Offer packet */
00008 #define PPPOE_CODE_PADR  0x19    /* Active Discovery Request */
00009 #define PPPOE_CODE_PADS  0x65    /* Active Discovery Session-confirmation */
00010 #define PPPOE_CODE_PADT  0xA7    /* Active Discovery Terminate */
00011 #define PPPOE_CODE_PADM  0xD3    /* Active Discovery Message packet */
00012 #define PPPOE_CODE_PADN  0xD4    /* Active Discovery Network packet */
00013 #define PPPOE_CODE_SESS  0x00    /* code when we have a session */
00014
00015 /* These 16-bit tags are on network order (RFC2516).
00016  */
00017 #define PPPOE_TAG_END_LIST       0x0000
00018 #define PPPOE_TAG_SERVICE_NAME   0x0101
00019 #define PPPOE_TAG_AC_NAME        0x0102
00020 #define PPPOE_TAG_HOST_UNIQ      0x0103
00021 #define PPPOE_TAG_AC_COOKIE      0x0104
00022 #define PPPOE_TAG_VENDOR_SPES    0x0105
00023 #define PPPOE_TAG_RELAY_SESS     0x0106
00024 #define PPPOE_TAG_HOST_URL       0x0111
00025 #define PPPOE_TAG_MOTM           0x0112
00026 #define PPPOE_TAG_IP_ROUTE_ADD   0x0121
00027 #define PPPOE_TAG_SERVICE_ERR    0x0201
00028 #define PPPOE_TAG_AC_SYSTEM_ERR  0x0202
00029 #define PPPOE_TAG_GENERIC_ERR    0x0203
00030
00031 #define PPPOE_HDR_SIZE      6   /* ver/type,code,session,length */
00032 #define PPPOE_TAG_HDR_SIZE  4   /* type,length header */
00033
00034 /*
00035  * The PPPOE header (RFC-2561) excluding Ether-header.
00036  */
00037 #include <sys/packon.h>
00038
00039 typedef struct pppoe_Packet {
00040 #if defined(USE_BIGENDIAN)
00041         BYTE  type : 4;
00042         BYTE  ver  : 4;
00043 #else
00044         BYTE  ver  : 4;
00045         BYTE  type : 4;
00046 #endif
00047         BYTE  code;
00048         WORD  session;
00049         WORD  length;
00050         BYTE  data [PPPOE_MAX_DATA];  /* higher level proto at data[2] */
00051       } pppoe_Packet;
00052
00053 #include <sys/packoff.h>
00054
00055
00056 extern void  pppoe_init (void);
00057 extern void  pppoe_exit (void);
00058 extern int   pppoe_start (void);
00059 extern int   pppoe_handler (const pppoe_Packet *pkt);
00060 extern BOOL  pppoe_is_up (const void *dest);
00061 extern int   pppoe_send_sess (const void *sock, const BYTE *buf, WORD len);
00062 extern void *pppoe_mac_format (union link_Packet *buf);
00063
00064 #endif
Generated on Wed Jan 25 15:42:38 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/PRESADDR.C Source File

SRC/PRESADDR.C

Go to the documentation of this file.
00001
00005 /* Copyright (c) 1996 by Internet Software Consortium.
00006  *
00007  * Permission to use, copy, modify, and distribute this software for any
00008  * purpose with or without fee is hereby granted, provided that the above
00009  * copyright notice and this permission notice appear in all copies.
00010  *
00011  * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
00012  * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
00013  * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
00014  * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
00015  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
00016  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
00017  * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
00018  * SOFTWARE.
00019  */
00020
00021 #include "socket.h"
00022
00023 #if defined(USE_BSD_API)
00024
00025 static const char *inet_ntop4 (const u_char *src, char *dst, size_t size);
00026 static int         inet_pton4 (const char *src, u_char *dst);
00027
00028 #if defined(USE_IPV6)
00029 static const char *inet_ntop6 (const u_char *src, char *dst, size_t size);
00030 static int         inet_pton6 (const char *src, u_char *dst);
00031 #endif
00032
00040 const char * W32_CALL inet_ntop (int af, const void *src, char *dst, size_t size)
00041 {
00042   switch (af)
00043   {
00044     case AF_INET:
00045          return inet_ntop4 ((const u_char*)src, dst, size);
00046 #if defined(USE_IPV6)
00047     case AF_INET6:
00048          return inet_ntop6 ((const u_char*)src, dst, size);
00049 #endif
00050     default:
00051          SOCK_ERRNO (EAFNOSUPPORT);
00052          return (NULL);
00053   }
00054 }
00055
00056
00066 int W32_CALL inet_pton (int af, const char *src, void *dst)
00067 {
00068   switch (af)
00069   {
00070     case AF_INET:
00071          return inet_pton4 (src, (u_char*)dst);
00072 #if defined(USE_IPV6)
00073     case AF_INET6:
00074          return inet_pton6 (src, (u_char*)dst);
00075 #endif
00076     default:
00077          SOCK_ERRNO (EAFNOSUPPORT);
00078          return (-1);
00079   }
00080 }
00081
00082
00092 static const char *inet_ntop4 (const u_char *src, char *dst, size_t size)
00093 {
00094   char tmp [sizeof("255.255.255.255")];
00095
00096   if ((size_t)sprintf(tmp,"%u.%u.%u.%u",src[0],src[1],src[2],src[3]) > size)
00097   {
00098     SOCK_ERRNO (ENOSPC);
00099     return (NULL);
00100   }
00101   return strcpy (dst, tmp);
00102 }
00103
00104 #if defined(USE_IPV6)
00105
00110 static const char *inet_ntop6 (const u_char *src, char *dst, size_t size)
00111 {
00112   /*
00113    * Note that int32_t and int16_t need only be "at least" large enough
00114    * to contain a value of the specified size.  On some systems, like
00115    * Crays, there is no such thing as an integer variable with 16 bits.
00116    * Keep this in mind if you think this function should have been coded
00117    * to use pointer overlays.  All the world's not a VAX.
00118    */
00119   char  tmp [sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
00120   char *tp;
00121   struct {
00122     long base;
00123     long len;
00124   } best, cur;
00125   u_long words [IN6ADDRSZ / INT16SZ];
00126   int    i;
00127
00128   /* Preprocess:
00129    *  Copy the input (bytewise) array into a wordwise array.
00130    *  Find the longest run of 0x00's in src[] for :: shorthanding.
00131    */
00132   memset (words, 0, sizeof(words));
00133   for (i = 0; i < IN6ADDRSZ; i++)
00134       words[i/2] |= (src[i] << ((1 - (i % 2)) << 3));
00135
00136   best.base = -1;
00137   best.len  = 0;
00138   cur.base  = -1;
00139   cur.len   = 0;
00140   for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++)
00141   {
00142     if (words[i] == 0)
00143     {
00144       if (cur.base == -1)
00145            cur.base = i, cur.len = 1;
00146       else cur.len++;
00147     }
00148     else if (cur.base != -1)
00149     {
00150       if (best.base == -1 || cur.len > best.len)
00151          best = cur;
00152       cur.base = -1;
00153     }
00154   }
00155   if ((cur.base != -1) && (best.base == -1 || cur.len > best.len))
00156      best = cur;
00157
00158   if (best.base != -1 && best.len < 2)
00159      best.base = -1;
00160
00161   /* Format the result.
00162    */
00163   tp = tmp;
00164   for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++)
00165   {
00166     /* Are we inside the best run of 0x00's?
00167      */
00168     if (best.base != -1 && i >= best.base && i < (best.base + best.len))
00169     {
00170       if (i == best.base)
00171          *tp++ = ':';
00172       continue;
00173     }
00174
00175     /* Are we following an initial run of 0x00s or any real hex?
00176      */
00177     if (i != 0)
00178        *tp++ = ':';
00179
00180     /* Is this address an encapsulated IPv4?
00181      */
00182     if (i == 6 && best.base == 0 &&
00183         (best.len == 6 || (best.len == 5 && words[5] == 0xffff)))
00184     {
00185       if (!inet_ntop4(src+12, tp, sizeof(tmp) - (tp - tmp)))
00186       {
00187         SOCK_ERRNO (ENOSPC);
00188         return (NULL);
00189       }
00190       tp += strlen (tp);
00191       break;
00192     }
00193     tp += sprintf (tp, "%lX", words[i]);
00194   }
00195
00196   /* Was it a trailing run of 0x00's?
00197    */
00198   if (best.base != -1 && (best.base + best.len) == (IN6ADDRSZ / INT16SZ))
00199      *tp++ = ':';
00200   *tp++ = '\0';
00201
00202   /* Check for overflow, copy, and we're done.
00203    */
00204   if ((size_t)(tp - tmp) > size)
00205   {
00206     SOCK_ERRNO (ENOSPC);
00207     return (NULL);
00208   }
00209   return strcpy (dst, tmp);
00210 }
00211 #endif      /* USE_IPV6 */
00212
00222 static int inet_pton4 (const char *src, u_char *dst)
00223 {
00224   static const char digits[] = "0123456789";
00225   int    saw_digit, octets, ch;
00226   u_char tmp[INADDRSZ];
00227   u_char *tp;
00228
00229   saw_digit = 0;
00230   octets = 0;
00231   *(tp = tmp) = '\0';
00232   while ((ch = *src++) != '\0')
00233   {
00234     const char *pch;
00235
00236     if ((pch = strchr(digits, ch)) != NULL)
00237     {
00238       u_int New = *tp * 10 + (pch - digits);
00239
00240       if (New > 255)
00241          return (0);
00242       *tp = New;
00243       if (! saw_digit)
00244       {
00245         if (++octets > 4)
00246            return (0);
00247         saw_digit = 1;
00248       }
00249     }
00250     else if (ch == '.' && saw_digit)
00251     {
00252       if (octets == 4)
00253          return (0);
00254       *++tp = '\0';
00255       saw_digit = 0;
00256     }
00257     else
00258       return (0);
00259   }
00260   if (octets < 4)
00261      return (0);
00262
00263   memcpy (dst, tmp, INADDRSZ);
00264   return (1);
00265 }
00266
00267 #if defined(USE_IPV6)
00268
00280 static int inet_pton6 (const char *src, u_char *dst)
00281 {
00282   u_char  tmp [IN6ADDRSZ];
00283   u_char *endp, *colonp, *tp = tmp;
00284   const   char *curtok;
00285   int     ch, saw_xdigit;
00286   u_int   val;
00287
00288   memset (tmp, 0, sizeof(tmp));
00289   endp   = tmp + sizeof(tmp);
00290   colonp = NULL;
00291
00292   /* Leading :: requires some special handling.
00293    */
00294   if (*src == ':' && *++src != ':')
00295      return (0);
00296
00297   curtok = src;
00298   saw_xdigit = 0;
00299   val = 0;
00300
00301   while ((ch = *src++) != '\0')
00302   {
00303     const char *pch;
00304
00305     ch = tolower (ch);
00306     pch = strchr (hex_chars_lower, ch);
00307     if (pch)
00308     {
00309       val <<= 4;
00310       val |= (pch - hex_chars_lower);
00311       if (val > 0xffff)
00312          return (0);
00313       saw_xdigit = 1;
00314       continue;
00315     }
00316     if (ch == ':')
00317     {
00318       curtok = src;
00319       if (!saw_xdigit)
00320       {
00321         if (colonp)
00322            return (0);
00323         colonp = tp;
00324         continue;
00325       }
00326       if (tp + INT16SZ > endp)
00327          return (0);
00328
00329       *tp++ = (u_char) (val >> 8) & 0xff;
00330       *tp++ = (u_char) val & 0xff;
00331       saw_xdigit = 0;
00332       val = 0;
00333       continue;
00334     }
00335     if (ch == '.' && ((tp + INADDRSZ) <= endp) && inet_pton4(curtok,tp) > 0)
00336     {
00337       tp += INADDRSZ;
00338       saw_xdigit = 0;
00339       break;  /* '\0' was seen by inet_pton4(). */
00340     }
00341     return (0);
00342   }
00343   if (saw_xdigit)
00344   {
00345     if (tp + INT16SZ > endp)
00346        return (0);
00347     *tp++ = (u_char) (val >> 8) & 0xff;
00348     *tp++ = (u_char) val & 0xff;
00349   }
00350   if (colonp)
00351   {
00352     /*
00353      * Since some memmove()'s erroneously fail to handle
00354      * overlapping regions, we'll do the shift by hand.
00355      */
00356     const int n = tp - colonp;
00357     int   i;
00358
00359     for (i = 1; i <= n; i++)
00360     {
00361       endp[-i] = colonp[n-i];
00362       colonp[n-i] = '\0';
00363     }
00364     tp = endp;
00365   }
00366   if (tp != endp)
00367      return (0);
00368
00369   memcpy (dst, tmp, IN6ADDRSZ);
00370   return (1);
00371 }
00372 #endif    /* USE_IPV6 */
00373
00374
00375 #if defined(TEST_PROG)
00376
00377 int main (int argc, char **argv)
00378 {
00379   const char *ip6_str;
00380   ip6_address ip6_addr;
00381
00382   if (argc != 2)
00383   {
00384     printf ("Usage: %s ip6-address\n", argv[0]);
00385     return (-1);
00386   }
00387
00388   ip6_str = argv[1];
00389   memset (&ip6_addr, 0, sizeof(ip6_addr));
00390   if (!inet_pton(AF_INET6, ip6_str, &ip6_addr))
00391   {
00392     printf ("Invalid IPv6 address `%s'\n", ip6_str);
00393     return (-1);
00394   }
00395
00396   printf ("inet_pton(AF_INET6): %s -> %s\n",
00397           ip6_str, _inet6_ntoa(&ip6_addr));
00398   return (0);
00399 }
00400 #endif  /* TEST_PROG */
00401 #endif  /* USE_BSD_API */
00402
00403
Generated on Wed Jan 25 15:42:38 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/PRINTK.C Source File

SRC/PRINTK.C

Go to the documentation of this file.
00001
00036 #include <stdio.h>
00037 #include <stdlib.h>
00038 #include <stdarg.h>
00039 #include <string.h>
00040 #include <signal.h>
00041 #include <ctype.h>
00042 #include <errno.h>
00043 #include <time.h>
00044
00045 #include "wattcp.h"
00046 #include "strings.h"
00047 #include "misc.h"
00048 #include "netaddr.h"
00049 #include "printk.h"
00050
00051 #if defined(USE_BSD_API) || defined(USE_DEBUG) || (DOSX & (DOS4GW|X32VM))
00052
00053 int  _printk_safe = 1;     /* must be set to 0 in intr-handlers */
00054
00055 #if defined(WIN32)
00056   FILE *_printk_file = NULL;
00057 #else
00058   FILE *_printk_file = stderr;
00059 #endif
00060
00061 static char *printk_ptr = NULL;
00062 static char *printk_buf = NULL;
00063 static char *printk_end = NULL;
00064
00065 static const char *str_signal (int sig);
00066
00067 /*
00068  * _snprintk - format a message into a buffer.  Like sprintf except we
00069  * also specify the length of the output buffer, and we handle
00070  * %m (error message), %t (current time) and %I (IP address) formats.
00071  * Returns the number of chars put into buf.
00072  *
00073  * NB! Doesn't do floating-point formats and long modifiers.
00074  *     (e.g. "%lu").
00075  */
00076 int MS_CDECL _snprintk (char *buf, int buflen, const char *fmt, ...)
00077 {
00078   int     len;
00079   va_list args;
00080   va_start (args, fmt);
00081
00082   len = _vsnprintk (buf, buflen, fmt, args);
00083   va_end (args);
00084   return (len);
00085 }
00086
00087 int MS_CDECL _printk (const char *fmt, ...)
00088 {
00089   int left = (int)(printk_end - printk_ptr);
00090   int len = -1;
00091
00092   if (_printk_file && fmt && left > 0)
00093   {
00094     va_list args;
00095     va_start (args, fmt);
00096     len = _vsnprintk (printk_ptr, left, fmt, args);
00097     printk_ptr += len;
00098     _printk_flush();
00099     va_end (args);
00100   }
00101   return (len);
00102 }
00103
00104 /*
00105  * Return 0 if okay, else -1
00106  */
00107 int _fputsk (const char *buf, FILE *stream)
00108 {
00109   int rc = -1;
00110
00111   if (stream && _printk_safe)
00112      rc = fwrite (buf, strlen(buf), 1, stream);
00113   return (rc == 1 ? 0 : -1);
00114 }
00115
00116 void _printk_flush (void)
00117 {
00118   int len = printk_ptr - printk_buf;
00119
00120   if (_printk_safe && _printk_file && len > 0)
00121   {
00122     fwrite (printk_buf, len, 1, _printk_file);
00123     printk_ptr = printk_buf;
00124   }
00125 }
00126
00127 static void printk_exit (void)
00128 {
00129   _printk_flush();
00130   if (_printk_file && _printk_file != stderr && _printk_file != stdout)
00131   {
00132     fclose (_printk_file);
00133     _printk_file = NULL;
00134   }
00135 }
00136
00137 /*
00138  * Called from openlog() to allocate print-buffer and
00139  * optionally open a file. If file == NULL, print to stderr.
00140  */
00141 int _printk_init (int size, const char *file)
00142 {
00143   if (!printk_buf)
00144   {
00145     printk_ptr = printk_buf = (char*) malloc (size);
00146     if (!printk_ptr)
00147     {
00148       fprintf (stderr, "_printk_init: allocation failed\n");
00149       return (0);
00150     }
00151   }
00152
00153 #if defined(WIN32)
00154   _printk_file = stderr;
00155 #endif
00156
00157   if (file && (_printk_file = fopen(file,"wt")) == NULL)
00158   {
00159     fprintf (stderr, "_printk_init: cannot open `%s'\n", file);
00160     return (0);
00161   }
00162   printk_end = printk_ptr + size;
00163   RUNDOWN_ADD (printk_exit, 300);
00164   return (1);
00165 }
00166
00167
00168 /*
00169  * _vsnprintk - like _snprintk, takes a va_list instead of a list of args.
00170  */
00171 #define OUTCHAR(c)  (void) (buflen > 0 ? (--buflen, *buf++ = (c)) : 0)
00172
00173 int _vsnprintk (char *buf, int buflen, const char *fmt, va_list args)
00174 {
00175   int    c, n, width, prec, fillch;
00176   int    base, len, neg, quoted, upper;
00177   long   i;
00178   BOOL   right_pad, is_long;
00179   DWORD  val = 0L;
00180   BYTE  *p;
00181   char  *str, *f, *buf0 = buf, *_fmt = (char*)fmt;
00182   char   num[32];
00183   time_t t;
00184
00185   if (--buflen < 0)
00186      return (-1);
00187
00188   while (buflen > 0)
00189   {
00190     for (f = _fmt; *f != '%' && *f != '\0'; ++f)
00191         ;
00192     if (f > _fmt)
00193     {
00194       len = f - _fmt;
00195       if (len > buflen)
00196           len = buflen;
00197       memcpy (buf, _fmt, len);
00198       buf    += len;
00199       buflen -= len;
00200       _fmt = f;
00201     }
00202     if (*_fmt == '\0')
00203        break;
00204
00205     is_long = FALSE;
00206 next:
00207     c = *(++_fmt);
00208     width = prec = 0;
00209     right_pad = FALSE;
00210     fillch = ' ';
00211     if (c == '0')
00212     {
00213       fillch = '0';
00214       c = *(++_fmt);
00215     }
00216     if (c == '*')
00217     {
00218       width = va_arg (args, int);
00219       c = *(++_fmt);
00220     }
00221     else
00222     {
00223       if (c == '-')
00224       {
00225         right_pad = TRUE;
00226         c = *(++fmt);
00227       }
00228       while (isdigit(c))
00229       {
00230         width = width * 10 + c - '0';
00231         c = *(++_fmt);
00232       }
00233     }
00234
00235     if (c == '.')
00236     {
00237       c = *(++_fmt);
00238       if (c == '*')
00239       {
00240         prec = va_arg (args, int);
00241         c = *(++_fmt);
00242       }
00243       else
00244       {
00245         while (isdigit(c))
00246         {
00247           prec = prec * 10 + c - '0';
00248           c = *(++_fmt);
00249         }
00250       }
00251     }
00252     str   = NULL;
00253     base  = 0;
00254     neg   = 0;
00255     upper = 0;
00256     ++_fmt;
00257
00258     switch (c)
00259     {
00260       case 'l':
00261            is_long = 1;
00262            goto next;
00263
00264       case 'd':
00265            i = is_long ? va_arg (args, long) : va_arg (args, int);
00266            if (i < 0)
00267            {
00268              neg = 1;
00269              val = -i;
00270            }
00271            else
00272              val = i;
00273            base = 10;
00274            break;
00275
00276       case 'u':
00277            val  = is_long ? va_arg (args, DWORD) : va_arg (args, unsigned);
00278            base = 10;
00279            break;
00280
00281       case 'o':
00282            val = is_long ? va_arg (args, unsigned long) :
00283                            va_arg (args, unsigned int);
00284            base = 8;
00285            break;
00286
00287       case 'X':
00288            upper = 1;
00289            /* fall through */
00290       case 'x':
00291            val = is_long ? va_arg (args, unsigned long) :
00292                            va_arg (args, unsigned int);
00293            base = 16;
00294            break;
00295
00296       case 'p':
00297            val   = (DWORD) va_arg (args, void*);
00298            base  = 16;
00299            neg   = 2;
00300            upper = 1;
00301            break;
00302
00303       case 's':
00304            str = va_arg (args, char*);
00305            break;
00306
00307       case 'S':
00308            str = (char*) str_signal (va_arg(args, int));
00309            break;
00310
00311       case 'c':
00312            num[0] = va_arg (args, int);
00313            num[1] = '\0';
00314            str = num;
00315            break;
00316
00317       case 'm':
00318            str = rip (strerror(errno));
00319            break;
00320
00321       case 'I':
00322            str = _inet_ntoa (num, ntohl(va_arg(args,DWORD)));
00323            break;
00324
00325       case 't':
00326            str = "??";
00327            if (!_printk_safe)
00328               break;
00329            time (&t);
00330            str  = ctime (&t);
00331            str += 4;           /* chop off the day name */
00332            str[15] = '\0';     /* chop off year and newline */
00333            break;
00334
00335       case 'v':                /* "visible" string */
00336       case 'q':                /* quoted string */
00337            quoted = c == 'q';
00338            p = va_arg (args, BYTE*);
00339            if (fillch == '0' && prec > 0)
00340               n = prec;
00341            else
00342            {
00343              n = strlen ((char*)p);
00344              if (prec > 0 && prec < n)
00345                 n = prec;
00346            }
00347            while (n > 0 && buflen > 0)
00348            {
00349              c = *p++;
00350              --n;
00351              if (!quoted && c >= 0x80)
00352              {
00353                OUTCHAR ('M');
00354                OUTCHAR ('-');
00355                c -= 0x80;
00356              }
00357              if (quoted && (c == '"' || c == '\\'))
00358                 OUTCHAR ('\\');
00359              if (c < 0x20 || (0x7F <= c && c < 0xA0))
00360              {
00361                if (quoted)
00362                {
00363                  OUTCHAR ('\\');
00364                  switch (c)
00365                  {
00366                    case '\t':
00367                         OUTCHAR ('t');
00368                         break;
00369                    case '\n':
00370                         OUTCHAR ('n');
00371                         break;
00372                    case '\b':
00373                         OUTCHAR ('b');
00374                         break;
00375                    case '\f':
00376                         OUTCHAR ('f');
00377                         break;
00378                    default:
00379                         OUTCHAR ('x');
00380                         OUTCHAR (hex_chars_lower[c >> 4]);
00381                         OUTCHAR (hex_chars_lower[c & 0xF]);
00382                  }
00383                }
00384                else
00385                {
00386                  if (c == '\t')
00387                     OUTCHAR (c);
00388                  else
00389                  {
00390                    OUTCHAR ('^');
00391                    OUTCHAR (c ^ 0x40);
00392                  }
00393                }
00394              }
00395              else
00396                OUTCHAR (c);
00397            }
00398            continue;
00399
00400       default:
00401            *buf++ = '%';
00402            if (c != '%')
00403               --_fmt;        /* so %z outputs %z etc. */
00404            --buflen;
00405            continue;
00406     }
00407
00408     if (base)
00409     {
00410       str = num + sizeof(num);
00411       *(--str) = '\0';
00412       while (str > num + neg)
00413       {
00414         int idx = val % base;
00415
00416         *(--str) = upper ? hex_chars_upper[idx] :
00417                            hex_chars_lower[idx];
00418         val = val / base;
00419         if (--prec <= 0 && val == 0)
00420            break;
00421       }
00422       switch (neg)
00423       {
00424         case 1: *(--str) = '-';
00425                 break;
00426         case 2: *(--str) = 'x';
00427                 *(--str) = '0';
00428                 break;
00429       }
00430       len = num + sizeof(num) - 1 - str;
00431     }
00432     else
00433     {
00434       len = strlen (str);
00435       if (prec > 0 && len > prec)
00436          len = prec;
00437     }
00438     if (right_pad && width > 0)
00439     {
00440       if (width > buflen)
00441           width = buflen;
00442       if ((n = width - len) > 0)
00443       {
00444         buflen -= n;
00445         for (; n > 0; --n)
00446             *buf++ = fillch;
00447       }
00448     }
00449     if (len > buflen)
00450         len = buflen;
00451     memcpy (buf, str, len);
00452     buf += len;
00453     buflen -= len;
00454
00455     if (right_pad && width > 0)
00456     {
00457       if (width > buflen)
00458           width = buflen;
00459       if ((n = width - len) > 0)
00460       {
00461         buflen -= n;
00462         for (; n > 0; --n)
00463             *buf++ = fillch;
00464       }
00465     }
00466   }
00467   *buf = '\0';
00468   return (buf - buf0);
00469 }
00470
00471
00472 /*
00473  * Return name for signal 'sig'
00474  */
00475 #ifdef __HIGHC__
00476 #undef SIGABRT   /* = SIGIOT */
00477 #endif
00478
00479 static const char *str_signal (int sig)
00480 {
00481   static char buf[20];
00482
00483   switch (sig)
00484   {
00485     case 0:
00486          return ("None");
00487 #ifdef SIGINT
00488     case SIGINT:
00489          return ("SIGINT");
00490 #endif
00491 #ifdef SIGABRT
00492     case SIGABRT:
00493          return ("SIGABRT");
00494 #endif
00495 #ifdef SIGFPE
00496     case SIGFPE:
00497          return ("SIGFPE");
00498 #endif
00499 #ifdef SIGILL
00500     case SIGILL:
00501          return ("SIGILL");
00502 #endif
00503 #ifdef SIGSEGV
00504     case SIGSEGV:
00505          return ("SIGSEGV");
00506 #endif
00507 #ifdef SIGTERM
00508     case SIGTERM:
00509          return ("SIGTERM");
00510 #endif
00511 #ifdef SIGALRM
00512     case SIGALRM:
00513          return ("SIGALRM");
00514 #endif
00515 #ifdef SIGHUP
00516     case SIGHUP:
00517          return ("SIGHUP");
00518 #endif
00519 #ifdef SIGKILL
00520     case SIGKILL:
00521          return ("SIGKILL");
00522 #endif
00523 #ifdef SIGPIPE
00524     case SIGPIPE:
00525          return ("SIGPIPE");
00526 #endif
00527 #ifdef SIGQUIT
00528     case SIGQUIT:
00529          return ("SIGQUIT");
00530 #endif
00531 #ifdef SIGUSR1
00532     case SIGUSR1:
00533          return ("SIGUSR1");
00534 #endif
00535 #ifdef SIGUSR2
00536     case SIGUSR2:
00537          return ("SIGUSR2");
00538 #endif
00539 #ifdef SIGUSR3
00540     case SIGUSR3:
00541          return ("SIGUSR3");
00542 #endif
00543 #ifdef SIGNOFP
00544     case SIGNOFP:
00545          return ("SIGNOFP");
00546 #endif
00547 #ifdef SIGTRAP
00548     case SIGTRAP:
00549          return ("SIGTRAP");
00550 #endif
00551 #ifdef SIGTIMR
00552     case SIGTIMR:
00553          return ("SIGTIMR");
00554 #endif
00555 #ifdef SIGPROF
00556     case SIGPROF:
00557          return ("SIGPROF");
00558 #endif
00559 #ifdef SIGSTAK
00560     case SIGSTAK:
00561          return ("SIGSTAK");
00562 #endif
00563 #ifdef SIGBRK
00564     case SIGBRK:
00565          return ("SIGBRK");
00566 #endif
00567 #ifdef SIGBUS
00568     case SIGBUS:
00569          return ("SIGBUS");
00570 #endif
00571 #ifdef SIGIOT
00572     case SIGIOT:
00573          return ("SIGIOT");
00574 #endif
00575 #ifdef SIGEMT
00576     case SIGEMT:
00577          return ("SIGEMT");
00578 #endif
00579 #ifdef SIGSYS
00580     case SIGSYS:
00581          return ("SIGSYS");
00582 #endif
00583 #ifdef SIGCHLD
00584     case SIGCHLD:
00585          return ("SIGCHLD");
00586 #endif
00587 #ifdef SIGPWR
00588     case SIGPWR:
00589          return ("SIGPWR");
00590 #endif
00591 #ifdef SIGWINCH
00592     case SIGWINCH:
00593          return ("SIGWINCH");
00594 #endif
00595 #ifdef SIGPOLL
00596     case SIGPOLL:
00597          return ("SIGPOLL");
00598 #endif
00599 #ifdef SIGCONT
00600     case SIGCONT:
00601          return ("SIGCONT");
00602 #endif
00603 #ifdef SIGSTOP
00604     case SIGSTOP:
00605          return ("SIGSTOP");
00606 #endif
00607 #ifdef SIGTSTP
00608     case SIGTSTP:
00609          return ("SIGTSTP");
00610 #endif
00611 #ifdef SIGTTIN
00612     case SIGTTIN:
00613          return ("SIGTTIN");
00614 #endif
00615 #ifdef SIGTTOU
00616     case SIGTTOU:
00617          return ("SIGTTOU");
00618 #endif
00619 #ifdef SIGURG
00620     case SIGURG:
00621          return ("SIGURG");
00622 #endif
00623 #ifdef SIGLOST
00624     case SIGLOST:
00625          return ("SIGLOST");
00626 #endif
00627 #ifdef SIGDIL
00628     case SIGDIL:
00629          return ("SIGDIL");
00630 #endif
00631 #ifdef SIGXCPU
00632     case SIGXCPU:
00633          return ("SIGXCPU");
00634 #endif
00635 #ifdef SIGXFSZ
00636     case SIGXFSZ:
00637          return ("SIGXFSZ");
00638 #endif
00639   }
00640   strcpy (buf, "Unknown ");
00641   itoa (sig, buf+8, 10);
00642   return (buf);
00643 }
00644
00645 #endif /* USE_BSD_API || USE_DEBUG || (DOSX & (DOS4GW|X32VM)) */
Generated on Wed Jan 25 15:42:38 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/PRINTK.H Source File

SRC/PRINTK.H

Go to the documentation of this file.
00001
00003 #ifndef _w32_PRINTK_H
00004 #define _w32_PRINTK_H
00005
00006 #include <stdio.h>
00007 #include <stdarg.h>
00008
00009 #if defined(__DJGPP__) || defined(__HIGHC__) || defined(__WATCOMC__) || defined(__DMC__)
00010 #undef _WIN32       /* Needed for __DMC__ */
00011 #include <unistd.h>
00012 #endif
00013
00014 #if defined(__TURBOC__) || defined(_MSC_VER) || defined(__WATCOMC__) || \
00015     defined(__DMC__) || defined(__MINGW32__) || defined(__LCC__)
00016 #include <process.h>
00017 #endif
00018
00019 #ifdef _w32_WATTCP_H  /* if included after wattcp.h (Watt-32 compile) */
00020   #define _printk_safe   NAMESPACE (_printk_safe)
00021   #define _printk_file   NAMESPACE (_printk_file)
00022   #define _printk_init   NAMESPACE (_printk_init)
00023   #define _printk_flush  NAMESPACE (_printk_flush)
00024   #define _printk        NAMESPACE (_printk)
00025   #define _fputsk        NAMESPACE (_fputsk)
00026   #define _snprintk      NAMESPACE (_snprintk)
00027   #define _vsnprintk     NAMESPACE (_vsnprintk)
00028 #endif
00029
00030 extern int   _printk_safe;
00031 extern FILE *_printk_file;
00033 extern int   _printk_init  (int size, const char *file);
00034 extern void  _printk_flush (void);
00035
00036 extern int   _fputsk    (const char *buf, FILE *stream);
00037 extern int   _vsnprintk (char *buf, int len, const char *fmt, va_list ap);
00038
00039 extern int MS_CDECL _printk (const char *fmt, ...)
00040                      ATTR_PRINTF (1,2);
00041
00042 extern int MS_CDECL _snprintk (char *buf, int len, const char *fmt, ...)
00043                      ATTR_PRINTF (3,4);
00044
00045 #endif  /* _w32_PRINTK_H */
00046
Generated on Wed Jan 25 15:42:38 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/PUNYCODE.C Source File

SRC/PUNYCODE.C

00001 /*
00002  * punycode.c from RFC 3492
00003  * http://www.nicemice.net/idn/
00004  * Adam M. Costello
00005  * http://www.nicemice.net/amc/
00006  *
00007  * This is ANSI C code (C89) implementing Punycode (RFC 3492).
00008  */
00009
00010 #include <stdio.h>
00011 #include <stdlib.h>
00012 #include <limits.h>
00013 #include <string.h>
00014
00015 #include "wattcp.h"
00016 #include "misc.h"
00017 #include "strings.h"
00018 #include "punycode.h"
00019
00020 #if defined(USE_IDNA) || defined(TEST_PROG)
00021
00022 /*** Bootstring parameters for Punycode ***/
00023
00024 enum {
00025   base = 36, tmin = 1, tmax = 26,
00026   skew = 38, damp = 700,
00027   initial_bias = 72,
00028   initial_n = 0x80,
00029   delimiter = 0x2D
00030 };
00031
00032 /* basic(cp) tests whether cp is a basic code point:
00033  */
00034 #define basic(cp) ((DWORD)(cp) < 0x80)
00035
00036 /* delim(cp) tests whether cp is a delimiter:
00037  */
00038 #define delim(cp) ((cp) == delimiter)
00039
00040 /*
00041  * decode_digit(cp) returns the numeric value of a basic code
00042  * point (for use in representing integers) in the range 0 to
00043  * base-1, or base if cp is does not represent a value.
00044  */
00045 static DWORD decode_digit (DWORD cp)
00046 {
00047   return (cp - 48 < 10 ?
00048           cp - 22 : cp - 65 < 26 ?
00049           cp - 65 : cp - 97 < 26 ?
00050           cp - 97 : base);
00051 }
00052
00053 /*
00054  * encode_digit(d,flag) returns the basic code point whose value
00055  * (when used for representing integers) is d, which needs to be in
00056  * the range 0 to base-1.  The lowercase form is used unless flag is
00057  * nonzero, in which case the uppercase form is used.  The behavior
00058  * is undefined if flag is nonzero and digit d has no uppercase form.
00059  */
00060 static char encode_digit (DWORD d, int flag)
00061 {
00062   return (char) (d + 22 + 75 * (d < 26) - ((flag != 0) << 5));
00063   /*  0..25 map to ASCII a..z or A..Z */
00064   /* 26..35 map to ASCII 0..9         */
00065 }
00066
00067 /* flagged(bcp) tests whether a basic code point is flagged
00068  * (uppercase).  The behavior is undefined if bcp is not a
00069  * basic code point.
00070  */
00071 #define flagged(bcp) ((DWORD)(bcp) - 65 < 26)
00072
00073 /*
00074  * encode_basic(bcp,flag) forces a basic code point to lowercase
00075  * if flag is zero, uppercase if flag is nonzero, and returns
00076  * the resulting code point.  The code point is unchanged if it
00077  * is caseless.  The behavior is undefined if bcp is not a basic
00078  * code point.
00079  */
00080 static char encode_basic (DWORD bcp, int flag)
00081 {
00082   bcp -= (bcp - 97 < 26) << 5;
00083   return (char) (bcp + ((!flag && (bcp - 65 < 26)) << 5));
00084 }
00085
00086 /* maxint is the maximum value of a DWORD variable:
00087  */
00088 static const DWORD maxint = (DWORD)-1;
00089
00090 static DWORD adapt (DWORD delta, DWORD numpoints, int firsttime)
00091 {
00092   DWORD k;
00093
00094   delta = firsttime ? delta / damp : delta >> 1;
00095   /* delta >> 1 is a faster way of doing delta / 2
00096    */
00097   delta += delta / numpoints;
00098
00099   for (k = 0; delta > ((base - tmin) * tmax) / 2; k += base)
00100       delta /= base - tmin;
00101   return k + (base - tmin + 1) * delta / (delta + skew);
00102 }
00103
00104 /*
00105  *Main encode function
00106  */
00107 enum punycode_status punycode_encode (DWORD input_length,
00108                                       const DWORD *input,
00109                                       const BYTE *case_flags,
00110                                       size_t *output_length,
00111                                       char *output)
00112 {
00113   DWORD n, delta, h, b, out, max_out, bias, j, m, q, k, t;
00114
00115   /* Initialize the state: */
00116
00117   n = initial_n;
00118   delta = out = 0;
00119   max_out = *output_length;
00120   bias = initial_bias;
00121
00122   /* Handle the basic code points: */
00123   for (j = 0; j < input_length; ++j)
00124   {
00125     if (basic (input[j]))
00126     {
00127       if (max_out - out < 2)
00128          return (punycode_big_output);
00129       output[out++] = case_flags ? encode_basic (input[j], case_flags[j]) :
00130                                    (char)input[j];
00131     }
00132 #if 0
00133     else if (input[j] < n)
00134          return (punycode_bad_input);
00135     /* (not needed for Punycode with unsigned code points) */
00136 #endif
00137   }
00138
00139   h = b = out;
00140
00141   /* h is the number of code points that have been handled, b is the
00142    * number of basic code points, and out is the number of characters
00143    * that have been output.
00144    */
00145   if (b > 0)
00146      output[out++] = delimiter;
00147
00148   /* Main encoding loop:
00149    */
00150   while (h < input_length)
00151   {
00152     /* All non-basic code points < n have been
00153      * handled already.  Find the next larger one:
00154      */
00155     for (m = maxint, j = 0; j < input_length; ++j)
00156     {
00157 #if 0
00158       if (basic(input[j]))
00159           continue;
00160       /* (not needed for Punycode) */
00161 #endif
00162       if (input[j] >= n && input[j] < m)
00163          m = input[j];
00164     }
00165
00166     /* Increase delta enough to advance the decoder's
00167      * <n,i> state to <m,0>, but guard against overflow:
00168      */
00169     if (m - n > (maxint - delta) / (h + 1))
00170        return (punycode_overflow);
00171
00172     delta += (m - n) * (h + 1);
00173     n = m;
00174
00175     for (j = 0; j < input_length; ++j)
00176     {
00177       if (input[j] < n)
00178       {
00179         if (++delta == 0)
00180            return (punycode_overflow);
00181       }
00182
00183       if (input[j] == n)
00184       {
00185         /* Represent delta as a generalized variable-length integer:
00186          */
00187         for (q = delta, k = base;; k += base)
00188         {
00189           if (out >= max_out)
00190              return (punycode_big_output);
00191
00192           t = k <= bias ? tmin :
00193               k >= bias + tmax ? tmax :
00194               k - bias;
00195           if (q < t)
00196              break;
00197           output[out++] = encode_digit (t + (q - t) % (base - t), 0);
00198           q = (q - t) / (base - t);
00199         }
00200         output[out++] = encode_digit (q, case_flags && case_flags[j]);
00201         bias = adapt (delta, h + 1, h == b);
00202         delta = 0;
00203         ++h;
00204       }
00205     }
00206     ++delta;
00207     ++n;
00208   }
00209
00210   *output_length = out;
00211   return (punycode_success);
00212 }
00213
00214 /*** Main decode function ***/
00215
00216 enum punycode_status punycode_decode (DWORD input_length,
00217                                       const char *input,
00218                                       size_t *output_length,
00219                                       DWORD *output,
00220                                       BYTE *case_flags)
00221 {
00222   DWORD n, out, i, max_out, bias, b, j, in, oldi, w, k, digit, t;
00223
00224   /* Initialize the state: */
00225
00226   n = initial_n;
00227   out = i = 0;
00228   max_out = *output_length;
00229   bias = initial_bias;
00230
00231   /* Handle the basic code points:  Let b be the number of input code
00232    * points before the last delimiter, or 0 if there is none, then
00233    * copy the first b code points to the output.
00234    */
00235   for (b = j = 0; j < input_length; ++j)
00236       if (delim (input[j]))
00237          b = j;
00238   if (b > max_out)
00239      return (punycode_big_output);
00240
00241   for (j = 0; j < b; ++j)
00242   {
00243     if (case_flags)
00244        case_flags[out] = flagged (input[j]);
00245     if (!basic (input[j]))
00246        return (punycode_bad_input);
00247     output[out++] = input[j];
00248   }
00249
00250   /* Main decoding loop:  Start just after the last delimiter if any
00251    * basic code points were copied; start at the beginning otherwise.
00252    */
00253   for (in = b > 0 ? b + 1 : 0; in < input_length; ++out)
00254   {
00255     /* in is the index of the next character to be consumed, and
00256      * out is the number of code points in the output array.
00257      */
00258
00259     /* Decode a generalized variable-length integer into delta,
00260      * which gets added to i.  The overflow checking is easier
00261      * if we increase i as we go, then subtract off its starting
00262      * value at the end to obtain delta.
00263      */
00264     for (oldi = i, w = 1, k = base;; k += base)
00265     {
00266       if (in >= input_length)
00267          return (punycode_bad_input);
00268
00269       digit = decode_digit (input[in++]);
00270       if (digit >= base)
00271          return (punycode_bad_input);
00272
00273       if (digit > ((maxint - i) / w))
00274          return (punycode_overflow);
00275
00276       i += digit * w;
00277       t = k <= bias ? tmin :
00278           k >= bias + tmax ? tmax :
00279           k - bias;
00280       if (digit < t)
00281          break;
00282       if (w > maxint / (base - t))
00283          return (punycode_overflow);
00284
00285       w *= (base - t);
00286     }
00287
00288     bias = adapt (i - oldi, out + 1, oldi == 0);
00289
00290     /* i was supposed to wrap around from out+1 to 0,
00291      * incrementing n each time, so we'll fix that now:
00292      */
00293     if (i / (out + 1) > maxint - n)
00294        return (punycode_overflow);
00295
00296     n += i / (out + 1);
00297     i %= (out + 1);
00298
00299     /* Insert n at position i of the output:
00300      */
00301 #if 0
00302     /* not needed for Punycode: */
00303     if (decode_digit(n) <= base)
00304        return (punycode_invalid_input);
00305 #endif
00306     if (out >= max_out)
00307        return (punycode_big_output);
00308
00309     if (case_flags)
00310     {
00311       memmove (case_flags + i + 1, case_flags + i, out - i);
00312
00313       /* Case of last character determines uppercase flag:
00314        */
00315       case_flags[i] = flagged (input[in - 1]);
00316     }
00317     memmove (output + i + 1, output + i, (out - i) * sizeof *output);
00318     output[i++] = n;
00319   }
00320
00321   *output_length = out;
00322   return (punycode_success);
00323 }
00324 #endif  /* USE_IDNA || TEST_PROG */
00325
00326
00327 #if defined(TEST_PROG)
00328
00329 /* For testing, we'll just set some compile-time limits rather than
00330  * use malloc(), and set a compile-time option rather than using a
00331  * command-line option.
00332  */
00333 #define UNICODE_MAX_LENGTH  256
00334 #define ACE_MAX_LENGTH      256
00335
00336 static void usage (char **argv)
00337 {
00338   fprintf (stderr,
00339            "\n"
00340            "%s -e reads code points and writes a Punycode string.\n"
00341            "%s -d reads a Punycode string and writes code points.\n"
00342            "\n"
00343            "Input and output are plain text in the native character set.\n"
00344            "Code points are in the form u+hex separated by whitespace.\n"
00345            "Although the specification allows Punycode strings to contain\n"
00346            "any characters from the ASCII repertoire, this test code\n"
00347            "supports only the printable characters, and needs the Punycode\n"
00348            "string to be followed by a newline.\n"
00349            "The case of the u in u+hex is the force-to-uppercase flag.\n",
00350            argv[0], argv[0]);
00351   exit (EXIT_FAILURE);
00352 }
00353
00354 #define fail(msg) __fail (__LINE__, msg)
00355 static void __fail (unsigned line, const char *msg)
00356 {
00357   fprintf (stderr, "line %u: %s", line, msg);
00358   exit (EXIT_FAILURE);
00359 }
00360
00361 static const char too_big[]       = "input or output is too large, recompile with larger limits\n";
00362 static const char invalid_input[] = "invalid input\n";
00363 static const char overflow[]      = "arithmetic overflow\n";
00364 static const char io_error[]      = "I/O error\n";
00365
00366 /* The following string is used to convert printable
00367  * characters between ASCII and the native charset:
00368  */
00369 static const char print_ascii[] = "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
00370                                   "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
00371                                   " !\"#$%&'()*+,-./" "0123456789:;<=>?"
00372                                   "@ABCDEFGHIJKLMNO"
00373                                   "PQRSTUVWXYZ[\\]^_"
00374                                   "`abcdefghijklmno"
00375                                   "pqrstuvwxyz{|}~\n";
00376
00377 int main (int argc, char **argv)
00378 {
00379   enum punycode_status status;
00380   size_t input_length, output_length, j;
00381   BYTE   case_flags [UNICODE_MAX_LENGTH];
00382   int    r;
00383
00384   if (argc != 2 || argv[1][0] != '-' || argv[1][2] != 0)
00385      usage (argv);
00386
00387   if (argv[1][1] == 'e')
00388   {
00389     DWORD input [UNICODE_MAX_LENGTH], codept;
00390     char  output [ACE_MAX_LENGTH+1], uplus[3];
00391     int   c;
00392
00393     /* Read the input code points:
00394      */
00395     input_length = 0;
00396
00397     for (;;)
00398     {
00399       r = scanf ("%2s%lx", uplus, &codept);
00400       if (ferror (stdin))
00401          fail (io_error);
00402       if (r == EOF || r == 0)
00403          break;
00404
00405       if (r != 2 || uplus[1] != '+' || codept > (DWORD) - 1)
00406          fail (invalid_input);
00407
00408       if (input_length == UNICODE_MAX_LENGTH)
00409          fail (too_big);
00410
00411       if (uplus[0] == 'u')
00412            case_flags[input_length] = 0;
00413       else if (uplus[0] == 'U')
00414            case_flags[input_length] = 1;
00415       else fail (invalid_input);
00416
00417       input[input_length++] = codept;
00418     }
00419
00420     /* Encode:
00421      */
00422     output_length = ACE_MAX_LENGTH;
00423     status = punycode_encode (input_length, input, case_flags,
00424                               &output_length, output);
00425     if (status == punycode_bad_input)
00426        fail (invalid_input);
00427     if (status == punycode_big_output)
00428        fail (too_big);
00429     if (status == punycode_overflow)
00430        fail (overflow);
00431     WATT_ASSERT (status == punycode_success);
00432
00433     /* Convert to native charset and output:
00434      */
00435     for (j = 0; j < output_length; ++j)
00436     {
00437       c = output[j];
00438       WATT_ASSERT (c >= 0 && c <= 127);
00439       if (print_ascii[c] == 0)
00440          fail (invalid_input);
00441       output[j] = print_ascii[c];
00442     }
00443
00444     output[j] = '\0';
00445     r = puts (output);
00446     if (r == EOF)
00447        fail (io_error);
00448     return (EXIT_SUCCESS);
00449   }
00450
00451   if (argv[1][1] == 'd')
00452   {
00453     char  input [ACE_MAX_LENGTH+2], *p, *pp;
00454     DWORD output [UNICODE_MAX_LENGTH];
00455
00456     /* Read the Punycode input string and convert to ASCII: */
00457
00458     fgets (input, ACE_MAX_LENGTH+2, stdin);
00459     if (ferror (stdin))
00460        fail (io_error);
00461     if (feof (stdin))
00462        fail (invalid_input);
00463     input_length = strlen (input) - 1;
00464     if (input[input_length] != '\n')
00465        fail (too_big);
00466     input[input_length] = '\0';
00467
00468     for (p = input; *p != 0; ++p)
00469     {
00470       pp = strchr (print_ascii, *p);
00471       if (pp == 0)
00472          fail (invalid_input);
00473       *p = pp - print_ascii;
00474     }
00475
00476     /* Decode:
00477      */
00478     output_length = UNICODE_MAX_LENGTH;
00479     status = punycode_decode (input_length, input, &output_length,
00480                               output, case_flags);
00481     if (status == punycode_bad_input)
00482        fail (invalid_input);
00483     if (status == punycode_big_output)
00484        fail (too_big);
00485     if (status == punycode_overflow)
00486        fail (overflow);
00487     WATT_ASSERT (status == punycode_success);
00488
00489     /* Output the result:
00490      */
00491     for (j = 0; j < output_length; ++j)
00492         printf ("%s+%04lX\n", case_flags[j] ? "U" : "u", output[j]);
00493     return (EXIT_SUCCESS);
00494   }
00495   usage (argv);
00496   return (EXIT_SUCCESS);
00497 }
00498 #endif   /* TEST_PROG */
Generated on Wed Jan 25 15:42:38 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/PUNYCODE.H Source File

SRC/PUNYCODE.H

00001 /*
00002  * punycode from RFC 3492
00003  * http://www.nicemice.net/idn/
00004  * Adam M. Costello
00005  * http://www.nicemice.net/amc/
00006  */
00007
00008 #ifndef _w32_PUNYCODE_H
00009 #define _w32_PUNYCODE_H
00010
00011 enum punycode_status {
00012      punycode_success,
00013      punycode_bad_input,      /* Input is invalid.                       */
00014      punycode_big_output,     /* Output would exceed the space provided. */
00015      punycode_overflow        /* Input needs wider integers to process.  */
00016    };
00017
00018 /*
00019  * punycode_encode() converts Unicode to Punycode.  The input
00020  * is represented as an array of Unicode code points (not code
00021  * units; surrogate pairs are not allowed), and the output
00022  * will be represented as an array of ASCII code points.  The
00023  * output string is *not* null-terminated; it will contain
00024  * zeros if and only if the input contains zeros.  (Of course
00025  * the caller can leave room for a terminator and add one if
00026  * needed.)  The input_length is the number of code points in
00027  * the input.  The output_length is an in/out argument: the
00028  * caller passes in the maximum number of code points that it
00029  * can receive, and on successful return it will contain the
00030  * number of code points actually output.  The case_flags array
00031  * holds input_length boolean values, where nonzero suggests that
00032  * the corresponding Unicode character be forced to uppercase
00033  * after being decoded (if possible), and zero suggests that
00034  * it be forced to lowercase (if possible).  ASCII code points
00035  * are encoded literally, except that ASCII letters are forced
00036  * to uppercase or lowercase according to the corresponding
00037  * uppercase flags.  If case_flags is a null pointer then ASCII
00038  * letters are left as they are, and other code points are
00039  * treated as if their uppercase flags were zero.  The return
00040  * value can be any of the punycode_status values defined above
00041  * except punycode_bad_input; if not punycode_success, then
00042  * output_size and output might contain garbage.
00043  */
00044 enum punycode_status punycode_encode (DWORD input_length,
00045                                       const DWORD *input,
00046                                       const BYTE *case_flags,
00047                                       size_t *output_length,
00048                                       char *output);
00049
00050
00051 /*
00052  * punycode_decode() converts Punycode to Unicode.  The input is
00053  * represented as an array of ASCII code points, and the output
00054  * will be represented as an array of Unicode code points.  The
00055  * input_length is the number of code points in the input.  The
00056  * output_length is an in/out argument: the caller passes in
00057  * the maximum number of code points that it can receive, and
00058  * on successful return it will contain the actual number of
00059  * code points output.  The case_flags array needs room for at
00060  * least output_length values, or it can be a null pointer if the
00061  * case information is not needed.  A nonzero flag suggests that
00062  * the corresponding Unicode character be forced to uppercase
00063  * by the caller (if possible), while zero suggests that it be
00064  * forced to lowercase (if possible).  ASCII code points are
00065  * output already in the proper case, but their flags will be set
00066  * appropriately so that applying the flags would be harmless.
00067  * The return value can be any of the punycode_status values
00068  * defined above; if not punycode_success, then output_length,
00069  * output, and case_flags might contain garbage.  On success, the
00070  * decoder will never need to write an output_length greater than
00071  * input_length, because of how the encoding is defined.
00072  */
00073 enum punycode_status punycode_decode (DWORD input_length,
00074                                       const char *input,
00075                                       size_t *output_length,
00076                                       DWORD *output,
00077                                       BYTE *case_flags);
00078 #endif
Generated on Wed Jan 25 15:42:38 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/QMSG.C Source File

SRC/QMSG.C

Go to the documentation of this file.
00001
00007 #include <stdio.h>
00008
00009 #include "copyrigh.h"
00010 #include "wattcp.h"
00011 #include "misc.h"
00012 #include "powerpak.h"
00013 #include "x32vm.h"
00014
00015 #if !defined(WIN32)
00016 /*
00017  * Disable stack-checking here because interrupt handlers might not
00018  * setup a legal stack.
00019  */
00020 #include "nochkstk.h"
00021
00022 #define SCR_WIDTH    80
00023 #define SCR_HEIGHT   50
00024 #define SCR_SEGMENT  0xB800
00025 #define SCR_START   (2*2*SCR_WIDTH)  /* start at line 3 */
00026
00027 BYTE dbg_colour   = 14 + (16*1);     /* yellow on blue */
00028 WORD dbg_scrpos   = SCR_START;
00029 WORD dbg_scrstart = SCR_START;
00030
00031 static int curr_line = (SCR_START/(2*SCR_WIDTH));
00032
00033 void dputch (char x)
00034 {
00035   if (x == '\r')
00036   {
00037     dbg_scrpos = 2 * SCR_WIDTH * curr_line;
00038   }
00039   else if (x == '\n')
00040   {
00041     dbg_scrpos += 2 * SCR_WIDTH;
00042     curr_line++;
00043   }
00044   else
00045   {
00046     POKEW (SCR_SEGMENT, dbg_scrpos, x | (dbg_colour << 8));
00047     dbg_scrpos += 2;
00048   }
00049   if (dbg_scrpos > 2*SCR_HEIGHT*SCR_WIDTH)
00050       dbg_scrpos = dbg_scrstart;
00051   if (curr_line >= SCR_HEIGHT)
00052       curr_line = (SCR_START/(2*SCR_WIDTH));
00053 }
00054
00055 void dmsg (const char *s)
00056 {
00057   while (s && *s)
00058     dputch (*s++);
00059 }
00060
00061 void dhex1int (int x)
00062 {
00063   x &= 0x0F;
00064   if (x > 9)
00065        x = 'A' + x - 10;
00066   else x += '0';
00067   dputch ((char)x);
00068 }
00069
00070 void dhex2int (int x)
00071 {
00072   x &= 0xFF;
00073   dhex1int (x >> 4);
00074   dhex1int (x);
00075 }
00076
00077 void dhex4int (int x)
00078 {
00079   x &= 0xFFFF;
00080   dhex2int (x >> 8);
00081   dhex2int (x & 0xFF);
00082 }
00083
00084 void dhex8int (DWORD x)
00085 {
00086   dhex4int ((int)(x >> 16));
00087   dhex4int ((int)(x & 0xFFFF));
00088   dputch (' ');
00089 }
00090 #endif  /* WIN32 */
00091
Generated on Wed Jan 25 15:42:38 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/RECEIVE.C Source File

SRC/RECEIVE.C

Go to the documentation of this file.
00001
00005 /*  BSD sockets functionality for Waterloo TCP/IP
00006  *
00007  *  Copyright (c) 1997-2002 Gisle Vanem <giva@bgnett.no>
00008  *
00009  *  Redistribution and use in source and binary forms, with or without
00010  *  modification, are permitted provided that the following conditions
00011  *  are met:
00012  *  1. Redistributions of source code must retain the above copyright
00013  *     notice, this list of conditions and the following disclaimer.
00014  *  2. Redistributions in binary form must reproduce the above copyright
00015  *     notice, this list of conditions and the following disclaimer in the
00016  *     documentation and/or other materials provided with the distribution.
00017  *  3. All advertising materials mentioning features or use of this software
00018  *     must display the following acknowledgement:
00019  *       This product includes software developed by Gisle Vanem
00020  *       Bergen, Norway.
00021  *
00022  *  THIS SOFTWARE IS PROVIDED BY ME (Gisle Vanem) AND CONTRIBUTORS ``AS IS''
00023  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00024  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00025  *  ARE DISCLAIMED.  IN NO EVENT SHALL I OR CONTRIBUTORS BE LIABLE FOR ANY
00026  *  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00027  *  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00028  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00029  *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00030  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00031  *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00032  *
00033  *  Version
00034  *
00035  *  0.5 : Dec 18, 1997 : G. Vanem - created
00036  *  0.6 : Aug 08, 2002 : G. Vanem - added AF_INET6 support
00037  */
00038
00039
00040 #include "socket.h"
00041
00042 #if defined(USE_BSD_API)
00043
00044 static int tcp_receive (Socket *sock, void *buf, int len, int flags,
00045                         struct sockaddr *from, int *fromlen);
00046
00047 static int udp_receive (Socket *sock, void *buf, int len, int flags,
00048                         struct sockaddr *from, int *fromlen);
00049
00050 static int raw_receive (Socket *sock, void *buf, unsigned len, int flags,
00051                         struct sockaddr *from, int *fromlen);
00052
00053 /*
00054  * receive() flags:
00055  *  MSG_PEEK
00056  *  MSG_WAITALL
00057  *  MSG_OOB       (not yet supported)
00058  *  MSG_DONTROUTE (not yet supported)
00059  *  MSG_EOR       (not yet supported)
00060  *  MSG_TRUNC     (not yet supported)
00061  *  MSG_CTRUNC    (not yet supported)
00062  *
00063  *  Only one flags bit is handled at a time.
00064  */
00065
00066 static int receive (const char *func, int s, void *buf, int len, int flags,
00067                     struct sockaddr *from, int *fromlen)
00068 {
00069   Socket *socket = _socklist_find (s);
00070   int     ret    = 0;
00071
00072   if (func)
00073      SOCK_DEBUGF (("\n%s:%d", func, s));
00074
00075   if (!socket)
00076   {
00077     if (_sock_dos_fd(s))
00078     {
00079       SOCK_DEBUGF ((", ENOTSOCK"));
00080       SOCK_ERRNO (ENOTSOCK);
00081       return (-1);
00082     }
00083     SOCK_DEBUGF ((", EBADF"));
00084     SOCK_ERRNO (EBADF);
00085     return (-1);
00086   }
00087
00088   VERIFY_RW (buf, len);
00089
00090   if (from && fromlen)
00091   {
00092     int sa_len = (socket->so_family == AF_INET6)  ?
00093                   sizeof(struct sockaddr_in6)     :
00094                  (socket->so_family == AF_PACKET) ?
00095                   sizeof(struct sockaddr_ll)      :
00096                   sizeof(struct sockaddr_in);
00097
00098     if (*fromlen < sa_len)
00099     {
00100       SOCK_DEBUGF ((", EADDRNOTAVAIL (fromlen = %d, sa_len = %d)",
00101                     *fromlen, sa_len));
00102       SOCK_ERRNO (EADDRNOTAVAIL);
00103       return (-1);
00104     }
00105     VERIFY_RW (from, sa_len);
00106   }
00107
00108   if (socket->so_state & SS_CONN_REFUSED)
00109   {
00110     if (socket->so_error == ECONNRESET)  /* from BSO_RST_CALLBACK */
00111     {
00112       SOCK_DEBUGF ((", ECONNRESET"));
00113       SOCK_ERRNO (ECONNRESET);
00114     }
00115     else
00116     {
00117       SOCK_DEBUGF ((", ECONNREFUSED (1)"));
00118       SOCK_ERRNO (ECONNREFUSED);
00119     }
00120     return (-1);
00121   }
00122
00123   if (socket->so_state & SS_CANTRCVMORE)
00124   {
00125     SOCK_DEBUGF ((", EPIPE (can't recv more)"));
00126     SOCK_ERRNO (EPIPE);  /* !! was ENOTCONN */
00127     return (-1);
00128   }
00129
00130   if ((flags & MSG_PEEK) && (flags & MSG_WAITALL))
00131   {
00132     SOCK_DEBUGF ((", invalid PEEK+WAITALL flags"));
00133     SOCK_ERRNO (EINVAL);
00134     return (-1);
00135   }
00136
00137   /* If application installs the same signal handlers we do, we must
00138    * exit cracefully from below loops.
00139    */
00140   if (_sock_sig_setup() < 0)
00141   {
00142     SOCK_DEBUGF ((", EINTR"));
00143     SOCK_ERRNO (EINTR);
00144     return (-1);
00145   }
00146
00147   switch (socket->so_type)
00148   {
00149     case SOCK_STREAM:
00150          ret = tcp_receive (socket, buf, len, flags, from, fromlen);
00151          SOCK_DEBUGF ((", len=%d", ret));
00152          break;
00153
00154     case SOCK_DGRAM:
00155          ret = udp_receive (socket, buf, len, flags, from, fromlen);
00156          SOCK_DEBUGF ((", len=%d", ret));
00157          break;
00158
00159     case SOCK_RAW:
00160          ret = raw_receive (socket, buf, len, flags, from, fromlen);
00161          SOCK_DEBUGF ((", len=%d", ret));
00162          break;
00163
00164     case SOCK_PACKET:
00165          ret = sock_packet_receive (socket, buf, len, from, fromlen);
00166          SOCK_DEBUGF ((", len=%d", ret));
00167          break;
00168
00169     default:
00170          SOCK_DEBUGF ((", EPROTONOSUPPORT"));
00171          SOCK_ERRNO (EPROTONOSUPPORT);
00172          ret = -1;
00173          break;
00174   }
00175   _sock_sig_restore();
00176   return (ret);
00177 }
00178
00179 /*
00180  * recvfrom(): receive from socket 's'. Address (src-ip/port) is put
00181  *             in 'from' (if non-NULL)
00182  */
00183 int W32_CALL recvfrom (int s, void *buf, int len, int flags,
00184                        struct sockaddr *from, int *fromlen)
00185 {
00186   return receive ("recvfrom", s, buf, len, flags, from, fromlen);
00187 }
00188
00189 /*
00190  * recv(): receive data from socket 's'. Flags may be
00191  *         MSG_PEEK, MSG_OOB or MSG_WAITALL
00192  *         Normally used on SOCK_STREAM sockets.
00193  */
00194 int W32_CALL recv (int s, void *buf, int len, int flags)
00195 {
00196   return receive ("recv", s, buf, len, flags, NULL, NULL);
00197 }
00198
00199 /*
00200  * read_s(): As above but no flags.
00201  */
00202 int read_s (int s, char *buf, int len)
00203 {
00204   return receive ("read_s", s, buf, len, 0, NULL, NULL);
00205 }
00206
00207 /*
00208  * recvmsg(): read into a 'msg->msg_iov' vector.
00209  *            Loop for each element in the vector. If 'msg->msg_name'
00210  *            is non-NULL, fill in from-addr.
00211  */
00212 int recvmsg (int s, struct msghdr *msg, int flags)
00213 {
00214   struct iovec    *iov;
00215   int    count = msg->msg_iovlen;
00216   int    i, bytes, len;
00217
00218   SOCK_DEBUGF (("\nrecvmsg:%d, iovecs=%d", s, count));
00219
00220   iov = msg->msg_iov;
00221   if (!iov)
00222   {
00223     SOCK_DEBUGF ((", EFAULT"));
00224     SOCK_ERRNO (EFAULT);
00225     return (-1);
00226   }
00227
00228   for (i = bytes = 0; i < count; i++)
00229   {
00230 #if (DOSX)
00231     if (!valid_addr ((DWORD)iov[i].iov_base, iov[i].iov_len))
00232     {
00233       SOCK_DEBUGF ((", EFAULT (iovec[%d] = %p/%d)",
00234                    (int)i, iov[i].iov_base, iov[i].iov_len));
00235       SOCK_ERRNO (EFAULT);
00236       return (-1);
00237     }
00238 #endif
00239
00240     len = receive (NULL, s, iov[i].iov_base, iov[i].iov_len,
00241                    flags, (struct sockaddr*)msg->msg_name,
00242                    &msg->msg_namelen);
00243     if (len < 0)
00244     {
00245       bytes = -1;
00246       break;
00247     }
00248     bytes += len;
00249     if (len != iov[i].iov_len)  /* nothing more to read */
00250        break;
00251   }
00252   SOCK_DEBUGF ((", total %d", bytes));
00253   return (bytes);
00254 }
00255
00256 /*
00257  * readv_s(): Complementary of writev_s().
00258  */
00259 int readv_s (int s, const struct iovec *vector, size_t count)
00260 {
00261   int i, len, bytes = 0;
00262
00263   SOCK_DEBUGF (("\nreadv_s:%d, iovecs=%lu", s, (DWORD)count));
00264
00265   for (i = 0; i < (int)count; i++)
00266   {
00267 #if (DOSX)
00268     if (!valid_addr ((DWORD)vector[i].iov_base, vector[i].iov_len))
00269     {
00270       SOCK_DEBUGF ((", EFAULT (iovec[%d] = %p/%d)",
00271                    (int)i, vector[i].iov_base, vector[i].iov_len));
00272       SOCK_ERRNO (EFAULT);
00273       return (-1);
00274     }
00275 #endif
00276
00277     len = receive (NULL, s, vector[i].iov_base, vector[i].iov_len,
00278                    0, NULL, NULL);
00279     if (len < 0)
00280     {
00281       bytes = -1;
00282       break;
00283     }
00284     bytes += len;
00285     if (len != vector[i].iov_len)  /* nothing more to read */
00286        break;
00287   }
00288   SOCK_DEBUGF ((", total %d", bytes));
00289   return (bytes);
00290 }
00291
00292 /*
00293  * Fill in packet's address in 'from' and length in 'fromlen'.
00294  * Only used for UDP & Raw-IP. TCP have peer info in 'socket->remote_addr'.
00295  */
00296 static void udp_raw_fill_from_ip4 (struct sockaddr *from, int *fromlen,
00297                                    const struct in_addr *peer, WORD port)
00298 {
00299   struct sockaddr_in *sa = (struct sockaddr_in*) from;
00300
00301   if (sa && fromlen)
00302   {
00303     sa->sin_addr   = *peer;
00304     sa->sin_family = AF_INET;
00305     sa->sin_port   = port;
00306     memset (&sa->sin_zero, 0, sizeof(sa->sin_zero));
00307   }
00308   if (fromlen)
00309      *fromlen = sizeof (*sa);
00310 }
00311
00312 #if defined(USE_IPV6)
00313 static void udp_raw_fill_from_ip6 (struct sockaddr *from, int *fromlen,
00314                                    const void *peer, WORD port)
00315 {
00316   struct sockaddr_in6 *sa = (struct sockaddr_in6*) from;
00317
00318   if (sa && fromlen)
00319   {
00320     memset (sa, 0, sizeof(*sa));
00321     memcpy (&sa->sin6_addr, peer, sizeof(sa->sin6_addr));
00322     sa->sin6_family = AF_INET6;
00323     sa->sin6_port   = port;
00324   }
00325   if (fromlen)
00326      *fromlen = sizeof (*sa);
00327 }
00328 #endif
00329
00330 /*
00331  * TCP receiver
00332  */
00333 static int tcp_receive (Socket *socket, void *buf, int len, int flags,
00334                         struct sockaddr *from, int *fromlen)
00335 {
00336   int        ret     = 0;
00337   BOOL       got_fin = FALSE; /* got FIN from peer */
00338   DWORD      timer   = 0UL;
00339   sock_type *sk      = (sock_type*) socket->tcp_sock;
00340
00341   if (!from && !socket->local_addr)
00342   {
00343     SOCK_DEBUGF ((", no local_addr"));
00344     SOCK_ERRNO (ENOTCONN);
00345     return (-1);
00346   }
00347
00348   if (flags & MSG_OOB)
00349   {
00350     SOCK_DEBUGF ((", no OOB-data"));
00351     SOCK_ERRNO (EWOULDBLOCK);
00352     return (-1);
00353   }
00354
00355   if (socket->timeout && sock_inactive)
00356      timer = set_timeout (1000 * socket->timeout);
00357
00358   while (1)
00359   {
00360     BOOL ok = (tcp_tick(sk) != 0);
00361
00362     tcp_Retransmitter (TRUE);
00363
00364     if (socket->so_state & SS_ISDISCONNECTING)
00365     {
00366       got_fin = TRUE;  /* might not have got a FIN, but need to read */
00367       goto read_it;
00368     }
00369
00371 #if 0
00372     if ((socket-so_options & SO_OOBINLINE) && urgent_data(sk))
00373     {
00374       ret = urgent_data_read (sk, (BYTE*)buf, len);
00375       break;
00376     }
00377 #endif
00378
00379     /* Don't do this for a listening socket
00380      */
00381     if (!(socket->so_options & SO_ACCEPTCONN))
00382     {
00383       if ((sk->tcp.locflags & LF_GOT_FIN) &&     /* got FIN, no unACK data */
00384           sk->tcp.rx_datalen == 0)
00385       {
00386         socket->so_state |=  SS_ISDISCONNECTING; /* We may receive more */
00387         socket->so_state &= ~SS_ISCONNECTED;     /* no longer ESTAB state */
00388         got_fin = TRUE;
00389         SOCK_DEBUGF ((", got FIN"));
00390         goto read_it;
00391       }
00392
00393       if (!ok)
00394       {
00395         socket->so_state |= (SS_CANTRCVMORE | SS_ISDISCONNECTING);
00396         socket->so_state &= ~SS_ISCONNECTED;
00397         SOCK_DEBUGF ((", EPIPE"));
00398         SOCK_ERRNO (EPIPE);  /* !! was ENOTCONN */
00399         return (-1);
00400       }
00401     }
00402
00403     if (sock_rbused(sk) > socket->recv_lowat)
00404     {
00405 read_it:
00406       if (flags & MSG_PEEK)
00407            ret = sock_preread (sk, (BYTE*)buf, len);
00408       else if (flags & MSG_WAITALL)
00409            ret = sock_read (sk, (BYTE*)buf, len);
00410       else ret = sock_fastread (sk, (BYTE*)buf, len);
00411       break;
00412     }
00413
00414     if (socket->so_state & SS_CONN_REFUSED)
00415     {
00416       SOCK_DEBUGF ((", ECONNREFUSED (2)"));
00417       SOCK_ERRNO (ECONNREFUSED);
00418       return (-1);
00419     }
00420
00421     if (socket->so_state & SS_NBIO)
00422     {
00423       SOCK_DEBUGF ((", EWOULDBLOCK"));
00424       SOCK_ERRNO (EWOULDBLOCK);
00425       return (-1);
00426     }
00427
00428     if (chk_timeout(timer))
00429     {
00430       SOCK_DEBUGF ((", ETIMEDOUT"));
00431       SOCK_ERRNO (ETIMEDOUT);
00432       return (-1);
00433     }
00434
00435     if (_sock_sig_pending())
00436     {
00437       SOCK_DEBUGF ((", EINTR"));
00438       SOCK_ERRNO (EINTR);
00439       return (-1);
00440     }
00441
00442     if (sk->tcp.usr_yield)
00443         (*sk->tcp.usr_yield)();
00444     else WATT_YIELD();
00445   }
00446
00447   if (ret > 0)
00448   {
00449     int sa_len = (socket->so_family == AF_INET6) ?
00450                    sizeof(struct sockaddr_in6) :
00451                    sizeof(struct sockaddr_in);
00452     if (from)
00453        memcpy (from, socket->remote_addr, sa_len);
00454     if (fromlen)
00455        *fromlen = sa_len;
00456     socket->keepalive = 0UL;  /* reset keep-alive timer */
00457   }
00458   else if (ret < 0)
00459   {
00460     if (got_fin)   /* A FIN and -1 from sock_xread() maps to 0 */
00461        ret = 0;
00462     else           /* else some buffer/socket error */
00463     {
00464       SOCK_DEBUGF ((", EIO"));
00465       SOCK_ERRNO (EIO);
00466     }
00467   }
00468   return (ret);
00469 }
00470
00471
00472 /*
00473  * UDP receiver
00474  */
00475 static int udp_receive (Socket *socket, void *buf, int len, int flags,
00476                         struct sockaddr *from, int *fromlen)
00477 {
00478   int   ret   = 0;
00479   DWORD timer = 0UL;
00480
00481   if (socket->timeout)
00482      timer = set_timeout (1000 * socket->timeout);
00483
00485 #if 0
00486   /* If bind() not called, allow data from anybody on any port !!
00487    */
00488   if (from && !socket->local_addr)
00489   {
00490     struct sockaddr_in addr = { AF_INET, 0, { INADDR_ANY }};
00491
00492     socket->so_state |= SS_PRIV;
00493
00494     if (_UDP_listen (socket, addr.sin_addr, addr.sin_port) < 0)
00495        return (-1);
00496   }
00497 #endif
00498
00499   while (1)
00500   {
00501     sock_type *sk = (sock_type*) socket->udp_sock;
00502     BOOL       ok = (tcp_tick(sk) != 0);
00503
00504     WATT_YIELD();
00505
00506     if (socket->so_error == ECONNREFUSED ||
00507         (sk->udp.locflags & LF_GOT_ICMP))
00508     {
00509       socket->so_state |= (SS_CANTRCVMORE | SS_CANTSENDMORE);
00510       SOCK_DEBUGF ((", ECONNREFUSED"));
00511       SOCK_ERRNO (ECONNREFUSED);
00512       return (-1);
00513     }
00514
00515     if (!ok)
00516     {
00517       socket->so_state |= (SS_CANTRCVMORE | SS_CANTSENDMORE);
00518       SOCK_DEBUGF ((", EPIPE"));
00519       SOCK_ERRNO (EPIPE);    /* !! was ENOTCONN */
00520       return (-1);
00521     }
00522
00523     tcp_Retransmitter (TRUE);
00524
00525     /* If this socket is for broadcast (or is unbound), check the
00526      * queue setup by sock_recv_init() (in _UDP_listen).
00527      * Note: it is possible to receive 0-byte probe packets.
00528      */
00529     if (socket->so_family == AF_INET && (socket->so_state & SS_PRIV))
00530     {
00531       struct in_addr peer = { 0 };
00532       sock_type     *udp  = (sock_type*)socket->udp_sock;
00533       WORD           port;
00534
00535       SOCK_ERRNO (0);
00536       ret = sock_recv_from (udp, &peer, &port, buf, len,
00537                             (flags & MSG_PEEK) ? 1 : 0);
00538
00539       if (ret && _w32_errno != EBADF && peer.s_addr)
00540       {
00541         udp_raw_fill_from_ip4 (from, fromlen, &peer, port);
00542         SOCK_DEBUGF ((", 1: remote: %s (%d)", inet_ntoa(peer), ntohs(port)));
00543
00544         if (ret < 0)   /* 0-byte probe */
00545            return (0);
00546         return (ret);
00547       }
00548     }
00549
00550 #if defined(USE_IPV6)
00551     else if (socket->so_family == AF_INET6 && (socket->so_state & SS_PRIV))
00552     {
00553       struct in6_addr peer;
00554       sock_type      *udp = (sock_type*) socket->udp_sock;
00555       WORD            port;
00556
00557       SOCK_ERRNO (0);
00558       memcpy (&peer, &in6addr_any, sizeof(peer));
00559       ret = sock_recv_from (udp, &peer, &port, buf, len,
00560                             (flags & MSG_PEEK) ? 1 : 0);
00561
00562       if (ret && _w32_errno != EBADF && !IN6_IS_ADDR_UNSPECIFIED(&peer))
00563       {
00564         udp_raw_fill_from_ip6 (from, fromlen, &peer, port);
00565         SOCK_DEBUGF ((", 1: remote: %s (%d)", _inet6_ntoa(&peer), ntohs(port)));
00566
00567         if (ret < 0)   /* 0-byte probe */
00568            return (0);
00569         return (ret);
00570       }
00571     }
00572 #endif
00573
00574     else if (sock_rbused(sk) > socket->recv_lowat)
00575     {
00576       if (flags & MSG_PEEK)
00577            ret = sock_preread  (sk, (BYTE*)buf, len);
00578       else if (flags & MSG_WAITALL)
00579            ret = sock_read     (sk, (BYTE*)buf, len);
00580       else ret = sock_fastread (sk, (BYTE*)buf, len);
00581       break;
00582     }
00583
00584     if (socket->so_state & SS_CONN_REFUSED)
00585     {
00586       SOCK_DEBUGF ((", ECONNREFUSED (2)"));
00587       SOCK_ERRNO (ECONNREFUSED);
00588       return (-1);
00589     }
00590
00591     if (socket->so_state & SS_NBIO)
00592     {
00593       SOCK_DEBUGF ((", EWOULDBLOCK"));
00594       SOCK_ERRNO (EWOULDBLOCK);
00595       return (-1);
00596     }
00597
00598     if (chk_timeout(timer))
00599     {
00600       SOCK_DEBUGF ((", ETIMEDOUT"));
00601       SOCK_ERRNO (ETIMEDOUT);
00602       return (-1);
00603     }
00604
00605     if (_sock_sig_pending())
00606     {
00607       SOCK_DEBUGF ((", EINTR"));
00608       SOCK_ERRNO (EINTR);
00609       return (-1);
00610     }
00611   }
00612
00613   if (ret > 0)
00614   {
00615 #if defined(USE_IPV6)
00616     if (socket->so_family == AF_INET6)
00617     {
00618       WORD        port = htons (socket->udp_sock->hisport);
00619       const void *peer = &socket->udp_sock->his6addr[0];
00620
00621       udp_raw_fill_from_ip6 (from, fromlen, peer, port);
00622
00623       if (socket->remote_addr)
00624       {
00625         struct sockaddr_in6 *ra = (struct sockaddr_in6*)socket->remote_addr;
00626
00627         ra->sin6_family = AF_INET6;
00628         ra->sin6_port   = port;
00629         memcpy (&ra->sin6_addr, peer, sizeof(ra->sin6_addr));
00630       }
00631       SOCK_DEBUGF ((", 2: remote: %s (%d)", _inet6_ntoa(peer), ntohs(port)));
00632     }
00633     else
00634 #endif
00635     {
00636       struct in_addr peer;
00637       _udp_Socket   *udp = socket->udp_sock;
00638       WORD           port;
00639
00640       port = htons (udp->hisport);
00641       peer.s_addr = htonl (udp->hisaddr);
00642
00643       udp_raw_fill_from_ip4 (from, fromlen, &peer, port);
00644
00645       if (socket->remote_addr)
00646       {
00647         socket->remote_addr->sin_family = AF_INET;
00648         socket->remote_addr->sin_addr   = peer;
00649         socket->remote_addr->sin_port   = port;
00650       }
00651       SOCK_DEBUGF ((", 2: remote: %s (%d)", inet_ntoa(peer), ntohs(port)));
00652     }
00653   }
00654   return (ret);
00655 }
00656
00657
00658 /*
00659  * Raw-IP receiver. Doesn't handle IP-options yet.
00660  */
00661 static int raw_receive (Socket *socket, void *buf, unsigned len, int flags,
00662                         struct sockaddr *from, int *fromlen)
00663 {
00664   _raw_Socket *raw = NULL;
00665   DWORD timer, loop;
00666
00667 #if defined(USE_IPV6)
00668   _raw6_Socket *raw6 = NULL;
00669
00670   if (socket->so_family == AF_INET6)
00671   {
00672     if (len < sizeof(raw6->ip6))
00673     {
00674       SOCK_DEBUGF (("EINVAL"));
00675       SOCK_ERRNO (EINVAL);
00676       return (-1);
00677     }
00678   }
00679   else
00680 #endif
00681   if (len < sizeof(raw->ip))
00682   {
00683     SOCK_DEBUGF (("EINVAL"));
00684     SOCK_ERRNO (EINVAL);
00685     return (-1);
00686   }
00687
00688   if (socket->timeout)
00689        timer = set_timeout (1000 * socket->timeout);
00690   else timer = 0;
00691   loop = 1;
00692
00693   while (1)
00694   {
00695     unsigned ip_len, hdr_len;
00696
00697     /* give sock_rbused() and memcpy() below a chance to run
00698      * before sock_raw_recv() (via tcp_tick) drops a packet
00699      */
00700     if (loop++ > 1)
00701     {
00702       tcp_tick (NULL);
00703       tcp_Retransmitter (TRUE);
00704     }
00705
00706 #if defined(USE_IPV6)
00707     if (socket->so_family == AF_INET6)
00708     {
00709       raw6    = (_raw6_Socket*) find_oldest_raw6 (socket->raw6_sock);
00710       ip_len  = raw6 ? intel16 (raw6->ip6.len) : 0;
00711       hdr_len = sizeof(in6_Header);
00712     }
00713     else
00714 #endif
00715     {
00716       raw     = (_raw_Socket*) find_oldest_raw (socket->raw_sock);
00717       ip_len  = raw ? intel16 (raw->ip.length) : 0; /* includes header length */
00718       hdr_len = sizeof(in_Header);
00719     }
00720
00721 #if defined(USE_IPV6)
00722     if (socket->so_family == AF_INET6)
00723     {
00724       if (ip_len >= hdr_len + socket->recv_lowat)
00725       {
00726         struct in6_Header *ip6 = (struct in6_Header*) buf;
00727
00728         /* SOCK_RAW shall allway return IP-header and data in 'buf'
00729          */
00730         memcpy (ip6, &raw6->ip6, hdr_len);
00731         len = min (ip_len - hdr_len, len);
00732         if (len > 0)
00733            memcpy (++ip6, &raw6->rx_data[0], len);
00734
00735         raw6->used = FALSE;
00736
00737         udp_raw_fill_from_ip6 (from, fromlen, &raw6->ip6.source[0], 0);
00738         SOCK_DEBUGF ((", remote: %s", _inet6_ntoa(&raw6->ip6.source[0])));
00739         return (len + hdr_len);
00740       }
00741     }
00742     else
00743 #endif
00744     if (ip_len >= hdr_len + socket->recv_lowat)
00745     {
00746       struct in_addr    peer;
00747       struct in_Header *ip = (struct in_Header*) buf;
00748
00749       /* SOCK_RAW shall allway return IP-header and data in 'buf'
00750        */
00751       memcpy (ip, &raw->ip, hdr_len);
00752       len = min (ip_len - hdr_len, len);
00753       if (len > 0)
00754          memcpy (++ip, &raw->rx_data[0], len);
00755
00756       peer.s_addr = raw->ip.source;
00757       raw->used   = FALSE;
00758
00759       udp_raw_fill_from_ip4 (from, fromlen, &peer, 0);
00760       SOCK_DEBUGF ((", remote: %s", inet_ntoa(peer)));
00761       return (len + hdr_len);
00762     }
00763
00764     if (socket->so_state & SS_NBIO)
00765     {
00766       SOCK_DEBUGF ((", EWOULDBLOCK"));
00767       SOCK_ERRNO (EWOULDBLOCK);
00768       break;
00769     }
00770
00771     if (chk_timeout(timer))
00772     {
00773       SOCK_DEBUGF ((", ETIMEDOUT"));
00774       SOCK_ERRNO (ETIMEDOUT);
00775       break;
00776     }
00777
00778     if (_sock_sig_pending())
00779     {
00780       SOCK_DEBUGF ((", EINTR"));
00781       SOCK_ERRNO (EINTR);
00782       break;
00783     }
00784
00785     WATT_YIELD();
00786   }
00787
00788   ARGSUSED (flags);
00789   return (-1);
00790 }
00791 #endif  /* USE_BSD_API */
Generated on Wed Jan 25 15:42:38 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/REGISTER.H Source File

SRC/REGISTER.H

Go to the documentation of this file.
00001
00014 #ifndef _w32_REGISTER_H
00015 #define _w32_REGISTER_H
00016
00017 /*
00018  * Definition related to EFLAGS.
00019  */
00020 #define EFLAGS_CARRY                    0x1
00021 #define EFLAGS_PARITY                   0x4
00022
00023 #define EFLAGS_AUX_CARRY                0x10
00024 #define EFLAGS_ZERO                     0x40
00025 #define EFLAGS_SIGN                     0x80
00026
00027 #define EFLAGS_TRAP                     0x100
00028 #define EFLAGS_INTR_ENABLE              0x200
00029 #define EFLAGS_DIRECTION                0x400
00030 #define EFLAGS_OVERFLOW                 0x800
00031
00032 #define EFLAGS_IOPL_MASK                0x3000
00033 #define EFLAGS_NESTED_TASK              0x8000
00034
00035 #define EFLAGS_RESUME                   0x10000
00036 #define EFLAGS_VIRTUAL_MODE             0x20000
00037 #define EFLAGS_ALIGN_CHECK              0x40000
00038 #define EFLAGS_VIRTUAL_INTR             0x80000
00039
00040 #define EFLAGS_VIRTUAL_INTR_PEND        0x100000
00041 #define EFLAGS_ID                       0x200000
00042
00043 /*
00044  * Definitions related to CR0.
00045  */
00046 #define CR0_PROTECTION_ENABLE           0x1
00047 #define CR0_MONITOR_COPROC              0x2
00048 #define CR0_COPROC_SOFT_EMUL            0x4
00049 #define CR0_FLOATING_INSTR_EXCEPTION    0x8
00050
00051 #define CR0_EXTENSION_TYPE              0x10
00052 #define CR0_NUMERIC_ERROR               0x20
00053
00054 #define CR0_WRITE_PROTECT               0x10000
00055 #define CR0_ALIGMENT_MASK               0x40000
00056
00057 #define CR0_NO_WRITE_THROUGH            0x20000000
00058 #define CR0_PAGE_LEVEL_CACHE_DISABLE    0x40000000
00059 #define CR0_PAGING                      0x80000000
00060
00061 #if defined(IN_ASM_FILE)
00062   #if defined(__DJGPP__)
00063     #include <machine/asm.h>
00064     /* Use only after ".data" */
00065     #define DATA(x,type) .align 2; .globl _##x; _##x: type
00066   #else
00067     #define ENTRY(f)     .text; .p2align 4,,15; .globl _##f; _##f:
00068     #define DATA(x,type) .align 4; .globl _##x; _##x: type
00069     #define _C_LABEL(x)  _##x
00070   #endif
00071
00072 #else
00073
00074 /*
00075  * Definition of eflags registers has a bit field structure.
00076  */
00077 typedef struct {
00078   /*
00079    * first byte : bits 0->7
00080    */
00081   unsigned int carry                : 1;
00082   unsigned int                      : 1;
00083   unsigned int parity               : 1;
00084   unsigned int                      : 1;
00085
00086   unsigned int auxiliary_carry      : 1;
00087   unsigned int                      : 1;
00088   unsigned int zero                 : 1;      /* result is zero */
00089   unsigned int sign                 : 1;      /* result is less than zero */
00090   /*
00091    * Second byte : bits 7->15
00092    */
00093   unsigned int trap                 : 1;
00094   unsigned int intr_enable          : 1;      /* set => intr on */
00095   unsigned int direction            : 1;      /* set => autodecrement */
00096   unsigned int overflow             : 1;
00097
00098   unsigned int IO_privilege         : 2;
00099   unsigned int nested_task          : 1;
00100   unsigned int                      : 1;
00101   /*
00102    * Third byte : bits 15->23
00103    */
00104   unsigned int resume               : 1;
00105   unsigned int virtual_mode         : 1;
00106   unsigned int aligment_check       : 1;
00107   unsigned int virtual_intr         : 1;
00108   unsigned int virtual_intr_pending : 1;
00109   unsigned int id                   : 1;
00110   unsigned int                      : 2;
00111   /*
00112    * fourth byte : bits 24->31 : UNUSED
00113    */
00114   unsigned int                      : 8;
00115 } eflags_bits;
00116
00117 typedef union {
00118         eflags_bits   eflags;
00119         unsigned int  i;
00120       } eflags;
00121
00122 /*
00123  * Definition of CR registers has a bit field structure.
00124  */
00125 typedef struct {
00126   /*
00127    * first byte : bits 0->7
00128    */
00129   unsigned int protection_enable        : 1;
00130   unsigned int monitor_coproc           : 1;
00131   unsigned int coproc_soft_emul         : 1;
00132   unsigned int floating_instr_except    : 1;
00133
00134   unsigned int extension_type           : 1;
00135   unsigned int numeric_error            : 1;
00136   unsigned int                          : 2;
00137   /*
00138    * second byte 8->15 : UNUSED
00139    */
00140   unsigned int                          : 8;
00141   /*
00142    * third byte 16->23
00143    */
00144   unsigned int write_protect            : 1;
00145   unsigned int                          : 1;
00146   unsigned int aligment_mask            : 1;
00147   unsigned int                          : 1;
00148
00149   unsigned int                          : 4;
00150   /*
00151    * fourth byte 24->31
00152    */
00153   unsigned int                          : 4;
00154   unsigned int                          : 1;
00155   unsigned int no_write_through         : 1;
00156   unsigned int page_level_cache_disable : 1;
00157   unsigned int paging                   : 1;
00158 } cr0_bits;
00159
00160 typedef union {
00161         cr0_bits      cr0;
00162         unsigned long i;
00163       } cr0;
00164
00165 #endif  /* IN_ASM_FILE */
00166
00167 #endif
00168
Generated on Wed Jan 25 15:42:38 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/RES_COMP.C Source File

SRC/RES_COMP.C

Go to the documentation of this file.
00001
00005 /* ++Copyright++ 1985, 1993
00006  * -
00007  * Copyright (c) 1985, 1993
00008  *    The Regents of the University of California.  All rights reserved.
00009  *
00010  * Redistribution and use in source and binary forms, with or without
00011  * modification, are permitted provided that the following conditions
00012  * are met:
00013  * 1. Redistributions of source code must retain the above copyright
00014  *    notice, this list of conditions and the following disclaimer.
00015  * 2. Redistributions in binary form must reproduce the above copyright
00016  *    notice, this list of conditions and the following disclaimer in the
00017  *    documentation and/or other materials provided with the distribution.
00018  * 3. All advertising materials mentioning features or use of this software
00019  *    must display the following acknowledgement:
00020  *   This product includes software developed by the University of
00021  *   California, Berkeley and its contributors.
00022  * 4. Neither the name of the University nor the names of its contributors
00023  *    may be used to endorse or promote products derived from this software
00024  *    without specific prior written permission.
00025  *
00026  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
00027  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00028  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00029  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
00030  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00031  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00032  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00033  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00034  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00035  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00036  * SUCH DAMAGE.
00037  * -
00038  * Portions Copyright (c) 1993 by Digital Equipment Corporation.
00039  *
00040  * Permission to use, copy, modify, and distribute this software for any
00041  * purpose with or without fee is hereby granted, provided that the above
00042  * copyright notice and this permission notice appear in all copies, and that
00043  * the name of Digital Equipment Corporation not be used in advertising or
00044  * publicity pertaining to distribution of the document or software without
00045  * specific, written prior permission.
00046  *
00047  * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
00048  * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
00049  * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
00050  * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
00051  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
00052  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
00053  * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
00054  * SOFTWARE.
00055  * -
00056  * --Copyright--
00057  */
00058
00059 #include "resolver.h"
00060
00061 #if defined(USE_BIND)
00062
00063 static int mklower (int);
00064 static int dn_find (u_char *, u_char *, u_char **, u_char **);
00065
00066 /*
00067  * Expand compressed domain name 'comp_dn' to full domain name.
00068  * 'msg' is a pointer to the begining of the message,
00069  * 'eom_orig' points to the first location after the message,
00070  * 'exp_dn' is a pointer to a buffer of size 'length' for the result.
00071  * Return size of compressed name or -1 if there was an error.
00072  */
00073 int dn_expand (const u_char *msg, const u_char *eom_orig,
00074                const u_char *comp_dn, char *exp_dn, int length)
00075 {
00076   const u_char *cp;
00077   char *dn, *eom;
00078   int   n, len = -1, checked = 0;
00079
00080   dn  = exp_dn;
00081   cp  = comp_dn;
00082   eom = exp_dn + length;
00083
00084   /* Fetch next label in domain name
00085    */
00086   while ((n = *cp++) != 0)
00087   {
00088     /* Check for indirection
00089      */
00090     switch (n & INDIR_MASK)
00091     {
00092       case 0:
00093            if (dn != exp_dn)
00094            {
00095              if (dn >= eom)
00096                 return (-1);
00097              *dn++ = '.';
00098            }
00099            if (dn+n >= eom)
00100               return (-1);
00101            checked += n + 1;
00102            while (--n >= 0)
00103            {
00104              int c = *cp++;
00105              if ((c == '.') || (c == '\\'))
00106              {
00107                if (dn + n + 2 >= eom)
00108                   return (-1);
00109                *dn++ = '\\';
00110              }
00111              *dn++ = c;
00112              if (cp >= eom_orig)  /* out of range */
00113                 return (-1);
00114            }
00115            break;
00116
00117       case INDIR_MASK:
00118            if (len < 0)
00119               len = cp - comp_dn + 1;
00120            cp = msg + (((n & 0x3f) << 8) | (*cp & 0xff));
00121            if (cp < msg || cp >= eom_orig)  /* out of range */
00122               return (-1);
00123            checked += 2;
00124            /*
00125             * Check for loops in the compressed name;
00126             * if we've looked at the whole message,
00127             * there must be a loop.
00128             */
00129            if (checked >= eom_orig - msg)
00130               return (-1);
00131            break;
00132
00133       default:
00134            return (-1);      /* flag error */
00135     }
00136   }
00137
00138   *dn = '\0';
00139   {
00140     int c;
00141     for (dn = exp_dn; (c = *dn) != '\0'; dn++)
00142         if (isascii(c) && isspace(c))
00143            return (-1);
00144   }
00145
00146   if (len < 0)
00147      len = cp - comp_dn;
00148   return (len);
00149 }
00150
00151 /*
00152  * Compress domain name 'exp_dn' into 'comp_dn'.
00153  * Return the size of the compressed name or -1.
00154  * 'length' is the size of the array pointed to by 'comp_dn'.
00155  * 'dnptrs' is a list of pointers to previous compressed names. dnptrs[0]
00156  * is a pointer to the beginning of the message. The list ends with NULL.
00157  * 'lastdnptr' is a pointer to the end of the arrary pointed to
00158  * by 'dnptrs'. Side effect is to update the list of pointers for
00159  * labels inserted into the message as we compress the name.
00160  * If 'dnptr' is NULL, we don't try to compress names. If 'lastdnptr'
00161  * is NULL, we don't update the list.
00162  */
00163 int dn_comp (const char *exp_dn, u_char *comp_dn, int length,
00164              u_char **dnptrs, u_char **lastdnptr)
00165 {
00166   u_char  *cp, *dn;
00167   u_char **cpp, **lpp, *eob;
00168   u_char  *msg;
00169   u_char  *sp = NULL;
00170   int      c, l = 0;
00171
00172   dn  = (u_char *)exp_dn;
00173   cp  = comp_dn;
00174   eob = cp + length;
00175   lpp = cpp = NULL;
00176   if (dnptrs)
00177   {
00178     if ((msg = *dnptrs++) != NULL)
00179     {
00180       for (cpp = dnptrs; *cpp; cpp++)
00181           ;
00182       lpp = cpp;  /* end of list to search */
00183     }
00184   }
00185   else
00186     msg = NULL;
00187
00188   for (c = *dn++; c != '\0'; )
00189   {
00190     /* look to see if we can use pointers */
00191     if (msg)
00192     {
00193       if ((l = dn_find (dn-1, msg, dnptrs, lpp)) >= 0)
00194       {
00195         if (cp+1 >= eob)
00196            return (-1);
00197         *cp++ = (l >> 8) | INDIR_MASK;
00198         *cp++ = l % 256;
00199         return (cp - comp_dn);
00200       }
00201       /* not found, save it */
00202       if (lastdnptr && cpp < lastdnptr-1)
00203       {
00204         *cpp++ = cp;
00205         *cpp = NULL;
00206       }
00207     }
00208     sp = cp++;  /* save ptr to length byte */
00209     do
00210     {
00211       if (c == '.')
00212       {
00213         c = *dn++;
00214         break;
00215       }
00216       if (c == '\\')
00217       {
00218         if ((c = *dn++) == '\0')
00219            break;
00220       }
00221       if (cp >= eob)
00222       {
00223         if (msg)
00224            *lpp = NULL;
00225         return (-1);
00226       }
00227       *cp++ = c;
00228     }
00229     while ((c = *dn++) != '\0');
00230
00231     /* catch trailing '.'s but not '..' */
00232     if ((l = cp - sp - 1) == 0 && c == '\0')
00233     {
00234       cp--;
00235       break;
00236     }
00237     if (l <= 0 || l > MAXLABEL)
00238     {
00239       if (msg)
00240          *lpp = NULL;
00241       return (-1);
00242     }
00243     *sp = l;
00244   }
00245   if (cp >= eob)
00246   {
00247     if (msg)
00248        *lpp = NULL;
00249     return (-1);
00250   }
00251   *cp++ = '\0';
00252   return (cp - comp_dn);
00253 }
00254
00255 /*
00256  * Skip over a compressed domain name. Return the size or -1.
00257  */
00258 int __dn_skipname (const u_char *comp_dn, const u_char *eom)
00259 {
00260   const u_char *cp = comp_dn;
00261
00262   while (cp < eom)
00263   {
00264    int n = *cp++;
00265    if (!n)
00266       break;
00267
00268     /* check for indirection
00269      */
00270     switch (n & INDIR_MASK)
00271     {
00272       case 0:           /* normal case, n == len */
00273            cp += n;
00274            continue;
00275       case INDIR_MASK:  /* indirection */
00276            cp++;
00277            break;
00278       default:          /* illegal type */
00279            return (-1);
00280     }
00281     break;
00282   }
00283   if (cp > eom)
00284      return (-1);
00285   return (cp - comp_dn);
00286 }
00287
00288
00289 static int mklower (int ch)
00290 {
00291   if (isascii(ch) && isupper(ch))
00292      return (tolower(ch));
00293   return (ch);
00294 }
00295
00296 /*
00297  * Search for expanded name from a list of previously compressed names.
00298  * Return the offset from msg if found or -1.
00299  * dnptrs is the pointer to the first name on the list,
00300  * not the pointer to the start of the message.
00301  */
00302 static int dn_find (u_char *exp_dn, u_char *msg, u_char **dnptrs, u_char **lastdnptr)
00303 {
00304   u_char **cpp;
00305
00306   for (cpp = dnptrs; cpp < lastdnptr; cpp++)
00307   {
00308     u_char *dn = exp_dn;
00309     u_char *sp = *cpp;
00310     u_char *cp = *cpp;
00311     int     n;
00312
00313     while ((n = *cp++) != 0)
00314     {
00315       /*
00316        * check for indirection
00317        */
00318       switch (n & INDIR_MASK)
00319       {
00320         case 0:    /* normal case, n == len */
00321              while (--n >= 0)
00322              {
00323                if (*dn == '.')
00324                   goto next;
00325                if (*dn == '\\')
00326                   dn++;
00327                if (mklower(*dn++) != mklower(*cp++))
00328                   goto next;
00329              }
00330              if ((n = *dn++) == '\0' && *cp == '\0')
00331                 return (sp - msg);
00332              if (n == '.')
00333                 continue;
00334              goto next;
00335
00336         case INDIR_MASK:  /* indirection */
00337              cp = msg + (((n & 0x3f) << 8) | *cp);
00338              break;
00339
00340         default:          /* illegal type */
00341              return (-1);
00342       }
00343     }
00344     if (*dn == '\0')
00345       return (sp - msg);
00346     next: ;
00347   }
00348   return (-1);
00349 }
00350 #endif /* USE_BIND */
00351
Generated on Wed Jan 25 15:42:39 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/RES_DATA.C Source File

SRC/RES_DATA.C

Go to the documentation of this file.
00001
00005 /* ++Copyright++ 1995
00006  * -
00007  * Copyright (c) 1995
00008  *    The Regents of the University of California.  All rights reserved.
00009  *
00010  * Redistribution and use in source and binary forms, with or without
00011  * modification, are permitted provided that the following conditions
00012  * are met:
00013  * 1. Redistributions of source code must retain the above copyright
00014  *    notice, this list of conditions and the following disclaimer.
00015  * 2. Redistributions in binary form must reproduce the above copyright
00016  *    notice, this list of conditions and the following disclaimer in the
00017  *    documentation and/or other materials provided with the distribution.
00018  * 3. All advertising materials mentioning features or use of this software
00019  *    must display the following acknowledgement:
00020  *   This product includes software developed by the University of
00021  *   California, Berkeley and its contributors.
00022  * 4. Neither the name of the University nor the names of its contributors
00023  *    may be used to endorse or promote products derived from this software
00024  *    without specific prior written permission.
00025  *
00026  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
00027  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00028  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00029  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
00030  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00031  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00032  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00033  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00034  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00035  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00036  * SUCH DAMAGE.
00037  * -
00038  * Portions Copyright (c) 1993 by Digital Equipment Corporation.
00039  *
00040  * Permission to use, copy, modify, and distribute this software for any
00041  * purpose with or without fee is hereby granted, provided that the above
00042  * copyright notice and this permission notice appear in all copies, and that
00043  * the name of Digital Equipment Corporation not be used in advertising or
00044  * publicity pertaining to distribution of the document or software without
00045  * specific, written prior permission.
00046  *
00047  * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
00048  * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
00049  * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
00050  * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
00051  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
00052  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
00053  * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
00054  * SOFTWARE.
00055  * -
00056  * --Copyright--
00057  */
00058
00059 #include "resolver.h"
00060
00061 #if defined(USE_BSD_API) || defined(USE_BIND)
00062
00063 const char *_res_opcodes[] = {
00064            "QUERY",
00065            "IQUERY",
00066            "CQUERYM",
00067            "CQUERYU",  /* experimental */
00068            "NOTIFY",   /* experimental */
00069            "5",
00070            "6",
00071            "7",
00072            "8",
00073            "UPDATEA",
00074            "UPDATED",
00075            "UPDATEDA",
00076            "UPDATEM",
00077            "UPDATEMA",
00078            "ZONEINIT",
00079            "ZONEREF"
00080          };
00081
00082 const char *_res_resultcodes[] = {
00083            "NOERROR",
00084            "FORMERR",
00085            "SERVFAIL",
00086            "NXDOMAIN",
00087            "NOTIMP",
00088            "REFUSED",
00089            "6",
00090            "7",
00091            "8",
00092            "9",
00093            "10",
00094            "11",
00095            "12",
00096            "13",
00097            "14",
00098            "NOCHANGE"
00099          };
00100
00101 const char *h_errlist[] = {
00102            "Error 0",                          /* 0 NETDB_SUCCESS */
00103            "Unknown host",                     /* 1 HOST_NOT_FOUND */
00104            "Host name lookup failure",         /* 2 TRY_AGAIN */
00105            "Unknown server error",             /* 3 NO_RECOVERY */
00106            "No address associated with name",  /* 4 NO_ADDRESS / NO_DATA */
00107          };
00108
00109 int h_nerr = DIM (h_errlist);
00110
00111 /*
00112  * herror --
00113  *  print the error indicated by the h_errno value.
00114  */
00115 void W32_CALL herror (const char *prefix)
00116 {
00117   if (prefix && *prefix)
00118      fprintf (stderr, "%s :", prefix);
00119
00120   fputs (hstrerror(h_errno), stderr);
00121
00122 #ifdef __DJGPP__
00123   fputc ('\n', stderr); /* only djgpp(?) use newline, ref. perror() */
00124 #endif
00125 }
00126
00127 const char * W32_CALL hstrerror (int err)
00128 {
00129   if (err < 0)
00130      return ("Resolver internal error");
00131   if (err < h_nerr)
00132      return (h_errlist[err]);
00133   return ("Unknown resolver error");
00134 }
00135 #endif /* USE_BSD_API || USE_BIND */
00136
Generated on Wed Jan 25 15:42:39 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/RES_DEBU.C Source File

SRC/RES_DEBU.C

Go to the documentation of this file.
00001
00005 /* ++Copyright++ 1985, 1990, 1993
00006  * -
00007  * Copyright (c) 1985, 1990, 1993
00008  *    The Regents of the University of California.  All rights reserved.
00009  *
00010  * Redistribution and use in source and binary forms, with or without
00011  * modification, are permitted provided that the following conditions
00012  * are met:
00013  * 1. Redistributions of source code must retain the above copyright
00014  *    notice, this list of conditions and the following disclaimer.
00015  * 2. Redistributions in binary form must reproduce the above copyright
00016  *    notice, this list of conditions and the following disclaimer in the
00017  *    documentation and/or other materials provided with the distribution.
00018  * 3. All advertising materials mentioning features or use of this software
00019  *    must display the following acknowledgement:
00020  *   This product includes software developed by the University of
00021  *   California, Berkeley and its contributors.
00022  * 4. Neither the name of the University nor the names of its contributors
00023  *    may be used to endorse or promote products derived from this software
00024  *    without specific prior written permission.
00025  *
00026  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
00027  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00028  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00029  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
00030  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00031  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00032  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00033  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00034  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00035  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00036  * SUCH DAMAGE.
00037  * -
00038  * Portions Copyright (c) 1993 by Digital Equipment Corporation.
00039  *
00040  * Permission to use, copy, modify, and distribute this software for any
00041  * purpose with or without fee is hereby granted, provided that the above
00042  * copyright notice and this permission notice appear in all copies, and that
00043  * the name of Digital Equipment Corporation not be used in advertising or
00044  * publicity pertaining to distribution of the document or software without
00045  * specific, written prior permission.
00046  *
00047  * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
00048  * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
00049  * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
00050  * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
00051  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
00052  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
00053  * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
00054  * SOFTWARE.
00055  * -
00056  * --Copyright--
00057  */
00058
00059 #include "resolver.h"
00060
00061 #if defined(USE_BIND)
00062
00063 static const char *dewks (int wks)
00064 {
00065   static char buf[20];
00066
00067   switch (wks)
00068   {
00069     case 5:   return "rje";
00070     case 7:   return "echo";
00071     case 9:   return "discard";
00072     case 11:  return "systat";
00073     case 13:  return "daytime";
00074     case 15:  return "netstat";
00075     case 17:  return "qotd";
00076     case 19:  return "chargen";
00077     case 20:  return "ftp-data";
00078     case 21:  return "ftp";
00079     case 23:  return "telnet";
00080     case 25:  return "smtp";
00081     case 37:  return "time";
00082     case 39:  return "rlp";
00083     case 42:  return "name";
00084     case 43:  return "whois";
00085     case 53:  return "domain";
00086     case 57:  return "apts";
00087     case 59:  return "apfs";
00088     case 67:  return "bootps";
00089     case 68:  return "bootpc";
00090     case 69:  return "tftp";
00091     case 77:  return "rje";
00092     case 79:  return "finger";
00093     case 87:  return "link";
00094     case 95:  return "supdup";
00095     case 100: return "newacct";
00096     case 101: return "hostnames";
00097     case 102: return "iso-tsap";
00098     case 103: return "x400";
00099     case 104: return "x400-snd";
00100     case 105: return "csnet-ns";
00101     case 109: return "pop-2";
00102     case 111: return "sunrpc";
00103     case 113: return "auth";
00104     case 115: return "sftp";
00105     case 117: return "uucp-path";
00106     case 119: return "nntp";
00107     case 121: return "erpc";
00108     case 123: return "ntp";
00109     case 133: return "statsrv";
00110     case 136: return "profile";
00111     case 144: return "NeWS";
00112     case 161: return "snmp";
00113     case 162: return "snmp-trap";
00114     case 170: return "print-srv";
00115   }
00116   return itoa (wks, buf, 10);
00117 }
00118
00119 static const char *deproto (int protonum)
00120 {
00121   static char buf[20];
00122
00123   switch (protonum)
00124   {
00125     case 1:  return "icmp";
00126     case 2:  return "igmp";
00127     case 3:  return "ggp";
00128     case 5:  return "st";
00129     case 6:  return "tcp";
00130     case 7:  return "ucl";
00131     case 8:  return "egp";
00132     case 9:  return "igp";
00133     case 11: return "nvp-II";
00134     case 12: return "pup";
00135     case 16: return "chaos";
00136     case 17: return "udp";
00137   }
00138   return itoa (protonum, buf, 10);
00139 }
00140
00141 static const u_char *do_rrset (const u_char *msg, int len, const u_char *cp,
00142                                int cnt, int pflag, FILE *file, const char *hs)
00143 {
00144   int n, sflag;
00145
00146   /* Print answer records.
00147    */
00148   sflag = (_res.pfcode & pflag);
00149   if ((n = ntohs(cnt)) != 0)
00150   {
00151     if (!_res.pfcode || (sflag && (_res.pfcode & RES_PRF_HEAD1)))
00152        fprintf (file, "%s", hs);
00153
00154     while (--n >= 0)
00155     {
00156       if ((!_res.pfcode) || sflag)
00157          cp = __p_rr (cp, msg, file);
00158       else
00159       {
00160         unsigned dlen;
00161
00162         cp += __dn_skipname (cp, cp + MAXCDNAME);
00163         cp += INT16SZ;
00164         cp += INT16SZ;
00165         cp += INT32SZ;
00166         dlen = _getshort ((u_char*)cp);
00167         cp += INT16SZ;
00168         cp += dlen;
00169       }
00170       if ((cp - msg) > len)
00171          return (NULL);
00172     }
00173     if (!_res.pfcode || (sflag && (_res.pfcode & RES_PRF_HEAD1)))
00174        putc ('\n', file);
00175   }
00176   return (cp);
00177 }
00178
00179 void __p_query (const u_char *msg)
00180 {
00181   __fp_query (msg,stdout);
00182 }
00183
00184
00185 /*
00186  * Print the current options.
00187  * This is intended to be primarily a debugging routine.
00188  */
00189 void __fp_resstat (struct __res_state *statp, FILE *file)
00190 {
00191   u_long mask;
00192
00193   fprintf (file, ";; res options:");
00194   if (!statp)
00195      statp = &_res;
00196   for (mask = 1; mask; mask <<= 1)
00197       if (statp->options & mask)
00198          fprintf (file, " %s", p_option(mask));
00199   putc ('\n', file);
00200 }
00201
00202 /*
00203  * Print the contents of a query.
00204  * This is intended to be primarily a debugging routine.
00205  */
00206 void __fp_nquery (const u_char *msg, int len, FILE *file)
00207 {
00208   const u_char *cp, *endMark;
00209   const HEADER *hp;
00210   int   n, tline;
00211
00212   if (!(_res.options & RES_INIT) && res_init() == -1)
00213      return;
00214
00215 #define TruncTest(x) do {                   \
00216                        if (x >= endMark) {  \
00217                           tline = __LINE__; \
00218                           goto trunc;       \
00219                        }                    \
00220                      } while (0)
00221
00222 #define ErrorTest(x) do {                   \
00223                        if (x == NULL) {     \
00224                           tline = __LINE__; \
00225                           goto error;       \
00226                        }                    \
00227                      } while (0)
00228
00229   /* Print header fields.
00230    */
00231   hp = (HEADER *)msg;
00232   cp = msg + HFIXEDSZ;
00233   endMark = cp + len;
00234
00235   if (!_res.pfcode || (_res.pfcode & RES_PRF_HEADX) || hp->rcode)
00236   {
00237     fprintf (file, ";; ->>HEADER<<- opcode: %s, status: %s, id: %d",
00238              _res_opcodes[hp->opcode], _res_resultcodes[hp->rcode],
00239              ntohs(hp->id));
00240     putc ('\n', file);
00241   }
00242   if (!_res.pfcode || (_res.pfcode & RES_PRF_HEADX))
00243      putc (';', file);
00244
00245   if (!_res.pfcode || (_res.pfcode & RES_PRF_HEAD2))
00246   {
00247     fprintf (file, "; flags:");
00248     if (hp->qr) fprintf (file, " qr");
00249     if (hp->aa) fprintf (file, " aa");
00250     if (hp->tc) fprintf (file, " tc");
00251     if (hp->rd) fprintf (file, " rd");
00252     if (hp->ra) fprintf (file, " ra");
00253   }
00254   if (!_res.pfcode || (_res.pfcode & RES_PRF_HEAD1))
00255   {
00256     fprintf (file, "; Ques: %d", ntohs(hp->qdcount));
00257     fprintf (file, ", Ans: %d",  ntohs(hp->ancount));
00258     fprintf (file, ", Auth: %d", ntohs(hp->nscount));
00259     fprintf (file, ", Addit: %d",ntohs(hp->arcount));
00260   }
00261   if (!_res.pfcode ||
00262       (_res.pfcode & (RES_PRF_HEADX | RES_PRF_HEAD2 | RES_PRF_HEAD1)))
00263      putc ('\n', file);
00264
00265   /* Print question records.
00266    */
00267   n = ntohs (hp->qdcount);
00268   if (n != 0)
00269   {
00270     if (!_res.pfcode || (_res.pfcode & RES_PRF_QUES))
00271        fprintf (file, ";; QUESTIONS:\n");
00272
00273     while (--n >= 0)
00274     {
00275       if (!_res.pfcode || (_res.pfcode & RES_PRF_QUES))
00276          fprintf (file, ";;\t");
00277       TruncTest (cp);
00278       if (!_res.pfcode || (_res.pfcode & RES_PRF_QUES))
00279          cp = p_cdnname (cp, msg, len, file);
00280       else
00281       {
00282         char name[MAXDNAME];
00283         int  n = dn_expand (msg, msg+len, cp, name, sizeof(name));
00284
00285         if (n < 0)
00286              cp = NULL;
00287         else cp += n;
00288       }
00289       ErrorTest (cp);
00290       TruncTest (cp);
00291       if (!_res.pfcode || (_res.pfcode & RES_PRF_QUES))
00292          fprintf (file, ", type = %s", __p_type(_getshort((u_char*)cp)));
00293       cp += INT16SZ;
00294
00295       TruncTest (cp);
00296       if (!_res.pfcode || (_res.pfcode & RES_PRF_QUES))
00297          fprintf (file, ", class = %s\n", __p_class(_getshort((u_char*)cp)));
00298       cp += INT16SZ;
00299
00300       if (!_res.pfcode || (_res.pfcode & RES_PRF_QUES))
00301          putc ('\n', file);
00302     }
00303   }
00304   /* Print authoritative answer records
00305    */
00306   TruncTest (cp);
00307   cp = do_rrset (msg, len, cp, hp->ancount, RES_PRF_ANS, file,
00308                  ";; ANSWERS:\n");
00309   ErrorTest (cp);
00310
00311   /* print name server records
00312    */
00313   TruncTest (cp);
00314   cp = do_rrset (msg, len, cp, hp->nscount, RES_PRF_AUTH, file,
00315                  ";; AUTHORITY RECORDS:\n");
00316   ErrorTest (cp);
00317   TruncTest (cp);
00318
00319   /* print additional records
00320    */
00321   cp = do_rrset (msg, len, cp, hp->arcount, RES_PRF_ADD, file,
00322                  ";; ADDITIONAL RECORDS:\n");
00323   ErrorTest(cp);
00324   return;
00325
00326 trunc:
00327   fprintf (file, "\n;; ...truncated (%s, line %d)\n", __FILE__, tline);
00328   return;
00329
00330 error:
00331   fprintf (file, "\n;; ...malformed (%s, line %d)\n", __FILE__, tline);
00332 }
00333
00334 void __fp_query (const u_char *msg, FILE *file)
00335 {
00336   fp_nquery (msg, PACKETSZ, file);
00337 }
00338
00339 const u_char *__p_cdnname (const u_char *cp, const u_char *msg,
00340                            int len, FILE *file)
00341 {
00342   char name[MAXDNAME];
00343   int  n;
00344
00345   if ((n = dn_expand(msg, msg + len, cp, name, sizeof name)) < 0)
00346      return (NULL);
00347   if (name[0] == '\0')
00348        putc ('.', file);
00349   else fputs (name, file);
00350   return (cp + n);
00351 }
00352
00353 const u_char *__p_cdname (const u_char *cp, const u_char *msg, FILE *file)
00354 {
00355   return (p_cdnname(cp, msg, PACKETSZ, file));
00356 }
00357
00358 /* XXX:  the rest of these functions need to become length-limited, too. (vix)
00359  */
00360
00361 const u_char *__p_fqname (const u_char *cp, const u_char *msg, FILE *file)
00362 {
00363   char name[MAXDNAME];
00364   int  n = dn_expand (msg, cp + MAXCDNAME, cp, name, sizeof(name));
00365
00366   if (n < 0)
00367      return (NULL);
00368
00369   if (name[0] == '\0')
00370      putc ('.', file);
00371   else
00372   {
00373     fputs (name, file);
00374     if (name[strlen(name)-1] != '.')
00375        putc ('.', file);
00376   }
00377   return (cp + n);
00378 }
00379
00380 /*
00381  * Print resource record fields in human readable form.
00382  */
00383 const u_char *__p_rr (const u_char *cp, const u_char *msg, FILE *file)
00384 {
00385   struct in_addr inaddr;
00386   const  u_char *cp1, *cp2;
00387   int    type, Class, dlen;
00388   int    n = 0, c = 0;
00389   int    lcnt;
00390   u_long tmpttl, t;
00391
00392   if (!(_res.options & RES_INIT) && res_init() == -1)
00393   {
00394     h_errno = NETDB_INTERNAL;
00395     return (NULL);
00396   }
00397
00398   cp = p_fqname (cp, msg, file);
00399   if (!cp)
00400      return (NULL);      /* compression error */
00401
00402   type   = _getshort ((u_char*)cp);
00403   cp    += INT16SZ;
00404   Class  = _getshort ((u_char*)cp);
00405   cp    += INT16SZ;
00406   tmpttl = _getlong ((u_char*)cp);
00407   cp    += INT32SZ;
00408   dlen   = _getshort ((u_char*)cp);
00409   cp    += INT16SZ;
00410   cp1    = cp;
00411
00412   if (!_res.pfcode || (_res.pfcode & RES_PRF_TTLID))
00413      fprintf (file, "\t%lu", (u_long)tmpttl);
00414
00415   if (!_res.pfcode || (_res.pfcode & RES_PRF_CLASS))
00416      fprintf (file, "\t%s", __p_class(Class));
00417
00418   fprintf (file, "\t%s", __p_type(type));
00419
00420   /* Print type specific data, if appropriate
00421    */
00422   switch (type)
00423   {
00424     case T_A:
00425          switch (Class)
00426          {
00427            case C_IN:
00428            case C_HS:
00429                 memcpy (&inaddr, cp, INADDRSZ);
00430                 if (dlen == 4)
00431                 {
00432                   fprintf (file, "\t%s", inet_ntoa(inaddr));
00433                   cp += dlen;
00434                 }
00435                 else if (dlen == 7)
00436                 {
00437                   char   *address;
00438                   u_char  protocol;
00439                   u_short port;
00440
00441                   address = inet_ntoa (inaddr);
00442                   cp += INADDRSZ;
00443                   protocol = *(u_char*)cp;
00444                   cp += sizeof(u_char);
00445                   port = _getshort ((u_char*)cp);
00446                   cp += INT16SZ;
00447                   fprintf (file, "\t%s\t; proto %d, port %d",
00448                            address, protocol, port);
00449                 }
00450                 break;
00451            default:
00452                 cp += dlen;
00453          }
00454          break;
00455
00456     case T_CNAME:
00457     case T_MB:
00458     case T_MG:
00459     case T_MR:
00460     case T_NS:
00461     case T_PTR:
00462          putc ('\t', file);
00463          cp = p_fqname (cp, msg, file);
00464          if (!cp)
00465             return (NULL);
00466          break;
00467
00468     case T_HINFO:
00469     case T_ISDN:
00470          cp2 = cp + dlen;
00471          n = *cp++;
00472          if (n != 0)
00473          {
00474            fprintf (file, "\t%.*s", n, cp);
00475            cp += n;
00476          }
00477          if ((cp < cp2) && (n = *cp++) != 0)
00478          {
00479            fprintf (file, "\t%.*s", n, cp);
00480            cp += n;
00481          }
00482          else if (type == T_HINFO)
00483                  fprintf (file, "\n;; *** Warning *** OS-type missing");
00484          break;
00485
00486     case T_SOA:
00487          putc ('\t', file);
00488          cp = p_fqname (cp, msg, file);
00489          if (!cp)
00490             return (NULL);
00491          putc (' ', file);
00492          cp = p_fqname (cp, msg, file);
00493          if (!cp)
00494             return (NULL);
00495          fputs (" (\n", file);
00496          t   = _getlong ((u_char*)cp);
00497          cp += INT32SZ;
00498          fprintf (file, "\t\t\t%lu\t; serial\n", (u_long)t);
00499          t   = _getlong ((u_char*)cp);
00500          cp += INT32SZ;
00501          fprintf (file, "\t\t\t%lu\t; refresh (%s)\n", (u_long)t, __p_time(t));
00502          t   = _getlong ((u_char*)cp);
00503          cp += INT32SZ;
00504          fprintf (file, "\t\t\t%lu\t; retry (%s)\n", (u_long)t, __p_time(t));
00505          t   = _getlong ((u_char*)cp);
00506          cp += INT32SZ;
00507          fprintf (file, "\t\t\t%lu\t; expire (%s)\n", (u_long)t, __p_time(t));
00508          t   = _getlong ((u_char*)cp);
00509          cp += INT32SZ;
00510          fprintf (file, "\t\t\t%lu )\t; minimum (%s)", (u_long)t, __p_time(t));
00511          break;
00512
00513     case T_MX:
00514     case T_AFSDB:
00515     case T_RT:
00516          fprintf (file, "\t%d ", _getshort((u_char*)cp));
00517          cp += INT16SZ;
00518          cp = p_fqname (cp, msg, file);
00519          if (!cp)
00520             return (NULL);
00521          break;
00522
00523     case T_PX:
00524          fprintf (file, "\t%d ", _getshort((u_char*)cp));
00525          cp += INT16SZ;
00526          cp = p_fqname (cp, msg, file);
00527          if (!cp)
00528             return (NULL);
00529          putc (' ', file);
00530          cp = p_fqname (cp, msg, file);
00531          if (!cp)
00532             return (NULL);
00533          break;
00534
00535     case T_TXT:
00536     case T_X25:
00537          fputs ("\t\"", file);
00538          cp2 = cp1 + dlen;
00539          while (cp < cp2)
00540          {
00541            n = (BYTE)*cp++;
00542            if (n != 0)
00543            {
00544              for (c = n; c > 0 && cp < cp2; c--)
00545                  if (*cp == '\n' || *cp == '"')
00546                  {
00547                    putc ('\\', file);
00548                    putc (*cp++, file);
00549                  }
00550                  else
00551                    putc (*cp++, file);
00552            }
00553          }
00554          putc ('"', file);
00555          break;
00556
00557     case T_NSAP:
00558          fprintf (file, "\t%s", inet_nsap_ntoa(dlen, cp, NULL));
00559          cp += dlen;
00560          break;
00561
00562     case T_MINFO:
00563     case T_RP:
00564          putc ('\t', file);
00565          cp = p_fqname (cp, msg, file);
00566          if (!cp)
00567             return (NULL);
00568          putc (' ', file);
00569          cp = p_fqname (cp, msg, file);
00570          if (!cp)
00571             return (NULL);
00572          break;
00573
00574     case T_UINFO:
00575          putc ('\t', file);
00576          fputs ((char*)cp, file);
00577          cp += dlen;
00578          break;
00579
00580     case T_UID:
00581     case T_GID:
00582          if (dlen == 4)
00583          {
00584            fprintf (file, "\t%u", (unsigned)_getlong((u_char*)cp));
00585            cp += INT32SZ;
00586          }
00587          break;
00588
00589     case T_WKS:
00590          if (dlen < INT32SZ + 1)
00591             break;
00592          memcpy (&inaddr, cp, INADDRSZ);
00593          cp += INT32SZ;
00594          fprintf (file, "\t%s %s ( ", inet_ntoa(inaddr), deproto((int)*cp));
00595          cp += sizeof(u_char);
00596          n = 0;
00597          lcnt = 0;
00598          while (cp < cp1 + dlen)
00599          {
00600            c = *cp++;
00601            do
00602            {
00603              if (c & 0200)
00604              {
00605                if (lcnt == 0)
00606                {
00607                  fputs ("\n\t\t\t", file);
00608                  lcnt = 5;
00609                }
00610                fputs (dewks(n), file);
00611                putc (' ', file);
00612                lcnt--;
00613              }
00614              c <<= 1;
00615            }
00616            while (++n & 07);
00617          }
00618          putc (')', file);
00619          break;
00620
00621 #if ALLOW_T_UNSPEC
00622     case T_UNSPEC:
00623          {
00624            int     numBytes = 8;
00625            u_char *dataPtr;
00626            int     i;
00627
00628            if (dlen < numBytes)
00629               numBytes = dlen;
00630            fprintf (file, "\tFirst %d bytes of hex data:", numBytes);
00631            for (i = 0, dataPtr = cp; i < numBytes; i++, dataPtr++)
00632                fprintf (file, " %x", *dataPtr);
00633            cp += dlen;
00634          }
00635          break;
00636 #endif
00637
00638     default:
00639          fprintf (file, "\t?%d?", type);
00640          cp += dlen;
00641   }
00642
00643 #if 0
00644   fprintf (file, "\t; dlen=%d, ttl %s\n", dlen, __p_time(tmpttl));
00645 #else
00646   putc ('\n', file);
00647 #endif
00648
00649   if (cp - cp1 != dlen)
00650   {
00651     fprintf (file, ";; packet size error (found %d, dlen was %d)\n",
00652              (int)(cp - cp1), dlen);
00653     cp = NULL;
00654   }
00655   return (cp);
00656 }
00657
00658 /*
00659  * Return a string for the type
00660  */
00661 const char *__p_type (int type)
00662 {
00663   static char buf[20];
00664
00665   switch (type)
00666   {
00667     case T_A:        return "A";
00668     case T_NS:       return "NS";
00669     case T_CNAME:    return "CNAME";
00670     case T_SOA:      return "SOA";
00671     case T_SRV:      return "SRV";
00672     case T_MB:       return "MB";
00673     case T_MG:       return "MG";
00674     case T_MR:       return "MR";
00675     case T_NULL:     return "NULL";
00676     case T_WKS:      return "WKS";
00677     case T_PTR:      return "PTR";
00678     case T_HINFO:    return "HINFO";
00679     case T_MINFO:    return "MINFO";
00680     case T_MX:       return "MX";
00681     case T_TXT:      return "TXT";
00682     case T_RP:       return "RP";
00683     case T_AFSDB:    return "AFSDB";
00684     case T_X25:      return "X25";
00685     case T_ISDN:     return "ISDN";
00686     case T_RT:       return "RT";
00687     case T_NSAP:     return "NSAP";
00688     case T_NSAP_PTR: return "NSAP_PTR";
00689     case T_SIG:      return "SIG";
00690     case T_KEY:      return "KEY";
00691     case T_PX:       return "PX";
00692     case T_GPOS:     return "GPOS";
00693     case T_AAAA:     return "AAAA";
00694     case T_LOC:      return "LOC";
00695     case T_AXFR:     return "AXFR";
00696     case T_MAILB:    return "MAILB";
00697     case T_MAILA:    return "MAILA";
00698     case T_ANY:      return "ANY";
00699     case T_UINFO:    return "UINFO";
00700     case T_UID:      return "UID";
00701     case T_GID:      return "GID";
00702     case T_WINS:     return "WINS";
00703     case T_WINSR:    return "WINS-R";
00704 #if ALLOW_T_UNSPEC
00705     case T_UNSPEC:   return "UNSPEC";
00706 #endif
00707   }
00708   return itoa (type, buf, 10);
00709 }
00710
00711 /*
00712  * Return a mnemonic for class
00713  */
00714 const char *__p_class (int Class)
00715 {
00716   static char buf[20];
00717
00718   switch (Class)
00719   {
00720     case C_IN:
00721          return ("IN");
00722     case C_HS:
00723          return ("HS");
00724     case C_ANY:
00725          return ("ANY");
00726   }
00727   return itoa (Class, buf, 10);
00728 }
00729
00730 /*
00731  * Return a mnemonic for an option
00732  */
00733 const char * __p_option (u_long option)
00734 {
00735   static char buf[40];
00736
00737   switch (option)
00738   {
00739     case RES_INIT:      return "init";
00740     case RES_DEBUG:     return "debug";
00741     case RES_AAONLY:    return "aaonly(unimpl)";
00742     case RES_USEVC:     return "usevc";
00743     case RES_PRIMARY:   return "primry(unimpl)";
00744     case RES_IGNTC:     return "igntc";
00745     case RES_RECURSE:   return "recurs";
00746     case RES_DEFNAMES:  return "defnam";
00747     case RES_STAYOPEN:  return "styopn";
00748     case RES_DNSRCH:    return "dnsrch";
00749     case RES_INSECURE1: return "insecure1";
00750     case RES_INSECURE2: return "insecure2";
00751   }
00752   sprintf (buf, "?0x%lx?", option);
00753   return (buf);
00754 }
00755
00756 /*
00757  * Return a mnemonic for a time to live
00758  */
00759 char * __p_time (u_long value)
00760 {
00761   static char buf[120];
00762   int    secs, mins, hours, days;
00763   char  *p;
00764
00765   if (value == 0)
00766   {
00767     strcpy (buf, "0 secs");
00768     return (buf);
00769   }
00770
00771   secs = value % 60;
00772   value /= 60;
00773   mins = value % 60;
00774   value /= 60;
00775   hours = value % 24;
00776   value /= 24;
00777   days = value;
00778   value = 0;
00779
00780 #define PLURALISE(x)  x, (x == 1) ? "" : "s"
00781   p = buf;
00782   if (days)
00783   {
00784     sprintf (p, "%d day%s", PLURALISE(days));
00785     while (*++p) ;
00786   }
00787   if (hours)
00788   {
00789     if (days)
00790        *p++ = ' ';
00791     sprintf (p, "%d hour%s", PLURALISE(hours));
00792     while (*++p) ;
00793   }
00794   if (mins)
00795   {
00796     if (days || hours)
00797        *p++ = ' ';
00798     sprintf (p, "%d min%s", PLURALISE(mins));
00799     while (*++p) ;
00800   }
00801   if (secs || ! (days || hours || mins))
00802   {
00803     if (days || hours || mins)
00804        *p++ = ' ';
00805     sprintf (p, "%d sec%s", PLURALISE(secs));
00806   }
00807   return (buf);
00808 }
00809 #endif /* USE_BIND */
00810
Generated on Wed Jan 25 15:42:39 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/RES_INIT.C Source File

SRC/RES_INIT.C

Go to the documentation of this file.
00001
00005 /* ++Copyright++ 1985, 1989, 1993
00006  * -
00007  * Copyright (c) 1985, 1989, 1993
00008  *    The Regents of the University of California.  All rights reserved.
00009  *
00010  * Redistribution and use in source and binary forms, with or without
00011  * modification, are permitted provided that the following conditions
00012  * are met:
00013  * 1. Redistributions of source code must retain the above copyright
00014  *    notice, this list of conditions and the following disclaimer.
00015  * 2. Redistributions in binary form must reproduce the above copyright
00016  *    notice, this list of conditions and the following disclaimer in the
00017  *    documentation and/or other materials provided with the distribution.
00018  * 3. All advertising materials mentioning features or use of this software
00019  *    must display the following acknowledgement:
00020  *   This product includes software developed by the University of
00021  *   California, Berkeley and its contributors.
00022  * 4. Neither the name of the University nor the names of its contributors
00023  *    may be used to endorse or promote products derived from this software
00024  *    without specific prior written permission.
00025  *
00026  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
00027  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00028  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00029  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
00030  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00031  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00032  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00033  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00034  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00035  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00036  * SUCH DAMAGE.
00037  * -
00038  * Portions Copyright (c) 1993 by Digital Equipment Corporation.
00039  *
00040  * Permission to use, copy, modify, and distribute this software for any
00041  * purpose with or without fee is hereby granted, provided that the above
00042  * copyright notice and this permission notice appear in all copies, and that
00043  * the name of Digital Equipment Corporation not be used in advertising or
00044  * publicity pertaining to distribution of the document or software without
00045  * specific, written prior permission.
00046  *
00047  * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
00048  * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
00049  * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
00050  * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
00051  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
00052  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
00053  * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
00054  * SOFTWARE.
00055  * -
00056  * --Copyright--
00057  */
00058
00059 #include "resolver.h"
00060
00061 #if defined(USE_BIND)
00062
00063 /*----------------- info about "sortlist" -----------------------------
00064  *
00065  * Marc Majka    1994/04/16
00066  * Allan Nathanson  1994/10/29 (BIND 4.9.3.x)
00067  *
00068  * NetInfo resolver configuration directory support.
00069  *
00070  * Allow a NetInfo directory to be created in the hierarchy which
00071  * contains the same information as the resolver configuration file.
00072  *
00073  * - The local domain name is stored as the value of the "domain" property.
00074  * - The Internet address(es) of the name server(s) are stored as values
00075  *   of the "nameserver" property.
00076  * - The name server addresses are stored as values of the "nameserver"
00077  *   property.
00078  * - The search list for host-name lookup is stored as values of the
00079  *   "search" property.
00080  * - The sortlist comprised of IP address netmask pairs are stored as
00081  *   values of the "sortlist" property. The IP address and optional netmask
00082  *   should be seperated by a slash (/) or ampersand (&) character.
00083  * - Internal resolver variables can be set from the value of the "options"
00084  *   property.
00085  */
00086
00087 #undef  is_it
00088 #define is_it(cp,x)      !strncmp(cp,x,sizeof(x)-1)
00089
00090 #ifndef INADDR_LOOPBACK
00091 #define INADDR_LOOPBACK  (u_long)0x7F000001
00092 #endif
00093
00094 char *res_cfg_options = NULL; /* resolver options */
00095 char *res_cfg_aliases = NULL; /* hostaliases file */
00096
00097 /*
00098  * Resolver state default settings.
00099  */
00100 struct __res_state _res;
00101
00102 static void res_setoptions (char *options, char *source)
00103 {
00104   char *cp = options;
00105
00106   if (_res.options & RES_DEBUG)
00107      (*_printf) (";; res_setoptions(\"%s\", \"%s\")...\n", options, source);
00108
00109   while (*cp)
00110   {
00111     /* skip leading and inner runs of spaces
00112      */
00113     while (*cp == ' ' || *cp == '\t')
00114           ++cp;
00115
00116     /* search for and process individual options
00117      */
00118     if (is_it(cp,"ndots:"))
00119     {
00120       int i = atoi (cp + sizeof("ndots:") - 1);
00121
00122       if (i <= RES_MAXNDOTS)
00123            _res.ndots = i;
00124       else _res.ndots = RES_MAXNDOTS;
00125
00126       if (_res.options & RES_DEBUG)
00127          (*_printf) (";;\tndots=%d\n", _res.ndots);
00128     }
00129     else if (is_it(cp,"debug"))
00130     {
00131       if (!(_res.options & RES_DEBUG))
00132       {
00133         (*_printf) (";; res_setoptions(\"%s\", \"%s\")..\n", options, source);
00134         _res.options |= RES_DEBUG;
00135       }
00136       (*_printf) (";;\tdebug\n");
00137     }
00138     else
00139     {
00140       /* XXX - print a warning here? */
00141     }
00142     /* skip to next run of spaces
00143      */
00144     while (*cp && *cp != ' ' && *cp != '\t')
00145           cp++;
00146   }
00147 }
00148
00149 u_int16_t res_randomid (void)
00150 {
00151   return (0xFFFF & rand());
00152 }
00153
00154
00155 /*
00156  * Set up default settings.  If the configuration file exist, the values
00157  * there will have precedence.  Otherwise, the server address is set to
00158  * INADDR_ANY and the default domain name comes from the gethostname().
00159  *
00160  * An interrim version of this code (BIND 4.9, pre-4.4BSD) used 127.0.0.1
00161  * rather than INADDR_ANY ("0.0.0.0") as the default name server address
00162  * since it was noted that INADDR_ANY actually meant ``the first interface
00163  * you "ifconfig"'d at boot time'' and if this was a SLIP or PPP interface,
00164  * it had to be "up" in order for you to reach your own name server.  It
00165  * was later decided that since the recommended practice is to always
00166  * install local static routes through 127.0.0.1 for all your network
00167  * interfaces, that we could solve this problem without a code change.
00168  *
00169  * The configuration file should always be used, since it is the only way
00170  * to specify a default domain.  If you are running a server on your local
00171  * machine, you should say "nameserver 0.0.0.0" or "nameserver 127.0.0.1"
00172  * in the configuration file.
00173  *
00174  * Return 0 if completes successfully, -1 on error
00175  */
00176 int res_init (void)
00177 {
00178   char *cp;
00179   char  dom[MAX_HOSTLEN];
00180   char  buf[BUFSIZ];
00181   int   nserv;
00182
00183   watt_sock_init (0, 0);
00184
00185   /*
00186    * These three fields used to be statically initialized.  This made
00187    * it hard to use this code in a shared library.  It is necessary,
00188    * now that we're doing dynamic initialization here, that we preserve
00189    * the old semantics: if an application modifies one of these three
00190    * fields of _res before res_init() is called, res_init() will not
00191    * alter them.  Of course, if an application is setting them to
00192    * _zero_ before calling res_init(), hoping to override what used
00193    * to be the static default, we can't detect it and unexpected results
00194    * will follow.  Zero for any of these fields would make no sense,
00195    * so one can safely assume that the applications were already getting
00196    * unexpected results.
00197    *
00198    * _res.options is tricky since some apps were known to diddle the bits
00199    * before res_init() was first called. We can't replicate that semantic
00200    * with dynamic initialization (they may have turned bits off that are
00201    * set in RES_DEFAULT).  Our solution is to declare such applications
00202    * "broken".  They could fool us by setting RES_INIT but none do (yet).
00203    */
00204   if (!_res.retrans)              _res.retrans = RES_TIMEOUT;
00205   if (!_res.retry)                _res.retry   = 4;
00206   if (!(_res.options & RES_INIT)) _res.options = RES_DEFAULT;
00207
00208   /*
00209    * This one used to initialize implicitly to zero, so unless the app
00210    * has set it to something in particular, we can randomize it now.
00211    */
00212   if (_res.id == 0)
00213       _res.id = res_randomid();
00214
00215   _res.nsaddr.sin_addr.s_addr = INADDR_ANY;
00216   _res.nsaddr.sin_family      = AF_INET;
00217   _res.nsaddr.sin_port        = htons (NAMESERVER_PORT);
00218   _res.nscount   = 0;
00219   _res.pfcode    = 0;
00220   _res.dnsrch[0] = _res.defdname;
00221   _res.dnsrch[1] = NULL;
00222   if (!(_res.options & RES_INIT))
00223      _res.ndots = 1;
00224
00225   if (getdomainname (dom,sizeof(dom)) == 0)
00226   {
00227     strncpy (_res.defdname, dom, sizeof(_res.defdname)-1);
00228     _res.defdname [sizeof(_res.defdname)-1] = '\0';
00229   }
00230   else
00231     _res.defdname[0] = 0;
00232
00233   for (nserv = 0; nserv < MAXNS; nserv++)
00234   {
00235     _res.nsaddr_list[nserv].sin_family = AF_INET;
00236     _res.nsaddr_list[nserv].sin_port   = htons (NAMESERVER_PORT);
00237     if (nserv < last_nameserver)
00238     {
00239       _res.nsaddr_list[nserv].sin_addr.s_addr = htonl (def_nameservers[nserv]);
00240       _res.nscount++;
00241     }
00242     else
00243       _res.nsaddr_list[nserv].sin_addr.s_addr = htonl (INADDR_LOOPBACK);
00244   }
00245
00246   if (_res.options & RES_DEBUG)
00247   {
00248     int i;
00249     for (i = 1; i <= _res.nscount; i++)
00250         (*_printf) ("Nameserv #%d: %s (%d)\n",
00251                     i, inet_ntoa(_res.nsaddr_list[i-1].sin_addr),
00252                     NAMESERVER_PORT);
00253   }
00254
00255   if (_res.defdname[0] == 0 &&
00256       gethostname (buf,sizeof(_res.defdname)-1) == 0 &&
00257       (cp = strchr(buf, '.')) != NULL)
00258     strcpy (_res.defdname, cp+1);
00259
00260   cp = getenv ("RES_OPTIONS");
00261   if (!cp)
00262      cp = res_cfg_options;
00263   if (cp)
00264      res_setoptions (cp, "env");
00265
00266   _res.options |= RES_INIT;
00267   return (0);
00268 }
00269
00270 /*
00271  * Configure hook routine for bind resolver. Must be called
00272  * before res_init() (via watt_sock_init).
00273  */
00274 static void (*prev_hook) (const char*, const char*);
00275
00276 static const struct config_table bind_cfg[] = {
00277           { "RES_OPTIONS", ARG_STRDUP, (void*)&res_cfg_options },
00278           { "HOSTALIASES", ARG_STRDUP, (void*)&res_cfg_aliases },
00279           { NULL,          0,          NULL                    }
00280         };
00281
00282 static void resolver_init (const char *name, const char *value)
00283 {
00284   if (!parse_config_table(&bind_cfg[0], "BIND.", name, value) && prev_hook)
00285      (*prev_hook) (name, value);
00286 }
00287
00288 static void res_exit (void)
00289 {
00290   DO_FREE (res_cfg_options);
00291   DO_FREE (res_cfg_aliases);
00292 }
00293
00294 void res_init0 (void)
00295 {
00296   prev_hook = usr_init;
00297   usr_init  = resolver_init;
00298   RUNDOWN_ADD (res_exit, 200);
00299 }
00300 #endif /* USE_BIND */
00301
Generated on Wed Jan 25 15:42:39 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/RES_LOC.C Source File

SRC/RES_LOC.C

Go to the documentation of this file.
00001
00005 /* ++Copyright++ 1985, 1989, 1993
00006  * -
00007  * Copyright (c) 1985, 1989, 1993
00008  *    The Regents of the University of California.  All rights reserved.
00009  *
00010  * Redistribution and use in source and binary forms, with or without
00011  * modification, are permitted provided that the following conditions
00012  * are met:
00013  * 1. Redistributions of source code must retain the above copyright
00014  *    notice, this list of conditions and the following disclaimer.
00015  * 2. Redistributions in binary form must reproduce the above copyright
00016  *    notice, this list of conditions and the following disclaimer in the
00017  *    documentation and/or other materials provided with the distribution.
00018  * 3. All advertising materials mentioning features or use of this software
00019  *    must display the following acknowledgement:
00020  *   This product includes software developed by the University of
00021  *   California, Berkeley and its contributors.
00022  * 4. Neither the name of the University nor the names of its contributors
00023  *    may be used to endorse or promote products derived from this software
00024  *    without specific prior written permission.
00025  *
00026  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
00027  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00028  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00029  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
00030  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00031  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00032  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00033  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00034  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00035  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00036  * SUCH DAMAGE.
00037  * -
00038  * Portions Copyright (c) 1993 by Digital Equipment Corporation.
00039  *
00040  * Permission to use, copy, modify, and distribute this software for any
00041  * purpose with or without fee is hereby granted, provided that the above
00042  * copyright notice and this permission notice appear in all copies, and that
00043  * the name of Digital Equipment Corporation not be used in advertising or
00044  * publicity pertaining to distribution of the document or software without
00045  * specific, written prior permission.
00046  *
00047  * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
00048  * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
00049  * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
00050  * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
00051  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
00052  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
00053  * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
00054  * SOFTWARE.
00055  * -
00056  * --Copyright--
00057  *
00058  * Code taken from RFC-1876
00059  *
00060  * Routines to convert between on-the-wire RR format and zone file
00061  * format.  Does not contain conversion to/from decimal degrees;
00062  * divide or multiply by 60*60*1000 for that.
00063  *
00064  * Adapted for WatTCP by Gisle Vanem 1997
00065  */
00066
00067 #include "resolver.h"
00068
00069 #if defined(USE_BIND)
00070
00071 static unsigned long poweroften[10] = {
00072                      1, 10, 100, 1000, 10000, 100000,
00073                      1000000,10000000,100000000,1000000000
00074                    };
00075
00076 /*
00077  * takes an XeY precision/size value, returns a string representation.
00078  */
00079 static const char *precsize_ntoa (BYTE prec)
00080 {
00081   static char retbuf[sizeof("90000000.00")];
00082
00083   int   mantissa = (int)((prec >> 4) & 0x0f) % 10;
00084   int   exponent = (int)((prec >> 0) & 0x0f) % 10;
00085   DWORD value    = mantissa * poweroften[exponent];
00086
00087   sprintf (retbuf,"%lu.%.2lu", value / 100, value % 100);
00088   return (retbuf);
00089 }
00090
00091 /*
00092  * converts ascii size/precision X * 10**Y(cm) to 0xXY. moves pointer.
00093  */
00094 static BYTE precsize_aton (char **strptr)
00095 {
00096   UINT  mval   = 0;
00097   UINT  cmval  = 0;
00098   BYTE  retval = 0;
00099   char *cp     = *strptr;
00100   int   exponent;
00101   int   mantissa;
00102
00103   while (isdigit((int)*cp))
00104      mval = mval * 10 + (*cp++ - '0');
00105
00106   if (*cp == '.')             /* centimeters */
00107   {
00108     cp++;
00109     if (isdigit((int)*cp))
00110     {
00111       cmval = (*cp++ - '0') * 10;
00112       if (isdigit((int)*cp))
00113          cmval += (*cp++ - '0');
00114     }
00115   }
00116   cmval = (mval * 100) + cmval;
00117
00118   for (exponent = 0; exponent < 9; exponent++)
00119       if (cmval < poweroften[exponent+1])
00120          break;
00121
00122   mantissa = cmval / poweroften[exponent];
00123   if (mantissa > 9)
00124       mantissa = 9;
00125
00126   retval = (mantissa << 4) | exponent;
00127   *strptr = cp;
00128   return (retval);
00129 }
00130
00131 /*
00132  * Converts ascii lat/lon to unsigned encoded 32-bit number
00133  */
00134 static DWORD latlon2ul (char **latlonstrptr, int *which)
00135 {
00136   DWORD retval;
00137   char *cp   = *latlonstrptr;
00138   int   deg  = 0;
00139   int   min  = 0;
00140   int   secs = 0;
00141   int   secsfrac = 0;
00142
00143   while (isdigit((int)*cp))
00144      deg = deg * 10 + (*cp++ - '0');
00145
00146   while (isspace((int)*cp))
00147      cp++;
00148
00149   if (!(isdigit((int)*cp)))
00150      goto fndhemi;
00151
00152   while (isdigit((int)*cp))
00153      min = min * 10 + (*cp++ - '0');
00154
00155   while (isspace((int)*cp))
00156      cp++;
00157
00158   if (!(isdigit((int)*cp)))
00159      goto fndhemi;
00160
00161   while (isdigit((int)*cp))
00162      secs = secs * 10 + (*cp++ - '0');
00163
00164   if (*cp == '.')            /* decimal seconds */
00165   {
00166     cp++;
00167     if (isdigit((int)*cp))
00168     {
00169       secsfrac = (*cp++ - '0') * 100;
00170       if (isdigit((int)*cp))
00171       {
00172         secsfrac += (*cp++ - '0') * 10;
00173         if (isdigit((int)*cp))
00174            secsfrac += (*cp++ - '0');
00175       }
00176     }
00177   }
00178
00179   while (!isspace((int)*cp))   /* if any trailing garbage */
00180      cp++;
00181
00182   while (isspace((int)*cp))
00183      cp++;
00184
00185 fndhemi:
00186
00187   switch (toupper(*cp))
00188   {
00189     case 'N':
00190     case 'E':
00191          retval = (1UL << 31UL)
00192                 + (((((deg * 60UL) + min) * 60UL) + secs) * 1000UL)
00193                 + secsfrac;
00194          break;
00195     case 'S':
00196     case 'W':
00197          retval = (1UL << 31UL)
00198                 - (((((deg * 60UL) + min) * 60UL) + secs) * 1000UL)
00199                 - secsfrac;
00200          break;
00201     default:
00202          retval = 0;     /* invalid value -- indicates error */
00203          break;
00204   }
00205
00206   switch (toupper(*cp))
00207   {
00208     case 'N':
00209     case 'S':
00210          *which = 1;           /* latitude */
00211          break;
00212     case 'E':
00213     case 'W':
00214          *which = 2;           /* longitude */
00215          break;
00216     default:
00217          *which = 0;           /* error */
00218          break;
00219   }
00220
00221   cp++;                        /* skip the hemisphere */
00222
00223   while (!isspace((int)*cp))   /* if any trailing garbage */
00224      cp++;
00225
00226   while (isspace((int)*cp))    /* move to next field */
00227      cp++;
00228
00229   *latlonstrptr = cp;
00230   return (retval);
00231 }
00232
00233 /*
00234  * Converts a zone file representation in a string to an RDATA
00235  * on-the-wire representation.
00236  */
00237 int loc_aton (const char *ascii, u_char *binary)
00238 {
00239   char *cp, *maxcp;
00240   BYTE *bcp;
00241   DWORD latit     = 0, longit  = 0, alt = 0;
00242   DWORD lltemp1   = 0, lltemp2 = 0;
00243   int   altmeters = 0;
00244   int   altfrac   = 0;
00245   int   altsign   = 1;
00246   BYTE  hp        = 0x16;   /* default = 1e6 cm = 10000.00m = 10km */
00247   BYTE  vp        = 0x13;   /* default = 1e3 cm = 10.00m           */
00248   BYTE  siz       = 0x12;   /* default = 1e2 cm = 1.00m            */
00249   int   which1    = 0;
00250   int   which2    = 0;
00251
00252   cp    = (char*)ascii;
00253   maxcp = cp + strlen (ascii);
00254
00255   lltemp1 = latlon2ul (&cp, &which1);
00256   lltemp2 = latlon2ul (&cp, &which2);
00257
00258   switch (which1 + which2)
00259   {
00260     case 3:                 /* 1 + 2, the only valid combination */
00261          if (which1 == 1 && which2 == 2)  /* normal case */
00262          {
00263            latit  = lltemp1;
00264            longit = lltemp2;
00265          }
00266          else if (which1 == 2 && which2 == 1) /* reversed */
00267          {
00268            longit = lltemp1;
00269            latit  = lltemp2;
00270          }
00271          else               /* some kind of brokenness */
00272            return (0);
00273          break;
00274     default:                /* we didn't get one of each */
00275          return (0);
00276   }
00277
00278   /* altitude */
00279   if (*cp == '-')
00280   {
00281     altsign = -1;
00282     cp++;
00283   }
00284
00285   if (*cp == '+')
00286      ++cp;
00287
00288   while (isdigit((int)*cp))
00289      altmeters = altmeters * 10 + (*cp++ - '0');
00290
00291   if (*cp == '.')                /* decimal meters */
00292   {
00293     cp++;
00294     if (isdigit((int)*cp))
00295     {
00296       altfrac = (*cp++ - '0') * 10;
00297       if (isdigit((int)*cp))
00298          altfrac += (*cp++ - '0');
00299     }
00300   }
00301
00302   alt = (10000000 + (altsign * (altmeters * 100 + altfrac)));
00303
00304   while (!isspace((int)*cp) && (cp < maxcp))
00305      cp++;                /* if trailing garbage or m */
00306
00307   while (isspace((int)*cp) && (cp < maxcp))
00308      cp++;
00309
00310   if (cp >= maxcp)
00311      goto defaults;
00312
00313   siz = precsize_aton (&cp);
00314
00315   while (!isspace((int)*cp) && (cp < maxcp)) /* if trailing garbage or m */
00316      cp++;
00317
00318   while (isspace((int)*cp) && (cp < maxcp))
00319      cp++;
00320
00321   if (cp >= maxcp)
00322      goto defaults;
00323
00324   hp = precsize_aton (&cp);
00325
00326   while (!isspace((int)*cp) && (cp < maxcp)) /* if trailing garbage or m */
00327      cp++;
00328
00329   while (isspace((int)*cp) && (cp < maxcp))
00330      cp++;
00331
00332   if (cp >= maxcp)
00333      goto defaults;
00334
00335   vp = precsize_aton (&cp);
00336
00337  defaults:
00338
00339   bcp = binary;
00340   *bcp++ = (BYTE) 0;  /* version byte */
00341   *bcp++ = siz;
00342   *bcp++ = hp;
00343   *bcp++ = vp;
00344   PUTLONG (latit, bcp);
00345   PUTLONG (longit, bcp);
00346   PUTLONG (alt, bcp);
00347
00348   return (16);            /* size of RR in octets */
00349 }
00350
00351 /*
00352  * Takes an on-the-wire LOC RR and prints it in zone file
00353  * (human readable) format.
00354  */
00355 char *loc_ntoa (const u_char *binary, char *ascii)
00356 {
00357   static char  tmpbuf[255*3];
00358   const  DWORD referencealt = 100000UL * 100UL;
00359   const  BYTE *rcp;
00360   char  *cp, *sizestr, *hpstr, *vpstr;
00361
00362   int   latdeg,  latmin,  latsec,  latsecfrac;
00363   int   longdeg, longmin, longsec, longsecfrac;
00364   char  northsouth, eastwest;
00365   int   altmeters,  altfrac, altsign;
00366
00367   long  latval, longval, altval;
00368   DWORD templ;
00369   BYTE  sizeval, hpval, vpval, versionval;
00370
00371   rcp = binary;
00372   if (ascii)
00373        cp = ascii;
00374   else cp = tmpbuf;
00375
00376   versionval = *rcp++;
00377
00378   if (versionval)
00379   {
00380     sprintf (cp, "; error: unknown LOC RR version");
00381     return (cp);
00382   }
00383
00384   sizeval = *rcp++;
00385   hpval   = *rcp++;
00386   vpval   = *rcp++;
00387
00388   GETLONG (templ, rcp);
00389   latval = (templ - (1UL << 31));
00390
00391   GETLONG (templ, rcp);
00392   longval = (templ - (1UL << 31));
00393
00394   GETLONG (templ, rcp);
00395   if (templ < referencealt)  /* below WGS 84 spheroid */
00396   {
00397     altval  = referencealt - templ;
00398     altsign = -1;
00399   }
00400   else
00401   {
00402     altval  = templ - referencealt;
00403     altsign = 1;
00404   }
00405
00406   if (latval < 0)
00407   {
00408     northsouth = 'S';
00409     latval = -latval;
00410   }
00411   else
00412     northsouth = 'N';
00413
00414   latsecfrac = latval % 1000;
00415   latval     = latval / 1000;
00416   latsec     = latval % 60;
00417   latval     = latval / 60;
00418   latmin     = latval % 60;
00419   latval     = latval / 60;
00420   latdeg     = latval;
00421
00422   if (longval < 0)
00423   {
00424     eastwest = 'W';
00425     longval  = -longval;
00426   }
00427   else
00428     eastwest = 'E';
00429
00430   longsecfrac = longval % 1000;
00431   longval     = longval / 1000;
00432   longsec     = longval % 60;
00433   longval     = longval / 60;
00434   longmin     = longval % 60;
00435   longval     = longval / 60;
00436   longdeg     = longval;
00437
00438   altfrac   = altval % 100;
00439   altmeters = (altval / 100) * altsign;
00440
00441   sizestr = strdup (precsize_ntoa(sizeval));
00442   hpstr   = strdup (precsize_ntoa(hpval));
00443   vpstr   = strdup (precsize_ntoa(vpval));
00444
00445   sprintf (cp,
00446            "%d %.2d %.2d.%.3d %c %d %.2d %.2d.%.3d %c %d.%.2dm %sm %sm %sm",
00447            latdeg, latmin, latsec, latsecfrac, northsouth,
00448            longdeg, longmin, longsec, longsecfrac, eastwest,
00449            altmeters, altfrac, sizestr, hpstr, vpstr);
00450   free (sizestr);
00451   free (hpstr);
00452   free (vpstr);
00453
00454   return (cp);
00455 }
00456 #endif /* USE_BIND */
00457
Generated on Wed Jan 25 15:42:39 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/RES_MKQU.C Source File

SRC/RES_MKQU.C

Go to the documentation of this file.
00001
00005 /* ++Copyright++ 1985, 1993
00006  * -
00007  * Copyright (c) 1985, 1993
00008  *    The Regents of the University of California.  All rights reserved.
00009  *
00010  * Redistribution and use in source and binary forms, with or without
00011  * modification, are permitted provided that the following conditions
00012  * are met:
00013  * 1. Redistributions of source code must retain the above copyright
00014  *    notice, this list of conditions and the following disclaimer.
00015  * 2. Redistributions in binary form must reproduce the above copyright
00016  *    notice, this list of conditions and the following disclaimer in the
00017  *    documentation and/or other materials provided with the distribution.
00018  * 3. All advertising materials mentioning features or use of this software
00019  *    must display the following acknowledgement:
00020  *   This product includes software developed by the University of
00021  *   California, Berkeley and its contributors.
00022  * 4. Neither the name of the University nor the names of its contributors
00023  *    may be used to endorse or promote products derived from this software
00024  *    without specific prior written permission.
00025  *
00026  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
00027  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00028  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00029  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
00030  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00031  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00032  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00033  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00034  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00035  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00036  * SUCH DAMAGE.
00037  * -
00038  * Portions Copyright (c) 1993 by Digital Equipment Corporation.
00039  *
00040  * Permission to use, copy, modify, and distribute this software for any
00041  * purpose with or without fee is hereby granted, provided that the above
00042  * copyright notice and this permission notice appear in all copies, and that
00043  * the name of Digital Equipment Corporation not be used in advertising or
00044  * publicity pertaining to distribution of the document or software without
00045  * specific, written prior permission.
00046  *
00047  * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
00048  * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
00049  * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
00050  * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
00051  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
00052  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
00053  * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
00054  * SOFTWARE.
00055  * -
00056  * --Copyright--
00057  */
00058
00059 #include "resolver.h"
00060
00061 #if defined(USE_BIND)
00062
00063 /*
00064  * Form all types of queries.
00065  * Returns the size of the result or -1.
00066  */
00067 int res_mkquery (
00068     int           op,            /* opcode of query */
00069     const char   *dname,         /* domain name */
00070     int           Class,         /* class of query */
00071     int           type,          /* type of query */
00072     const u_char *data,          /* resource record data */
00073     int           datalen,       /* length of data */
00074     const u_char *newrr_in,      /* new rr for modify or append */
00075     u_char       *buf,           /* buffer to put query */
00076     int           buflen)        /* size of buffer */
00077 {
00078   struct  rrec *newrr = (struct rrec *) newrr_in;
00079   HEADER  *hp;
00080   u_char  *cp;
00081   u_char  *dnptrs[20];
00082   u_char **dpp, **lastdnptr;
00083   int      n;
00084
00085   if ((_res.options & RES_INIT) == 0 && res_init() == -1)
00086   {
00087     h_errno = NETDB_INTERNAL;
00088     return (-1);
00089   }
00090
00091   if (_res.options & RES_DEBUG)
00092      (*_printf) (";; res_mkquery(%d, %s, %d, %d)\n", op, dname, Class, type);
00093
00094   /* Initialize header fields.
00095    */
00096   if (!buf || buflen < HFIXEDSZ)
00097      return (-1);
00098
00099   memset (buf, 0, HFIXEDSZ);
00100   hp = (HEADER*) buf;
00101   hp->id     = htons (++_res.id);
00102   hp->opcode = op;
00103   hp->rd     = (_res.options & RES_RECURSE) != 0;
00104   hp->rcode  = NOERROR;
00105   cp      = buf + HFIXEDSZ;
00106   buflen -= HFIXEDSZ;
00107   dpp     = dnptrs;
00108   *dpp++  = buf;
00109   *dpp++  = NULL;
00110   lastdnptr = dnptrs + sizeof dnptrs / sizeof dnptrs[0];
00111
00112   /* perform opcode specific processing
00113    */
00114   switch (op)
00115   {
00116     case STATUS:
00117          return (-1);
00118
00119     case QUERY:
00120          /* fallthrough */
00121
00122     case NS_NOTIFY_OP:    /* Notify secondary server of SOA change */
00123          buflen -= QFIXEDSZ;
00124          if (buflen < 0)
00125             return (-1);
00126
00127          if ((n = dn_comp(dname, cp, buflen, dnptrs, lastdnptr)) < 0)
00128             return (-1);
00129          cp     += n;
00130          buflen -= n;
00131          __putshort (type, cp);
00132          cp += INT16SZ;
00133          __putshort (Class, cp);
00134          cp += INT16SZ;
00135          hp->qdcount = htons (1);
00136          if (op == QUERY || !data)
00137             break;
00138          /*
00139           * Make an additional record for completion domain.
00140           */
00141          buflen -= RRFIXEDSZ;
00142          n = dn_comp ((char*)data, cp, buflen, dnptrs, lastdnptr);
00143          if (n < 0)
00144             return (-1);
00145          cp     += n;
00146          buflen -= n;
00147          __putshort (T_NULL, cp);
00148          cp += INT16SZ;
00149          __putshort (Class, cp);
00150          cp += INT16SZ;
00151          __putlong (0, cp);
00152          cp += INT32SZ;
00153          __putshort (0, cp);
00154          cp += INT16SZ;
00155          hp->arcount = htons (1);
00156          break;
00157
00158     case IQUERY:
00159          /*
00160           * Initialize answer section
00161           */
00162          if (buflen < 1 + RRFIXEDSZ + datalen)
00163             return (-1);
00164          *cp++ = '\0';  /* no domain name */
00165          __putshort (type, cp);
00166          cp += INT16SZ;
00167          __putshort (Class, cp);
00168          cp += INT16SZ;
00169          __putlong (0, cp);
00170          cp += INT32SZ;
00171          __putshort (datalen, cp);
00172          cp += INT16SZ;
00173          if (datalen)
00174          {
00175            memcpy (cp,data,datalen);
00176            cp += datalen;
00177          }
00178          hp->ancount = htons (1);
00179          break;
00180
00181 #if ALLOW_UPDATES
00182        /*
00183         * For UPDATEM/UPDATEMA, do UPDATED/UPDATEDA followed by UPDATEA
00184         * (Record to be modified is followed by its replacement in msg.)
00185         */
00186     case UPDATEM:
00187     case UPDATEMA:
00188     case UPDATED:
00189          /*
00190           * The res code for UPDATED and UPDATEDA is the same; user
00191           * calls them differently: specifies data for UPDATED; server
00192           * ignores data if specified for UPDATEDA.
00193           */
00194     case UPDATEDA:
00195          buflen -= RRFIXEDSZ + datalen;
00196          if ((n = dn_comp(dname, cp, buflen, dnptrs, lastdnptr)) < 0)
00197             return (-1);
00198          cp += n;
00199          __putshort (type, cp);
00200          cp += INT16SZ;
00201          __putshort (Class, cp);
00202          cp += INT16SZ;
00203          __putlong (0, cp);
00204          cp += INT32SZ;
00205          __putshort (datalen, cp);
00206          cp += INT16SZ;
00207          if (datalen)
00208          {
00209            memcpy (cp,data,datalen);
00210            cp += datalen;
00211          }
00212          if (op == UPDATED || op == UPDATEDA)
00213          {
00214            hp->ancount = 0;
00215            break;
00216          }
00217          /* Else UPDATEM/UPDATEMA, so drop into code for UPDATEA
00218           */
00219
00220     case UPDATEA:  /* Add new resource record */
00221          buflen -= RRFIXEDSZ + datalen;
00222          if ((n = dn_comp(dname, cp, buflen, dnptrs, lastdnptr)) < 0)
00223             return (-1);
00224          cp += n;
00225          __putshort (newrr->r_type, cp);
00226          cp += INT16SZ;
00227          __putshort (newrr->r_class, cp);
00228          cp += INT16SZ;
00229          __putlong (0, cp);
00230          cp += INT32SZ;
00231          __putshort (newrr->r_size, cp);
00232          cp += INT16SZ;
00233          if (newrr->r_size)
00234          {
00235            memcpy (cp,newrr->r_data,newrr->r_size);
00236            cp += newrr->r_size;
00237          }
00238          hp->ancount = 0;
00239          break;
00240 #endif
00241     default:
00242          return (-1);
00243   }
00244
00245 #if ALLOW_UPDATES == 0
00246   ARGSUSED (newrr);
00247   ARGSUSED (newrr_in);
00248 #endif
00249
00250   return (cp - buf);
00251 }
00252 #endif /* USE_BIND */
00253
Generated on Wed Jan 25 15:42:39 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/RES_QUER.C Source File

SRC/RES_QUER.C

Go to the documentation of this file.
00001
00005 /*
00006  * ++Copyright++ 1988, 1993
00007  * -
00008  * Copyright (c) 1988, 1993
00009  *    The Regents of the University of California.  All rights reserved.
00010  *
00011  * Redistribution and use in source and binary forms, with or without
00012  * modification, are permitted provided that the following conditions
00013  * are met:
00014  * 1. Redistributions of source code must retain the above copyright
00015  *    notice, this list of conditions and the following disclaimer.
00016  * 2. Redistributions in binary form must reproduce the above copyright
00017  *    notice, this list of conditions and the following disclaimer in the
00018  *    documentation and/or other materials provided with the distribution.
00019  * 3. All advertising materials mentioning features or use of this software
00020  *    must display the following acknowledgement:
00021  *   This product includes software developed by the University of
00022  *   California, Berkeley and its contributors.
00023  * 4. Neither the name of the University nor the names of its contributors
00024  *    may be used to endorse or promote products derived from this software
00025  *    without specific prior written permission.
00026  *
00027  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
00028  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00029  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00030  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
00031  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00032  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00033  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00034  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00035  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00036  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00037  * SUCH DAMAGE.
00038  * -
00039  * Portions Copyright (c) 1993 by Digital Equipment Corporation.
00040  *
00041  * Permission to use, copy, modify, and distribute this software for any
00042  * purpose with or without fee is hereby granted, provided that the above
00043  * copyright notice and this permission notice appear in all copies, and that
00044  * the name of Digital Equipment Corporation not be used in advertising or
00045  * publicity pertaining to distribution of the document or software without
00046  * specific, written prior permission.
00047  *
00048  * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
00049  * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
00050  * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
00051  * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
00052  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
00053  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
00054  * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
00055  * SOFTWARE.
00056  * -
00057  * --Copyright--
00058  */
00059
00060 #include "resolver.h"
00061
00062 #if defined(USE_BIND)
00063
00064 #if (PACKETSZ > 1024)
00065   #define MAXPACKET  PACKETSZ
00066 #else
00067   #define MAXPACKET  1024
00068 #endif
00069
00070 /*
00071  * Formulate a normal query, send, and await answer.
00072  * Returned answer is placed in supplied buffer "answer".
00073  * Perform preliminary check of answer, returning success only
00074  * if no error is indicated and the answer count is nonzero.
00075  * Return the size of the response on success, -1 on error.
00076  * Error number is left in h_errno.
00077  *
00078  * Caller must parse answer and determine whether it answers the question.
00079  */
00080 int res_query (const char *name, int Class, int type,
00081                u_char *answer, int anslen)
00082 {
00083   u_char  buf[MAXPACKET];
00084   HEADER *hp = (HEADER*) answer;
00085   int     n;
00086
00087   hp->rcode = NOERROR;  /* default */
00088
00089   if ((_res.options & RES_INIT) == 0 && res_init() == -1)
00090   {
00091     h_errno = NETDB_INTERNAL;
00092     return (-1);
00093   }
00094
00095   if (_res.options & RES_DEBUG)
00096     (*_printf) (";; res_query(%s, %d, %d)\n", name, Class, type);
00097
00098   n = res_mkquery (QUERY, name, Class, type, NULL, 0, NULL,
00099                    buf, sizeof(buf));
00100   if (n <= 0)
00101   {
00102     if (_res.options & RES_DEBUG)
00103       (*_printf) (";; res_query: mkquery failed\n");
00104
00105     h_errno = NO_RECOVERY;
00106     return (n);
00107   }
00108   n = res_send (buf, n, answer, anslen);
00109   if (n < 0)
00110   {
00111     if (_res.options & RES_DEBUG)
00112        (*_printf) (";; res_query: send error\n");
00113
00114     h_errno = TRY_AGAIN;
00115     return (n);
00116   }
00117
00118   if (hp->rcode != NOERROR || ntohs(hp->ancount) == 0)
00119   {
00120     if (_res.options & RES_DEBUG)
00121        (*_printf) (";; rcode = %d, ancount=%d\n",
00122                    hp->rcode, ntohs(hp->ancount));
00123
00124     switch (hp->rcode)
00125     {
00126       case NXDOMAIN:
00127            h_errno = HOST_NOT_FOUND;
00128            break;
00129       case SERVFAIL:
00130            h_errno = TRY_AGAIN;
00131            break;
00132       case NOERROR:
00133            h_errno = NO_DATA;
00134            break;
00135       case FORMERR:
00136       case NOTIMP:
00137       case REFUSED:
00138       default:
00139            h_errno = NO_RECOVERY;
00140            break;
00141     }
00142     return (-1);
00143   }
00144   return (n);
00145 }
00146
00147 /*
00148  * Formulate a normal query, send, and retrieve answer in supplied buffer.
00149  * Return the size of the response on success, -1 on error.
00150  * If enabled, implement search rules until answer or unrecoverable failure
00151  * is detected.  Error code, if any, is left in h_errno.
00152  */
00153 int res_search (const char *name, int Class, int type,
00154                 u_char *answer, int anslen)
00155 {
00156   #define RDBG(x)  (*_printf) ("res_search() = %d at line %u\n", x, __LINE__)
00157
00158   const char *cp;
00159   const char *const *domain;
00160   HEADER     *hp = (HEADER *) answer;
00161   u_int       dots;
00162   int         trailing_dot, ret = -1;
00163   int         saved_herrno;
00164   int         got_nodata   = 0;
00165   int         got_servfail = 0;
00166   int         tried_as_is  = 0;
00167   int         done         = 0;
00168
00169   if ((_res.options & RES_INIT) == 0 && res_init() == -1)
00170   {
00171     h_errno = NETDB_INTERNAL;
00172     RDBG (-1);
00173     return (-1);
00174   }
00175
00176   SOCK_ERRNO (0);
00177   h_errno = 0;       /* default, if we never query */
00178   dots    = 0;
00179
00180   for (cp = name; *cp; cp++)
00181       dots += (*cp == '.');
00182
00183   trailing_dot = 0;
00184   if (cp > name && *--cp == '.')
00185      trailing_dot++;
00186
00187   /* if there aren't any dots, it could be a user-level alias
00188    */
00189   if (!dots && (cp = __hostalias(name)) != NULL)
00190   {
00191     int rc = res_query (cp, Class, type, answer, anslen);
00192     RDBG (rc);
00193     return (rc);
00194   }
00195
00196   /* If there are dots in the name already, let's just give it a try
00197    * 'as is'.  The threshold can be set with the "ndots" option.
00198    */
00199   saved_herrno = -1;
00200   if (dots >= _res.ndots)
00201   {
00202     ret = res_querydomain (name, NULL, Class, type, answer, anslen);
00203     if (ret > 0)
00204     {
00205       RDBG (ret);
00206       return (ret);
00207     }
00208     saved_herrno = h_errno;
00209     tried_as_is++;
00210   }
00211
00212   /*
00213    * We do at least one level of search if
00214    *  - there is no dot and RES_DEFNAME is set, or
00215    *  - there is at least one dot, there is no trailing dot,
00216    *    and RES_DNSRCH is set.
00217    */
00218   if ((!dots && (_res.options & RES_DEFNAMES)) ||
00219       (dots && !trailing_dot && (_res.options & RES_DNSRCH)))
00220   {
00221     for (domain = (const char * const*)_res.dnsrch; *domain && !done; domain++)
00222     {
00223       ret = res_querydomain (name, *domain, Class, type, answer, anslen);
00224       if (ret > 0)
00225       {
00226         RDBG (ret);
00227         return (ret);
00228       }
00229
00230       /*
00231        * If no server present, give up.
00232        * If name isn't found in this domain,
00233        * keep trying higher domains in the search list
00234        * (if that's enabled).
00235        * On a NO_DATA error, keep trying, otherwise
00236        * a wildcard entry of another type could keep us
00237        * from finding this entry higher in the domain.
00238        * If we get some other error (negative answer or
00239        * server failure), then stop searching up,
00240        * but try the input name below in case it's
00241        * fully-qualified.
00242        */
00243       if (errno == ECONNREFUSED)
00244       {
00245         h_errno = TRY_AGAIN;
00246         RDBG (-1);
00247         return (-1);
00248       }
00249
00250       switch (h_errno)
00251       {
00252         case NO_DATA:
00253              got_nodata++;
00254              /* fallthrough */
00255         case HOST_NOT_FOUND:
00256              /* keep trying */
00257              break;
00258         case TRY_AGAIN:
00259              if (hp->rcode == SERVFAIL)
00260              {
00261                /* try next search element, if any */
00262                got_servfail++;
00263                break;
00264              }
00265              /* fallthrough */
00266         default:
00267              /* anything else implies that we're done */
00268              done++;
00269       }
00270
00271       /* if we got here for some reason other than DNSRCH,
00272        * we only wanted one iteration of the loop, so stop.
00273        */
00274       if (!(_res.options & RES_DNSRCH))
00275          done++;
00276     }
00277   }
00278
00279   /* if we have not already tried the name "as is", do that now.
00280    * note that we do this regardless of how many dots were in the
00281    * name or whether it ends with a dot.
00282    */
00283   if (!tried_as_is)
00284   {
00285     ret = res_querydomain (name, NULL, Class, type, answer, anslen);
00286     if (ret > 0)
00287     {
00288       RDBG (ret);
00289       return (ret);
00290     }
00291   }
00292
00293   /* if we got here, we didn't satisfy the search.
00294    * if we did an initial full query, return that query's h_errno
00295    * (note that we wouldn't be here if that query had succeeded).
00296    * else if we ever got a nodata, send that back as the reason.
00297    * else send back meaningless h_errno, that being the one from
00298    * the last DNSRCH we did.
00299    */
00300   if (saved_herrno != -1)
00301      h_errno = saved_herrno;
00302
00303   else if (got_nodata)
00304      h_errno = NO_DATA;
00305
00306   else if (got_servfail)
00307      h_errno = TRY_AGAIN;
00308
00309   if (done || h_errno == 0)
00310      return (1);
00311
00312   TCP_CONSOLE_MSG (1, ("res_search() / h_errno = %d\n", h_errno));
00313   RDBG (-1);
00314   return (-1);
00315 }
00316
00317
00318 /*
00319  * Perform a call on res_query on the concatenation of name and domain,
00320  * removing a trailing dot from name if domain is NULL.
00321  */
00322 int res_querydomain (const char *name, const char *domain, int Class,
00323                      int type, u_char *answer, int anslen)
00324 {
00325   char  nbuf[2*MAXDNAME+2];
00326   const char *longname = nbuf;
00327   int   n;
00328
00329   if ((_res.options & RES_INIT) == 0 && res_init() == -1)
00330   {
00331     h_errno = NETDB_INTERNAL;
00332     return (-1);
00333   }
00334
00335   if (_res.options & RES_DEBUG)
00336      (*_printf) (";; res_querydomain(%s, %s, %d, %d)\n",
00337                  name, domain ? domain : "<Nil>", Class, type);
00338
00339   if (!domain)
00340   {
00341     /* Check for trailing '.'; copy without '.' if present.
00342      */
00343     n = strlen (name) - 1;
00344     if (n != -1 && name[n] == '.' && n < (int)sizeof(nbuf)-1)
00345     {
00346       memcpy (nbuf, name, n);
00347       nbuf[n] = '\0';
00348     }
00349     else
00350       longname = name;
00351   }
00352   else
00353   {
00354     /* won't overflow
00355      */
00356     sprintf (nbuf, "%.*s.%.*s", MAXDNAME, name, MAXDNAME, domain);
00357   }
00358
00359   return res_query (longname, Class, type, answer, anslen);
00360 }
00361
00362 /*
00363  * Open and parse hostalias file. Lines may have comments ('#' or ';').
00364  * Line format is:
00365  *   [ ].host[ ]*alias{#}.[\r\n]
00366  */
00367 char *__hostalias (const char *name)
00368 {
00369   const char *file;
00370   FILE  *fp;
00371   char   buf[BUFSIZ];
00372   static char abuf[MAXDNAME];
00373
00374   if (_res.options & RES_NOALIASES)
00375      return (NULL);
00376
00377   file = getenv ("HOSTALIASES");
00378   if (!file)
00379      file = res_cfg_aliases;
00380
00381   if (!file || (fp = fopen(file, "r")) == NULL)
00382      return (NULL);
00383
00384   abuf[0] = '\0';
00385
00386   while (fgets(buf, sizeof(buf), fp))
00387   {
00388     char *p, *host, *alias;
00389
00390     p = strltrim (buf);
00391     if (!*p || *p == '\n' || *p == '#' || *p == ';')
00392        continue;
00393
00394     host  = strtok (p, " \t");
00395     alias = strtok (NULL, " \t\n");
00396     if (!host || !alias)
00397        continue;
00398
00399     if (!stricmp(host, name))
00400     {
00401       StrLcpy (abuf, alias, sizeof(abuf)-1);
00402       break;
00403     }
00404   }
00405   fclose (fp);
00406   return (abuf[0] ? abuf : NULL);
00407 }
00408 #endif /* USE_BIND */
00409
Generated on Wed Jan 25 15:42:39 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/RES_SEND.C Source File

SRC/RES_SEND.C

Go to the documentation of this file.
00001
00005 /*
00006  * ++Copyright++ 1985, 1989, 1993
00007  * -
00008  * Copyright (c) 1985, 1989, 1993
00009  *    The Regents of the University of California.  All rights reserved.
00010  *
00011  * Redistribution and use in source and binary forms, with or without
00012  * modification, are permitted provided that the following conditions
00013  * are met:
00014  * 1. Redistributions of source code must retain the above copyright
00015  *    notice, this list of conditions and the following disclaimer.
00016  * 2. Redistributions in binary form must reproduce the above copyright
00017  *    notice, this list of conditions and the following disclaimer in the
00018  *    documentation and/or other materials provided with the distribution.
00019  * 3. All advertising materials mentioning features or use of this software
00020  *    must display the following acknowledgement:
00021  *   This product includes software developed by the University of
00022  *   California, Berkeley and its contributors.
00023  * 4. Neither the name of the University nor the names of its contributors
00024  *    may be used to endorse or promote products derived from this software
00025  *    without specific prior written permission.
00026  *
00027  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
00028  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00029  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00030  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
00031  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00032  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00033  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00034  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00035  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00036  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00037  * SUCH DAMAGE.
00038  * -
00039  * Portions Copyright (c) 1993 by Digital Equipment Corporation.
00040  *
00041  * Permission to use, copy, modify, and distribute this software for any
00042  * purpose with or without fee is hereby granted, provided that the above
00043  * copyright notice and this permission notice appear in all copies, and that
00044  * the name of Digital Equipment Corporation not be used in advertising or
00045  * publicity pertaining to distribution of the document or software without
00046  * specific, written prior permission.
00047  *
00048  * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
00049  * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
00050  * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
00051  * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
00052  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
00053  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
00054  * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
00055  * SOFTWARE.
00056  * -
00057  * --Copyright--
00058  */
00059
00060 /*
00061  * 10.Dec-97   Adapted for Waterloo TCP/IP - G. Vanem (giva@bgnett.no)
00062  *
00063  */
00064
00065 /*
00066  * Send query to name server and wait for reply.
00067  */
00068
00069 #include "resolver.h"
00070
00071 #if defined(USE_BIND)
00072
00073 static sock_type *sock = NULL;  /* socket used for communications */
00074 static int vc          = 0;     /* is the socket a virtual ciruit? */
00075 static int connected   = 0;     /* is the socket connected */
00076
00077 static int  name_server_send (int ns, struct sockaddr_in *nsap);
00078 static void resolve_close    (void);
00079
00080 #define SAME_NS (-1)
00081 #define NEXT_NS (-2)
00082
00083
00084 #define Dprint(cond,args) if (cond) do {      \
00085                              (*_printf) args; \
00086                            } while (0)
00087
00088 #define DprintQ(cond,args,query,size)                        \
00089                           if (cond) do {                     \
00090                              (*_printf) args;                \
00091                              __fp_nquery (query,size,stdout);\
00092                           } while (0)
00093
00094 static void Aerror (const char *str, const char *error,
00095                     struct sockaddr_in address)
00096 {
00097   if (_res.options & RES_DEBUG)
00098      (*_printf) ("res_send: %s (%s/%u): %s\n",
00099                  str, inet_ntoa(address.sin_addr),
00100                  ntohs(address.sin_port), error);
00101 }
00102
00103 static void Perror (const char *str, const char *error)
00104 {
00105   if (_res.options & RES_DEBUG)
00106      (*_printf) ("res_send: %s: %s\n", str, error);
00107 }
00108
00109 static res_send_qhook Qhook = NULL;
00110 static res_send_rhook Rhook = NULL;
00111
00112 void res_send_setqhook (res_send_qhook hook)
00113 {
00114   Qhook = hook;
00115 }
00116
00117 void res_send_setrhook (res_send_rhook hook)
00118 {
00119   Rhook = hook;
00120 }
00121
00122 /*
00123  * int res_isourserver(ina)
00124  *    looks up "ina" in _res.ns_addr_list[]
00125  * returns:
00126  *    0 : not found
00127  *   >0 : found
00128  * author:
00129  *    paul vixie, 29may94
00130  */
00131 int res_isourserver (const struct sockaddr_in *inp)
00132 {
00133   struct sockaddr_in ina = *inp;
00134   int    ns;
00135
00136   for (ns = 0; ns < _res.nscount; ns++)
00137   {
00138     const struct sockaddr_in *srv = &_res.nsaddr_list[ns];
00139
00140     if (srv->sin_family == ina.sin_family &&
00141         srv->sin_port   == ina.sin_port   &&
00142         (srv->sin_addr.s_addr == INADDR_ANY ||
00143          srv->sin_addr.s_addr == ina.sin_addr.s_addr))
00144       return (1);
00145   }
00146   return (0);
00147 }
00148
00149 /*
00150  * int res_nameinquery(name, type, class, buf, eom)
00151  *    look for (name,type,class) in the query section of packet (buf,eom)
00152  * returns:
00153  *    -1 : format error
00154  *     0 : not found
00155  *    >0 : found
00156  * author:
00157  *     paul vixie, 29may94
00158  */
00159 int res_nameinquery (const char *name, int type, int Class,
00160                      const u_char *buf, const u_char *eom)
00161 {
00162   const u_char *cp = buf + HFIXEDSZ;
00163   int   qdcount    = ntohs (((HEADER*)buf)->qdcount);
00164
00165   while (qdcount-- > 0)
00166   {
00167     char tname[MAXDNAME+1];
00168     int n, ttype, tclass;
00169
00170     n = dn_expand (buf, eom, cp, tname, sizeof(tname));
00171     if (n < 0)
00172        return (-1);
00173     cp += n;
00174     ttype  = _getshort (cp);
00175     cp    += INT16SZ;
00176     tclass = _getshort (cp);
00177     cp    += INT16SZ;
00178     if (ttype == type && tclass == Class && !stricmp(tname,name))
00179        return (1);
00180   }
00181   return (0);
00182 }
00183
00184
00185 /*
00186  * int res_queriesmatch(buf1, eom1, buf2, eom2)
00187  *    is there a 1:1 mapping of (name,type,Class)
00188  *    in (buf1,eom1) and (buf2,eom2)?
00189  * returns:
00190  *    -1 : format error
00191  *     0 : not a 1:1 mapping
00192  *    >0 : is a 1:1 mapping
00193  * author:
00194  *     paul vixie, 29may94
00195  */
00196 int res_queriesmatch (const u_char *buf1, const u_char *eom1,
00197                       const u_char *buf2, const u_char *eom2)
00198 {
00199   const u_char *cp = buf1 + HFIXEDSZ;
00200   int   qdcount    = ntohs (((HEADER*)buf1)->qdcount);
00201
00202   if (qdcount != ntohs(((HEADER*)buf2)->qdcount))
00203      return (0);
00204
00205   while (qdcount-- > 0)
00206   {
00207     char tname[MAXDNAME+1];
00208     int n, ttype, tclass;
00209
00210     n = dn_expand (buf1, eom1, cp, tname, sizeof(tname));
00211     if (n < 0)
00212        return (-1);
00213     cp += n;
00214     ttype  = _getshort (cp);
00215     cp    += INT16SZ;
00216     tclass = _getshort (cp);
00217     cp    += INT16SZ;
00218     if (!res_nameinquery(tname, ttype, tclass, buf2, eom2))
00219        return (0);
00220   }
00221   return (1);
00222 }
00223
00224 /*--------------------------------------------------------------------*/
00225
00226 static HEADER *hp, *anhp;
00227 static int     gotsomewhere, connreset, terrno, Try;
00228 static int     v_circuit, ns, n;
00229 static int     ns_buflen, ns_anssiz;
00230 static u_long  badns;
00231 static u_char *ns_buf,   *ns_ans;
00232
00233 int res_send (const u_char *buf, int buflen, u_char *ans, int anssiz)
00234 {
00235   hp   = (HEADER *) buf;
00236   anhp = (HEADER *) ans;
00237
00238   ns_buf    = (u_char*)buf;
00239   ns_ans    = ans;
00240   ns_buflen = buflen;
00241   ns_anssiz = anssiz;
00242
00243   if ((_res.options & RES_INIT) == 0 && res_init() == -1)
00244   {
00245     /* errno should have been set by res_init() in this case
00246      */
00247     return (-1);
00248   }
00249   DprintQ ((_res.options & RES_DEBUG) || (_res.pfcode & RES_PRF_QUERY),
00250            (";; res_send()\n"), buf, buflen);
00251
00252   v_circuit    = (_res.options & RES_USEVC) || buflen > PACKETSZ;
00253   gotsomewhere = 0;
00254   connreset    = 0;
00255   terrno       = ETIMEDOUT;
00256   badns        = 0;
00257
00258   /* Send request, RETRY times, or until successful
00259    */
00260   for (Try = 0; Try < _res.retry; Try++)
00261   {
00262     for (ns = 0; ns < _res.nscount; ns++)
00263     {
00264       struct sockaddr_in *nsap = &_res.nsaddr_list[ns];
00265       int    rc;
00266
00267       do
00268         rc = name_server_send (ns, nsap);
00269       while (rc == SAME_NS);
00270
00271       if (rc != NEXT_NS)
00272          return (rc);
00273     }
00274   }
00275
00276   resolve_close();
00277   if (!v_circuit)
00278   {
00279     if (!gotsomewhere)
00280          SOCK_ERRNO (ECONNREFUSED); /* no nameservers found */
00281     else SOCK_ERRNO (ETIMEDOUT);    /* no answer obtained */
00282   }
00283   else
00284     SOCK_ERRNO (terrno);
00285   return (-1);
00286 }
00287
00288 /*------------------------------------------------------------------------*/
00289
00290 #if defined(_MSC_VER)
00291   #define ERROR_TYPE int volatile /* because '&errno' is used below */
00292 #else
00293   #define ERROR_TYPE int
00294 #endif
00295
00296 static int tcp_conn (_tcp_Socket *sock, ERROR_TYPE *error, DWORD timeout)
00297 {
00298   DWORD timer  = set_timeout (timeout);
00299   int   status = _ip_delay0 ((sock_type*)sock, (int)timeout, NULL, NULL);
00300
00301   if (status == -1)
00302   {
00303     *error = chk_timeout(timer) ? ETIMEDOUT : ECONNREFUSED;
00304     return (0);
00305   }
00306   *error = 0;
00307   return (1);
00308 }
00309
00310 /*------------------------------------------------------------------------*/
00311
00312 static int tcp_read (_tcp_Socket *sock, u_char *buf, int len,
00313                      ERROR_TYPE *error, DWORD timeout)
00314 {
00315   int status = _ip_delay1 ((sock_type*)sock, (int)timeout, NULL, NULL);
00316
00317   if (status == -1)
00318   {
00319     *error = ETIMEDOUT;
00320     return (0);
00321   }
00322   if (status == 1)
00323   {
00324     *error = ECONNRESET;
00325     return (0);
00326   }
00327   *error = 0;
00328   return sock_fastread ((sock_type*)sock, (BYTE*)buf, len);
00329 }
00330
00331 /*------------------------------------------------------------------------*/
00332
00333 static int udp_read (_udp_Socket *sock, u_char *buf, int len,
00334                      ERROR_TYPE *error, DWORD timeout)
00335 {
00336   int status = _ip_delay1 ((sock_type*)sock, (int)timeout, NULL, NULL);
00337
00338   if (status == -1)
00339   {
00340     *error = ETIMEDOUT;
00341     return (0);
00342   }
00343   *error = 0;
00344   return sock_fastread ((sock_type*)sock, (BYTE*)buf, len);
00345 }
00346
00347 /*------------------------------------------------------------------------*/
00348
00349 static int name_server_send (int ns, struct sockaddr_in *nsap)
00350 {
00351   int resplen = 0;
00352
00353   if (badns & (1 << ns))  /* this NameServer already marked bad */
00354   {
00355     resolve_close();
00356     return (NEXT_NS);
00357   }
00358
00359   if (Qhook)
00360   {
00361     int done = 0;
00362     int loops = 0;
00363     do
00364     {
00365       res_sendhookact act = (*Qhook) (&nsap, (const u_char**)&ns_buf,
00366                                       &ns_buflen, ns_ans, ns_anssiz,
00367                                       &resplen);
00368       switch (act)
00369       {
00370         case res_goahead:
00371              done = 1;
00372              break;
00373         case res_nextns:
00374              resolve_close();
00375              return (NEXT_NS);
00376         case res_done:
00377              return (resplen);
00378         case res_modified:
00379              /* give the hook another try */
00380              if (++loops < 42)
00381                 break;
00382              /* fallthrough */
00383         case res_error:
00384              /* fallthrough */
00385         default:
00386              return (-1);
00387       }
00388     }
00389     while (!done);
00390   }
00391
00392   Dprint (_res.options & RES_DEBUG,
00393           (";; Querying server (# %d) address = %s\n",
00394            ns + 1, inet_ntoa(nsap->sin_addr)));
00395
00396   if (v_circuit)  /* i.e. TCP */
00397   {
00398     int     truncated;
00399     u_short len;
00400     u_char *cp;
00401
00402     /* Use virtual circuit; at most one attempt per server.
00403      */
00404     Try = _res.retry;
00405     truncated = 0;
00406     if (!sock || !vc)
00407     {
00408       DWORD his_ip   = ntohl (nsap->sin_addr.s_addr);
00409       WORD  his_port = ntohs (nsap->sin_port);
00410
00411       if (sock)
00412          resolve_close();
00413
00414       sock = (sock_type*) calloc (sizeof(_tcp_Socket), 1);
00415       if (!sock)
00416       {
00417         Perror ("calloc(vc)", "no memory");
00418         return (-1);
00419       }
00420
00421       if (!tcp_open(&sock->tcp,0,his_ip,his_port,NULL) ||
00422           !tcp_conn(&sock->tcp,&errno,dns_timeout))
00423       {
00424         Aerror ("tcp_open/vc", "failed/timeout", *nsap);
00425         badns |= (1 << ns);
00426         resolve_close();
00427         return (NEXT_NS);
00428       }
00429       vc = 1;
00430     }
00431
00432     /* Send length & message
00433      */
00434     {
00435       int   send_len = INT16SZ + ns_buflen;
00436       BYTE *send_buf = (BYTE*) alloca (send_len);
00437
00438       PUTSHORT (ns_buflen, send_buf);
00439       memcpy (send_buf + INT16SZ, ns_buf, ns_buflen);
00440       if (sock_write(sock,send_buf,send_len) != send_len)
00441       {
00442         Perror ("sock_write() failed", sockerr(sock));
00443         badns |= (1 << ns);
00444         resolve_close();
00445         return (NEXT_NS);
00446       }
00447     }
00448
00449     /* Receive length & response
00450      */
00451     cp  = ns_ans;
00452     len = INT16SZ;
00453     while ((n = tcp_read(&sock->tcp,cp,len,&errno,dns_timeout)) > 0)
00454     {
00455       cp  += n;
00456       len -= n;
00457       if ((signed)len <= 0)
00458          break;
00459     }
00460     if (n <= 0)
00461     {
00462       Perror ("tcp_read() failed", sockerr(sock));
00463       resolve_close();
00464       return (NEXT_NS);
00465     }
00466     resplen = _getshort (ns_ans);
00467     if (resplen > ns_anssiz)
00468     {
00469       Dprint (_res.options & RES_DEBUG,(";; response truncated\n"));
00470       truncated = 1;
00471       len = ns_anssiz;
00472     }
00473     else
00474       len = resplen;
00475
00476     cp = ns_ans;
00477     while (len && (n = tcp_read(&sock->tcp,cp,len,&errno,dns_timeout)) > 0)
00478     {
00479       cp  += n;
00480       len -= n;
00481     }
00482     if (n <= 0)
00483     {
00484       Perror ("tcp_read(vc)",sockerr(sock));
00485       resolve_close();
00486       return (NEXT_NS);
00487     }
00488     if (truncated)
00489     {
00490       /* Flush rest of answer so connection stays in synch.
00491        */
00492       anhp->tc = 1;
00493       len = resplen - ns_anssiz;
00494       while (len)
00495       {
00496         u_char junk[PACKETSZ];
00497
00498         n = (len > sizeof(junk) ? sizeof(junk) : len);
00499         n = tcp_read (&sock->tcp,junk,n,&errno,dns_timeout);
00500         if (n > 0)
00501              len -= n;
00502         else break;
00503       }
00504     }
00505   }
00506   else  /* !v_circuit, i.e. UDP */
00507   {
00508     DWORD timeout;
00509
00510     if (!sock || vc)
00511     {
00512       if (vc)
00513          resolve_close();
00514
00515       sock = (sock_type*) calloc (sizeof(_udp_Socket), 1);
00516       if (!sock)
00517       {
00518         Perror ("calloc(dg)", "no memory");
00519         return (-1);
00520       }
00521       connected = 0;
00522     }
00523
00524     /* Connect only if we are sure we won't
00525      * receive a response from another server.
00526      */
00527     if (!connected)
00528     {
00529       DWORD his_ip   = ntohl (nsap->sin_addr.s_addr);
00530       WORD  his_port = ntohs (nsap->sin_port);
00531
00532       if (!udp_open(&sock->udp,0,his_ip,his_port,NULL))
00533       {
00534         Aerror ("connect/dg", "ARP failed", *nsap);
00535         badns |= (1 << ns);
00536         resolve_close();
00537         return (NEXT_NS);
00538       }
00539       connected = 1;
00540     }
00541     if (sock_write(sock,(const BYTE*)ns_buf,ns_buflen) != ns_buflen)
00542     {
00543       Perror ("sock_write() failed", "");
00544       badns |= (1 << ns);
00545       resolve_close();
00546       return (NEXT_NS);
00547     }
00548
00549     /* Wait for reply
00550      */
00551     timeout = (unsigned)_res.retrans << Try;
00552     if (Try > 0)
00553        timeout /= _res.nscount;
00554     if ((long)timeout <= 0)
00555        timeout = 1;
00556
00557   wait:
00558
00559     n = udp_read (&sock->udp, ns_ans, ns_anssiz, &errno, timeout);
00560     if (n == 0)
00561     {
00562       Dprint (_res.options & RES_DEBUG, (";; timeout\n"));
00563       gotsomewhere = 1;
00564       resolve_close();
00565       return (NEXT_NS);
00566     }
00567     gotsomewhere = 1;
00568     if (hp->id != anhp->id)
00569     {
00570       /* response from old query, ignore it.
00571        * XXX - potential security hazard could be detected here.
00572        */
00573       DprintQ ((_res.options & RES_DEBUG) || (_res.pfcode & RES_PRF_REPLY),
00574                (";; old answer:\n"), ns_ans, resplen);
00575       goto wait;
00576     }
00577
00578     if (!(_res.options & RES_INSECURE2) &&
00579         !res_queriesmatch(ns_buf, ns_buf+ns_buflen, ns_ans, ns_ans+ns_anssiz))
00580     {
00581       /* response contains wrong query? ignore it.
00582        * XXX - potential security hazard could be detected here.
00583        */
00584       DprintQ ((_res.options & RES_DEBUG) || (_res.pfcode & RES_PRF_REPLY),
00585                (";; wrong query name:\n"), ns_ans, resplen);
00586       goto wait;
00587     }
00588     if (anhp->rcode == SERVFAIL ||
00589         anhp->rcode == NOTIMP   ||
00590         anhp->rcode == REFUSED)
00591     {
00592       DprintQ (_res.options & RES_DEBUG,("server rejected query:\n"),
00593                ns_ans,resplen);
00594       badns |= (1 << ns);
00595       resolve_close();
00596
00597       /* don't retry if called from dig */
00598       if (!_res.pfcode)
00599          return (NEXT_NS);
00600     }
00601     if (!(_res.options & RES_IGNTC) && anhp->tc)
00602     {
00603       /* get rest of answer; use TCP with same server.
00604        */
00605       Dprint (_res.options & RES_DEBUG, (";; truncated answer\n"));
00606       v_circuit = 1;
00607       resolve_close();
00608       return (SAME_NS);
00609     }
00610   } /* if vcicuit / dg */
00611
00612   Dprint ((_res.options & RES_DEBUG) ||
00613           ((_res.pfcode & RES_PRF_REPLY) && (_res.pfcode & RES_PRF_HEAD1)),
00614           (";; got answer:\n"));
00615
00616   DprintQ ((_res.options & RES_DEBUG) || (_res.pfcode & RES_PRF_REPLY),
00617            (" \b"), ns_ans, resplen);
00618
00619   /*
00620    * If using virtual circuits (TCP), we assume that the first server
00621    * is preferred over the rest (i.e. it is on the local machine) and
00622    * only keep that one open. If we have temporarily opened a virtual
00623    * circuit, or if we haven't been asked to keep a socket open,
00624    * close the socket.
00625    */
00626   if ((v_circuit && (!(_res.options & RES_USEVC) || ns != 0)) ||
00627       !(_res.options & RES_STAYOPEN))
00628      resolve_close();
00629
00630   if (Rhook)
00631   {
00632     int done = 0, loops = 0;
00633
00634     do
00635     {
00636       res_sendhookact act = (*Rhook) (nsap, ns_buf, ns_buflen,
00637                                       ns_ans, ns_anssiz, &resplen);
00638       switch (act)
00639       {
00640         case res_goahead:
00641         case res_done:
00642              done = 1;
00643              break;
00644         case res_nextns:
00645              resolve_close();
00646              return (NEXT_NS);
00647         case res_modified:
00648              /* give the hook another try */
00649              if (++loops < 42)
00650                 break;
00651              /* fallthrough */
00652         case res_error:
00653              /* fallthrough */
00654         default:
00655              return (-1);
00656       }
00657     }
00658     while (!done);
00659   }
00660   return (resplen);
00661 }
00662
00663 /*
00664  * This routine is for closing the socket if a virtual circuit is used and
00665  * the program wants to close it.  This provides support for endhostent()
00666  * which expects to close the socket.
00667  *
00668  * This routine is not expected to be user visible.
00669  */
00670 static void resolve_close (void)
00671 {
00672   if (sock)
00673   {
00674     sock_close (sock);
00675
00676     if (sock->tcp.ip_type == TCP_PROTO &&
00677         sock->tcp.state < tcp_StateCLOSED)
00678        TCP_ABORT (&sock->tcp);
00679
00680     free (sock);
00681     sock = NULL;
00682     connected = 0;
00683     vc = 0;
00684   }
00685 }
00686 #endif /* USE_BIND */
00687
Generated on Wed Jan 25 15:42:39 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/RESOLVER.H Source File

SRC/RESOLVER.H

Go to the documentation of this file.
00001
00005 /* ++Copyright++
00006  * -
00007  * Copyright (c)
00008  *    The Regents of the University of California.  All rights reserved.
00009  *
00010  * Redistribution and use in source and binary forms, with or without
00011  * modification, are permitted provided that the following conditions
00012  * are met:
00013  * 1. Redistributions of source code must retain the above copyright
00014  *    notice, this list of conditions and the following disclaimer.
00015  * 2. Redistributions in binary form must reproduce the above copyright
00016  *    notice, this list of conditions and the following disclaimer in the
00017  *    documentation and/or other materials provided with the distribution.
00018  * 3. All advertising materials mentioning features or use of this software
00019  *    must display the following acknowledgement:
00020  *     This product includes software developed by the University of
00021  *     California, Berkeley and its contributors.
00022  * 4. Neither the name of the University nor the names of its contributors
00023  *    may be used to endorse or promote products derived from this software
00024  *    without specific prior written permission.
00025  *
00026  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
00027  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00028  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00029  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
00030  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00031  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00032  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00033  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00034  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00035  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00036  * SUCH DAMAGE.
00037  * -
00038  * Portions Copyright (c) 1993 by Digital Equipment Corporation.
00039  *
00040  * Permission to use, copy, modify, and distribute this software for any
00041  * purpose with or without fee is hereby granted, provided that the above
00042  * copyright notice and this permission notice appear in all copies, and that
00043  * the name of Digital Equipment Corporation not be used in advertising or
00044  * publicity pertaining to distribution of the document or software without
00045  * specific, written prior permission.
00046  *
00047  * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
00048  * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
00049  * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
00050  * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
00051  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
00052  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
00053  * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
00054  * SOFTWARE.
00055  * -
00056  * --Copyright--
00057  */
00058
00059 /* Key:
00060  *    ucb   = U C Berkeley 4.8.3 release
00061  *    vix   = Paul Vixie of Digital
00062  *    del   = Don Lewis of Harris
00063  *    mcsun = Piet Beertema of EUNet
00064  *    asp   = Andrew Partan of UUNet
00065  *    pma   = Paul Albitz of Hewlett Packard
00066  *    bb    = Bryan Beecher of UMich
00067  *    mpa   = Mark Andrews of CSIRO - DMS
00068  *    rossc = Ross Cartlidge of The Univeritsy of Sydney
00069  *    mtr   = Marshall Rose of TPC.INT
00070  *    bg    = Benoit Grange of INRIA
00071  *    ckd   = Christopher Davis of Kapor Enterprises
00072  *    gns   = Greg Shapiro of WPI
00073  */
00074
00075 /*
00076  * 10.Dec-97   Adapted for Waterloo TCP/IP - G. Vanem (giva@bgnett.no)
00077  *
00078  */
00079
00080 #ifndef _w32_RESOLVER_H_
00081 #define _w32_RESOLVER_H_
00082
00083 #if defined(__TURBOC__) && (__TURBOC__ <= 0x301)
00084   /*
00085    * Prevent tcc <= 2.01 from ever looking at this.
00086    */
00087 #else
00088
00089 #include <stdio.h>
00090 #include <stdlib.h>
00091 #include <string.h>
00092 #include <errno.h>
00093 #include <ctype.h>
00094 #include <sys/socket.h>
00095 #include <arpa/nameser.h>
00096 #include <arpa/inet.h>
00097 #include <netdb.h>
00098 #include <resolv.h>
00099
00100 #include "wattcp.h"
00101 #include "misc.h"
00102 #include "timer.h"
00103 #include "strings.h"
00104 #include "bsdname.h"
00105 #include "sock_ini.h"
00106 #include "netaddr.h"
00107 #include "udp_dom.h"
00108 #include "netaddr.h"
00109 #include "pcbuf.h"
00110 #include "pcdbug.h"
00111 #include "pctcp.h"
00112 #include "pcconfig.h"
00113
00114 extern const char *_res_opcodes[];
00115 extern const char *_res_resultcodes[];
00116
00117 extern char *res_cfg_options, *res_cfg_aliases;
00118
00119 extern void res_init0 (void);
00120
00121 #define CHECK_SRVR_ADDR  1  /* check nameserver address in responses */
00122 #define RESOLVSORT       1  /* allow sorting of addresses in gethostbyname (mpa) */
00123 #define RFC1535          1  /* use RFC 1535 default for "search" list (vix) */
00124 #define ALLOW_T_UNSPEC   0  /* enable the "unspec" RR type for old athena (ucb) */
00125 #define ALLOW_UPDATES    0  /* 1: enable updating resource records */
00126
00127 #endif  /* old __TURBOC__ */
00128 #endif  /* _w32_RESOLVER_H_  */
Generated on Wed Jan 25 15:42:39 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/RS232.C Source File

SRC/RS232.C

Go to the documentation of this file.
00001
00008 #include <stdio.h>
00009 #include <stdarg.h>
00010
00011 #include "wattcp.h"
00012 #include "strings.h"
00013 #include "language.h"
00014 #include "ioport.h"
00015 #include "misc.h"
00016 #include "timer.h"
00017 #include "rs232.h"
00018
00019 #if defined(USE_RS232_DBG) // && !defined(BORLAND386)
00020
00021 /* Offsets from base address 'trace2com_base'
00022  */
00023 #define TXRX_REG      0        /* Transmit/Receive Register */
00024 #define IER_REG       1        /* Interrupt Enable Register */
00025 #define BAUD_LSB_REG  0        /* LSB baudrate when LCR bit 7 is set */
00026 #define BAUD_MSB_REG  1        /* MSB baudrate when LCR bit 7 is set */
00027 #define IIR_REG       2        /* Interrupt Identification Register */
00028 #define FIFO_REG      2        /* 16550 FIFO control Register */
00029
00030 #define LCR_REG       3        /* Line Control Register */
00031 #define MCR_REG       4        /* Modem Control Register */
00032 #define LSR_REG       5        /* Line Status Register */
00033   #define LSR_THRE    0x20     /* Tx holding reg. empty */
00034
00035 static DWORD trace2com_speed      = 115200UL;
00036 static int   trace2com_base       = 0;
00037 static int   trace2com_fifoSize_1 = 0;
00038 static int   trace2com_stdPorts [4] = { 0x3F8, 0x2F8, 0x3E8, 0x2E8 };
00039
00040 /*
00041  * ___trace2com() - Strings passed here are dumped to the set-up serial
00042  * "com" port. If the string is < 16 chars long, it will fit into the
00043  * 16550 UARTs FIFO and will not cause any significant delay.
00044  * No interrupts are used, so this will not interfere with anything
00045  * else that might be happening.
00046  */
00047 int MS_CDECL __trace2com (const char *fmt, ...)
00048 {
00049   int     fifoLeft = 0; /* Assume TX FIFO is full on first round -> force check */
00050   char    buf [256];
00051   int     len, i;
00052   va_list args;
00053
00054   if (trace2com_base <= 0)   /* Not yet initialized */
00055      return (0);
00056
00057   va_start (args, fmt);
00058
00059 #if defined(VSNPRINTF)
00060   len = VSNPRINTF (buf, sizeof(buf)-1, fmt, args);
00061   if (len < 0 || len >= SIZEOF(buf)-1)
00062   {
00063     outsnl (_LANG("ERROR: __trace2com() overrun"));
00064     len = sizeof(buf)-1;
00065     buf [len] = '\0';
00066   }
00067 #else
00068   len = vsprintf (buf, fmt, args);
00069   if (len > SIZEOF(buf))  /* harm already done, but better than no test */
00070   {
00071     outsnl (_LANG("ERROR: __trace2com() overrun"));
00072     return (0);
00073   }
00074 #endif
00075
00076   for (i = 0; i < len; i++)
00077   {
00078     DWORD to = set_timeout (400000/trace2com_speed); /* 10ms at 38kB/s */
00079
00080     if (--fifoLeft < 0) /* Is the TX FIFO full? */
00081     {
00082       /* Wait until THRE or TX FIFO empty
00083        */
00084       while (!(_inportb (trace2com_base+LSR_REG) & LSR_THRE))
00085       {
00086         if (chk_timeout(to))
00087            return (i);
00088       }
00089       fifoLeft = trace2com_fifoSize_1; /* Now we can fill it up again */
00090     }
00091     _outportb (trace2com_base+TXRX_REG, buf[i]);
00092   }
00093
00094   if (--fifoLeft < 0)
00095   {
00096     DWORD to = set_timeout (400000/trace2com_speed);
00097
00098     /* Wait until THRE or TX FIFO empty
00099      */
00100     while (!(_inportb (trace2com_base+LSR_REG) & LSR_THRE))
00101     {
00102       if (chk_timeout(to))
00103          return (len);
00104     }
00105   }
00106   _outportb (trace2com_base+TXRX_REG, '\r');
00107   _outportb (trace2com_base+TXRX_REG, '\n');
00108   return (len+2);
00109 }
00110
00111 /*
00112  * trace2com_init() - Public initialisation
00113  */
00114 int trace2com_init (WORD portAddress, DWORD baudRate)
00115 {
00116   BYTE  Lsb, Msb;
00117   WORD  base;
00118   DWORD div;
00119
00120   /* Check/get UART address
00121    */
00122   if (portAddress < 1 || portAddress > 4)
00123      return (0);
00124
00125   base = trace2com_stdPorts [portAddress-1];
00126
00127   /* See if the chip is actually there and ready
00128    */
00129   if (_inportb (base+IER_REG) == 0xFF)    /* Nothing here */
00130      return (0);
00131
00132   if ((_inportb (base+IER_REG) & 0x0F) != 0x00)
00133      return (0);    /* UART is already in use by another program */
00134
00135   _outportb (base+IER_REG, 0);  /* disable all interrupts */
00136   if (_inportb (base+IER_REG) != 0)
00137      return (0);                /* Whatever is here is not an UART */
00138
00139   /* Set up UARTs registers
00140    */
00141   div = 115200UL / baudRate;
00142   Msb = div >> 8;
00143   Lsb = (div << 8) >> 8;
00144
00145   _outportb (base+LCR_REG, 0x80);       /* Turn address latch on */
00146   _outportb (base+BAUD_LSB_REG, Lsb);
00147   _outportb (base+BAUD_MSB_REG, Msb);
00148   _outportb (base+LCR_REG, 0x00);       /* Turn address latch off (again) */
00149
00150   _outportb (base+IER_REG, 0x00);       /* No interrupts, we use polling */
00151   _outportb (base+FIFO_REG, 0x01|0x08); /* Activate FIFO @ MODE 2 */
00152   _outportb (base+LCR_REG , 0x03);      /* 8, N, 1 */
00153   _outportb (base+MCR_REG, 0x03);       /* DTR + DTS on */
00154
00155   /* Check chip type, gives us the FIFO size
00156    */
00157   _outportb (base + FIFO_REG, 0x11);
00158   Lsb = _inportb (base + FIFO_REG);
00159
00160   /* If we have a 16750 or 16550 the FIFO size is 16, otherwise we assume 1
00161    */
00162   trace2com_fifoSize_1 = ((Lsb & 0x20) != 0x20 ||
00163                           (Lsb & 0xC0) == 0xC0) ? 15 : 0;
00164
00165   /* We are now officially open for business
00166    */
00167   trace2com_speed = baudRate;
00168   trace2com_base  = base;
00169
00170   SIO_TRACE ((_LANG("Watt-32 COM%d trace started"), portAddress));
00171   return (1);
00172 }
00173 #endif  /* USE_RS232_DBG && !BORLAND386 */
00174
Generated on Wed Jan 25 15:42:39 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/RS232.H Source File

SRC/RS232.H

Go to the documentation of this file.
00001
00015 #ifndef _w32_RS232_H
00016 #define _w32_RS232_H
00017
00018 #if defined(USE_RS232_DBG)
00019   extern int            trace2com_init (WORD portAddress, DWORD baudRate);
00020   extern int MS_CDECL __trace2com (const char *fmt, ...)  ATTR_PRINTF (1,2);
00021
00022   #define SIO_TRACE(p)  __trace2com p
00023 #else
00024   #define SIO_TRACE(p)  ((void)0)
00025 #endif
00026 #endif
00027
Generated on Wed Jan 25 15:42:39 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/SELECT.C Source File

SRC/SELECT.C

Go to the documentation of this file.
00001
00005 /*  BSD sockets functionality for Waterloo TCP/IP
00006  *
00007  *  Copyright (c) 1997-2002 Gisle Vanem <giva@bgnett.no>
00008  *
00009  *  Redistribution and use in source and binary forms, with or without
00010  *  modification, are permitted provided that the following conditions
00011  *  are met:
00012  *  1. Redistributions of source code must retain the above copyright
00013  *     notice, this list of conditions and the following disclaimer.
00014  *  2. Redistributions in binary form must reproduce the above copyright
00015  *     notice, this list of conditions and the following disclaimer in the
00016  *     documentation and/or other materials provided with the distribution.
00017  *  3. All advertising materials mentioning features or use of this software
00018  *     must display the following acknowledgement:
00019  *       This product includes software developed by Gisle Vanem
00020  *       Bergen, Norway.
00021  *
00022  *  THIS SOFTWARE IS PROVIDED BY ME (Gisle Vanem) AND CONTRIBUTORS ``AS IS''
00023  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00024  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00025  *  ARE DISCLAIMED.  IN NO EVENT SHALL I OR CONTRIBUTORS BE LIABLE FOR ANY
00026  *  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00027  *  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00028  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00029  *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00030  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00031  *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00032  *
00033  *  Version
00034  *
00035  *  0.5 : Dec 18, 1997 : G. Vanem - created
00036  *  0.6 : Nov 05, 1999 : G. Vanem - several changes;
00037  *                       Protect select-loop as critical region.
00038  *                       Changed criteria for read/writeability.
00039  */
00040
00041 #include "socket.h"
00042
00043 #if defined(USE_BSD_API)
00044
00045 #ifdef __HIGHC__     /* set warning for stack-usage */
00046 #pragma stack_size_warn (16000)    /* ~3*MAX_SOCKETS */
00047 #endif
00048
00049 #define ALWAYS_YIELD  0
00050
00051 #ifndef STDIN_FILENO
00052 #define STDIN_FILENO  0
00053 #endif
00054
00055 #ifndef STDOUT_FILENO
00056 #define STDOUT_FILENO 1
00057 #endif
00058
00059 #ifndef STDERR_FILENO
00060 #define STDERR_FILENO 2
00061 #endif
00062
00063
00068 static struct timeval sel_min_block = { 0, 500000 }; /* 0.5 sec */
00069
00070 /*
00071  * Select sockets for read, write or exceptions
00072  *   Returns 1 if socket is ready or
00073  *   Returns 0 if socket isn't selectable
00074  */
00075 static int read_select  (int s, Socket *socket);
00076 static int write_select (int s, Socket *socket);
00077 static int exc_select   (int s, Socket *socket);
00078
00079 /*
00080  * Setup for read/write/except_select()
00081  */
00082 static __inline Socket *setup_select (int s, BOOL first_loop)
00083 {
00084   Socket *socket = _socklist_find (s);
00085
00086   if (first_loop && !socket)
00087   {
00088     if (_sock_dos_fd(s))
00089     {
00090       SOCK_DEBUGF ((", ENOTSOCK (%d)", s));
00091       SOCK_ERRNO (ENOTSOCK);
00092     }
00093     else
00094     {
00095       SOCK_DEBUGF ((", EBADF (%d)", s));
00096       SOCK_ERRNO (EBADF);
00097     }
00098   }
00099   return (socket);
00100 }
00101
00112 int select_s (int nfds, fd_set *readfds, fd_set *writefds,
00113               fd_set *exceptfds, struct timeval *timeout)
00114 {
00115   fd_set tmp_read  [NUM_SOCK_FDSETS];
00116   fd_set tmp_write [NUM_SOCK_FDSETS];
00117   fd_set tmp_except[NUM_SOCK_FDSETS];
00118   struct timeval starttime, expiry, now;
00119
00120   int  num_fd    = nfds;
00121   int  ret_count = 0;
00122   BOOL expired   = FALSE;
00123   BOOL loop_1st  = TRUE;
00124   int  s, loops;
00125
00126 #if defined(USE_DEBUG)
00127   unsigned total_rd = 0;
00128   unsigned total_wr = 0;
00129   unsigned total_ex = 0;
00130 #endif
00131
00132   SOCK_DEBUGF (("\nselect: n=0-%d, %c%c%c", num_fd-1,
00133                 readfds   ? 'r' : '-',
00134                 writefds  ? 'w' : '-',
00135                 exceptfds ? 'x' : '-'));
00136
00137
00138   /* num_fd == 0 is permitted. Often used to perform delays:
00139    *   select (0,NULL,NULL,NULL,&tv);
00140    *
00141    * Some programs uses -1 to mean all possible sockets.
00142    */
00143   if (num_fd > MAX_SOCKETS || num_fd < 0)
00144       num_fd = MAX_SOCKETS;
00145
00146   if (timeout)
00147   {
00148     if ((long)timeout->tv_sec < 0 || timeout->tv_usec < 0)
00149     {
00150       SOCK_DEBUGF ((", EINVAL (negative timeout)"));
00151       SOCK_ERRNO (EINVAL);
00152       return (-1);
00153     }
00154
00155     gettimeofday2 (&starttime, NULL); /* initialize start time */
00156
00157     expiry.tv_sec  = starttime.tv_sec  + timeout->tv_sec;
00158     expiry.tv_usec = starttime.tv_usec + timeout->tv_usec;
00159     while (expiry.tv_usec >= 1000000L)
00160     {
00161       expiry.tv_usec -= 1000000L;
00162       expiry.tv_sec++;
00163     }
00164
00165     SOCK_DEBUGF ((", timeout %lu.%06lds",
00166                   (DWORD)timeout->tv_sec, timeout->tv_usec));
00167   }
00168   else
00169     SOCK_DEBUGF ((", timeout undef"));
00170
00171
00177   memset (tmp_read, 0, sizeof(tmp_read));
00178   memset (tmp_write, 0, sizeof(tmp_write));
00179   memset (tmp_except, 0, sizeof(tmp_except));
00180
00181   /* If application catches same signals we do, we must exit
00182    * gracefully from the do-while and for loops below.
00183    */
00184   if (_sock_sig_setup() < 0)
00185      goto select_intr;
00186
00187   /*
00188    * Loop until specified timeout expires or event(s) satisfied.
00189    */
00190   for (loop_1st = TRUE, loops = 1;; loop_1st = FALSE, loops++)
00191   {
00192     /* Poll for caught signals (SIGINT/SIGALRM)
00193      */
00194     if (_sock_sig_pending())
00195        goto select_intr;
00196
00197     for (s = 0; s < num_fd; s++)
00198     {
00199       /* read/write/except counters for socket 's'
00200        */
00201       int     do_read  = 0, do_write  = 0, do_exc  = 0;
00202       int     read_cnt = 0, write_cnt = 0, exc_cnt = 0;
00203       Socket *socket = NULL;
00204
00205       /* Not safe to run sock_daemon() (or other "tasks") now
00206        */
00207       _sock_crit_start();
00208
00209       if (readfds && FD_ISSET(s,readfds))
00210          do_read = 1;
00211
00212       if (writefds && FD_ISSET(s,writefds))
00213          do_write = 1;
00214
00215       if (exceptfds && FD_ISSET(s,exceptfds))
00216          do_exc = 1;
00217
00218       if (do_read || do_write || do_exc)
00219       {
00220         tcp_tick (NULL);      /* must do tcp_tick() here */
00221         if (s >= SK_FIRST)
00222         {
00223           socket = setup_select (s, loop_1st);
00224           if (!socket)        /* skip this fd */
00225              do_read = do_write = do_exc = 0;
00226         }
00227       }
00228
00229       /* Check this socket for readability ?
00230        */
00231       if (do_read)
00232       {
00233         read_cnt = read_select (s, socket);
00234         if (read_cnt > 0)
00235            FD_SET (s, &tmp_read[0]);
00236       }
00237
00238       /* Check this socket for writeability ?
00239        */
00240       if (do_write)
00241       {
00242         write_cnt = write_select (s, socket);
00243         if (write_cnt > 0)
00244            FD_SET (s, &tmp_write[0]);
00245       }
00246
00247       /* Check this socket for exception ?
00248        */
00249       if (do_exc)
00250       {
00251         exc_cnt = exc_select (s, socket);
00252         if (exc_cnt > 0)
00253            FD_SET (s, &tmp_except[0]);
00254       }
00255
00256       /* Increment the return and total counters (may increment by 0)
00257        */
00258       ret_count += (read_cnt + write_cnt + exc_cnt);
00259
00260 #if defined(USE_DEBUG)
00261       total_rd += read_cnt;
00262       total_wr += write_cnt;
00263       total_ex += exc_cnt;
00264 #endif
00265
00266       /* Safe to run other "tasks" now.
00267        */
00268       _sock_crit_stop();
00269       SOCK_DBUG_FLUSH();
00270
00271     } /* end of for loop; all sockets checked at least once */
00272
00273
00274     /* WATT_YIELD() sometimes hangs for approx 250msec under Win-XP.
00275      * Don't yield for "small" timeouts.
00276      */
00277 #if (!ALWAYS_YIELD)
00278     if (!timeout || timercmp(timeout,&sel_min_block,>))
00279 #endif
00280     {
00281       if (ret_count == 0)
00282       {
00283         WATT_YIELD();
00284         tcp_tick (NULL);
00285       }
00286     }
00287
00288     if (timeout)
00289     {
00290       gettimeofday2 (&now, NULL);
00291       if (now.tv_sec > expiry.tv_sec ||
00292           (now.tv_sec == expiry.tv_sec && now.tv_usec >= expiry.tv_usec))
00293         expired = TRUE;
00294     }
00295
00296     /* If atleast 1 event is set.
00297      */
00298     if (ret_count > 0)
00299     {
00300       SOCK_DEBUGF ((", cnt=%d (%dr/%dw/%dx)",
00301                     ret_count, total_rd, total_wr, total_ex));
00302
00303       /* Copy our working fd_sets to output fd_sets
00304        */
00305       for (s = 0; s < num_fd; s++)
00306       {
00307         if (readfds)
00308         {
00309           if (FD_ISSET(s, &tmp_read[0]))
00310                FD_SET (s, readfds);
00311           else FD_CLR (s, readfds);
00312         }
00313         if (writefds)
00314         {
00315           if (FD_ISSET(s, &tmp_write[0]))
00316                FD_SET (s, writefds);
00317           else FD_CLR (s, writefds);
00318         }
00319         if (exceptfds)
00320         {
00321           if (FD_ISSET(s, &tmp_except[0]))
00322                FD_SET (s, exceptfds);
00323           else FD_CLR (s, exceptfds);
00324         }
00325       }
00326
00327       /* Do as Linux and return the time left of the period.
00328        * NB! The 'tv_sec' can be negative if select_s() took too long.
00329        */
00330       if (timeout)
00331       {
00332         double remaining = timeval_diff (&now, &expiry);
00333
00334         timeout->tv_sec  = (long)(remaining / 1E6);
00335         timeout->tv_usec = (long)remaining % 1000000UL;
00336       }
00337       goto select_ok;
00338     }
00339
00340     if (expired)
00341     {
00342       SOCK_DEBUGF ((", timeout!: %.6fs", timeval_diff(&now, &starttime)/1E6));
00343
00344       if (readfds)
00345          for (s = 0; s < num_fd; s++)
00346              FD_CLR (s, readfds);
00347
00348       if (writefds)
00349          for (s = 0; s < num_fd; s++)
00350              FD_CLR (s, writefds);
00351
00352       if (exceptfds)
00353          for (s = 0; s < num_fd; s++)
00354              FD_CLR (s, exceptfds);
00355
00356       ret_count = 0;   /* should already be 0 */
00357       goto select_ok;
00358     }
00359   }
00360
00361 select_intr:
00362   SOCK_DEBUGF ((", EINTR"));
00363   SOCK_ERRNO (EINTR);
00364   ret_count = -1;
00365   _sock_crit_stop();
00366
00367 select_ok:
00368   _sock_sig_restore();
00369
00370   return (ret_count);
00371 }
00372
00373 #if defined(WIN32)
00374 int W32_CALL select (int nfds, fd_set *read_fds, fd_set *write_fds,
00375                      fd_set *except_fds, struct timeval *timeout)
00376 {
00377   return select_s (nfds, read_fds, write_fds, except_fds, timeout);
00378 }
00379 #endif
00380
00381
00382 #ifdef NOT_YET
00383 int pselect (int nfds, fd_set *readfds, fd_set *writefds,
00384              fd_set *exceptfds, struct timespec *timeout,
00385              const sigset_t *sigmask)
00386 {
00387   struct timeval tv;
00388   sigset_t old_mask;
00389   int      rc;
00390
00391   if (timeout)
00392   {
00393     tv.tv_sec  = tv_sec;
00394     tv_tv_nsec = 1000UL * tv_usec;
00395   }
00396   if (sigmask)
00397      sigprocmask (SIG_BLOCK, sigmask, &old_mask);
00398
00399   rc = select (nfds, readfs, writefds, exceptfds, timeout ? &tv : NULL);
00400
00401   if (sigmask)
00402      sigprocmask (SIG_UNBLOCK, &old_mask, NULL);
00403
00404   return (rc);
00405 }
00406 #endif
00407
00408 /*
00409  * Check listen-queue for first connected TCB.
00410  * Only called for listening (accepting) sockets.
00411  */
00412 static __inline int listen_queued (Socket *socket)
00413 {
00414   int i;
00415
00416   for (i = 0; i < socket->backlog && i < DIM(socket->listen_queue); i++)
00417   {
00418     _tcp_Socket *tcb = socket->listen_queue[i];
00419
00420     if (!tcb)
00421        continue;
00422
00423     /* Socket has reached Established state or receive data above
00424      * low water mark. This means, socket may have reached Closed,
00425      * but this still counts as a readable event.
00426      */
00427     if (tcb->state == tcp_StateESTAB ||
00428         sock_rbused((sock_type*)tcb) > socket->recv_lowat)
00429        return (1);
00430   }
00431   return (0);
00432 }
00433
00434 /*
00435  * Return TRUE if socket has a "real" error and not a "pending" error.
00436  * I.e. EALREADY is not a real error, but a pending condition until a
00437  * non-blocking socket is actually connected. Or if connection fails,
00438  * in which case the error is ECONNREFUSED.
00439  *
00440  * This signalled read/write state is assumed to persist for the
00441  * remaining life of the socket.
00442  */
00443 #define READ_STATE_MASK   (SS_CANTRCVMORE)  /* set in recv() or shutdown() */
00444 #define WRITE_STATE_MASK  (SS_CANTSENDMORE | SS_ISCONNECTED)
00445
00446 static __inline int sock_signalled (Socket *socket, int mask)
00447 {
00448   if (socket->so_state & mask)
00449      return (1);
00450
00451   /* A normal blocking socket. 'so_error' is set in
00452    * connect(), a "ICMP Unreachable" callback or when RST received
00453    * in pctcp.c. Otherwise 'so_error' is zero.
00454    */
00455   if (!(socket->so_state & SS_NBIO))
00456      return (socket->so_error);
00457
00458 #if 0
00459   if (socket->so_options & SO_ACCEPTCONN) /* non-blocking listen sock */
00460      return (0);
00461
00462   if (socket->so_error == EALREADY)       /* temporary non-blocking error */
00463      return (0);
00464   return (1);
00465 #else
00466   return (0);
00467 #endif
00468 }
00469
00470 #if !defined(WIN32)
00471 /*
00472  * Check if a standard handle is ready.
00473  * This should return TRUE if handle is redirected.
00474  */
00475 static BOOL handle_ready (int hnd)
00476 {
00477   union REGS regs;
00478
00479 #if defined(__HIGHC__)
00480   regs.x.ax = 0x4406;
00481   regs.x.bx = hnd;
00482 #else
00483   regs.w.ax = 0x4406;
00484   regs.w.bx = hnd;
00485 #endif
00486
00487   intdos (&regs, &regs);
00488   return (regs.h.al == 0xFF);  /* ready character device */
00489 }
00490 #else
00491 #define handle_ready(hnd)  0
00492 #endif
00493
00494 /*
00495  * Check if 's' can be read from.
00496  */
00497 static int read_select (int s, Socket *socket)
00498 {
00499   if (s == STDIN_FILENO)
00500   {
00501 #if defined(__DJGPP__) && 0
00502     struct timeval tv = { 0, 0 };
00503     fd_set rd;
00504     int    rc;
00505
00506     FD_ZERO (&rd);
00507     FD_SET (STDIN_FILENO, &rd);
00508     rc = (select) (1, &rd, NULL, NULL, &tv);
00509     return (rc == 1 ? 1 : 0);
00510 #else
00511     return (watt_kbhit() || handle_ready(STDIN_FILENO));
00512 #endif
00513   }
00514
00515   if (s <= STDERR_FILENO)
00516      return (0);
00517
00518   if (socket->so_type == SOCK_PACKET)
00519      return sock_packet_rbused (socket) ? 1 : 0;
00520
00521   if (socket->so_type == SOCK_RAW)
00522   {
00523 #if defined(USE_IPV6)
00524     if (socket->so_family == AF_INET6)
00525        return sock_rbused ((sock_type*)socket->raw6_sock) ? 1 : 0;
00526 #endif
00527     return sock_rbused ((sock_type*)socket->raw_sock) ? 1 : 0;
00528   }
00529
00530   if (socket->so_type == SOCK_DGRAM)
00531   {
00532     size_t len;
00533
00534     if (socket->so_state & SS_PRIV)
00535          len = sock_recv_used ((sock_type*)socket->udp_sock);
00536     else len = sock_rbused ((sock_type*)socket->udp_sock);
00537
00538     if (len > socket->recv_lowat ||
00539         sock_signalled(socket,READ_STATE_MASK))
00540        return (1);
00541     return (0);
00542   }
00543
00544   if (socket->so_type == SOCK_STREAM)
00545   {
00546     sock_type *sk = (sock_type*) socket->tcp_sock;
00547
00548     if ((socket->so_state & SS_NBIO) &&
00549         sk->tcp.state == tcp_StateESTAB &&
00550         socket->so_error == EALREADY)
00551        socket->so_error = EISCONN;
00552
00553     if (sock_signalled(socket,READ_STATE_MASK) || /* signalled for read_s() */
00554         sk->tcp.state >= tcp_StateLASTACK      || /* got FIN from peer */
00555         sock_rbused(sk) > socket->recv_lowat)     /* Rx-data above low-limit */
00556        return (1);
00557
00558     if ((socket->so_options & SO_ACCEPTCONN) &&   /* connection pending */
00559         listen_queued(socket))
00560        return (1);
00561   }
00562   return (0);
00563 }
00564
00565 /*
00566  * Check if 's' can be written to.
00567  */
00568 static int write_select (int s, Socket *socket)
00569 {
00570 #if defined(__DJGPP__) && 0
00571   if (s == STDOUT_FILENO || s == STDERR_FILENO)
00572   {
00573     struct timeval tv = { 0, 0 };
00574     fd_set wr;
00575     int    rc;
00576
00577     FD_ZERO (&wr);
00578     FD_SET (s, &wr);
00579     rc = (select) (1, NULL, &wr, NULL, &tv);
00580     return (rc == 1 ? 1 : 0);
00581   }
00582 #else
00583   if (s == STDOUT_FILENO)
00584      return !ferror (stdout);
00585
00586   if (s == STDERR_FILENO)
00587      return !ferror (stderr);
00588 #endif
00589
00590   if (s == STDIN_FILENO)
00591      return (0);
00592
00593   /* SOCK_PACKET, SOCK_RAW and SOCK_DGRAM sockets are always writeable
00594    */
00595   if (socket->so_type == SOCK_PACKET ||
00596       socket->so_type == SOCK_RAW    ||
00597       socket->so_type == SOCK_DGRAM)
00598      return (1);
00599
00600   if (socket->so_type == SOCK_STREAM)
00601   {
00602     sock_type *sk = (sock_type*) socket->tcp_sock;
00603
00604     if (sk->tcp.state == tcp_StateESTAB)
00605     {
00606       if ((socket->so_state & SS_NBIO) && socket->so_error == EALREADY)
00607          socket->so_error = EISCONN;
00608
00609       if (sock_tbleft(sk) > socket->send_lowat)  /* Tx room above low-limit */
00610          return (1);
00611     }
00612     if (sk->tcp.state >= tcp_StateESTCL)
00613        return (1);
00614
00615     if (sock_signalled(socket,WRITE_STATE_MASK)) /* signalled for write */
00616        return (1);
00617   }
00618   return (0);
00619 }
00620
00621 /*
00622  * Check 's' for exception or faulty condition.
00623  */
00624 static int exc_select (int s, Socket *socket)
00625 {
00626   if (s < SK_FIRST)
00627      return (0);
00628
00631 #if 0
00632   if (sock_signalled(socket, READ_STATE_MASK|WRITE_STATE_MASK))
00633      return (1);
00634 #endif
00635
00636   ARGSUSED (socket);
00637   return (0);
00638 }
00639 #endif /* USE_BSD_API */
00640
00641
00642 /*
00643  * A small test program (for djgpp/Watcom/DMC)
00644  */
00645 #if defined(TEST_PROG)
00646
00647 #include <unistd.h>
00648 #include <conio.h>
00649
00650 #if defined(__WATCOMC__)
00651   #include "getopt.h"
00652
00653   #define usleep(us)      delay((us)/1000)
00654   #define uclock()        clock()
00655   #define UCLOCKS_PER_SEC CLOCKS_PER_SEC
00656   #define uclock_t        clock_t
00657 #endif
00658
00659 void usage (const char *argv0)
00660 {
00661   fprintf (stderr,
00662            "Usage: %s [-s select_size] [-w micro-sec] [-hid]\n"
00663            "\t\t -s  set the number of fd's to select for (default 1)\n"
00664            "\t\t -w  time to wait in select (default 0.5)\n"
00665            "\t\t -h  don't use 8254 hi-resolution timer function\n"
00666            "\t\t -i  use timer ISR (init_timer_isr)\n"
00667            "\t\t -d  write debug to wattcp.sk/wattcp.dbg\n", argv0);
00668   exit (-1);
00669 }
00670
00671 char *fd_set_str (char *buf, size_t len, const fd_set *fd)
00672 {
00673   char *p   = buf;
00674   char *end = buf + len;
00675   int   i, num;
00676
00677 #if 0
00678   p += sprintf (p, "%d: ", fd->fd_count);
00679 #endif
00680
00681   for (i = 0, num = 0; i < 8*FD_SETSIZE; i++)
00682   {
00683     if (FD_ISSET(i,fd))
00684     {
00685       p += sprintf (p, "%d,", i);
00686       num++;
00687     }
00688     if (p > end - 12)
00689     {
00690       strcat(p, "<overflow>");
00691       break;
00692     }
00693   }
00694   if (p < end - 12)
00695      strcat (p, "<none set>");
00696   return (buf);
00697 }
00698
00699 void select_dump (int sock_err, int num_fd, const struct timeval *tv,
00700                   const fd_set *fd_read,
00701                   const fd_set *fd_write,
00702                   const fd_set *fd_except)
00703 {
00704   char buf1[512], buf2[512], buf3[512];
00705
00706   printf ("select_dump: sock_err %d, num_fd %d, timeout %ld.06%lu\n"
00707           "\tread-fds:   %s\n"
00708           "\twrite-fds:  %s\n"
00709           "\texcept-fds: %s\n",
00710           sock_err, num_fd, (long)tv->tv_sec, tv->tv_usec,
00711           fd_set_str(buf1,sizeof(buf1),fd_read),
00712           fd_set_str(buf2,sizeof(buf2),fd_write),
00713           fd_set_str(buf3,sizeof(buf3),fd_except));
00714 }
00715
00716 int main (int argc, char **argv)
00717 {
00718   BOOL   use_8254  = TRUE;
00719   BOOL   use_isr   = FALSE;
00720   BOOL   debug     = FALSE;
00721   double sel_wait  = 0.5;
00722   int    sel_size  = 1;
00723   int    ch;
00724
00725   while ((ch = getopt(argc, argv, "s:w:hid?")) != EOF)
00726     switch (ch)
00727     {
00728       case 'h':
00729            use_8254 = FALSE;
00730            break;
00731
00732       case 'i':
00733            init_timer_isr();
00734            use_isr = TRUE;
00735            break;
00736
00737       case 's':
00738            sel_size = atoi (optarg);
00739            break;
00740
00741       case 'd':
00742            dbug_init();
00743            debug = TRUE;
00744            break;
00745
00746       case 'w':
00747            sel_wait = atof (optarg);
00748            break;
00749
00750       case '?':
00751       default:
00752            usage (argv[0]);
00753            break;
00754     }
00755
00756   if (sel_size <= 0 || sel_size > MAX_SOCKETS)
00757   {
00758     printf ("Illegal select-size %d. Range 0 - %d\n", sel_size, MAX_SOCKETS);
00759     return (-1);
00760   }
00761
00762   sock_init();
00763
00764   printf ("select-wait %.3f sec, select-size %d, debug %d, "
00765           "has_8254 %d, uses_int8 %d\n"
00766           "Press 'q' to quit\n", sel_wait, sel_size, debug,
00767           has_8254, use_isr);
00768   hires_timer (use_8254);
00769
00770   while (1)
00771   {
00772     fd_set read [NUM_SOCK_FDSETS];
00773     struct timeval tv;
00774     uclock_t start, diff;
00775
00776     tv.tv_sec  = (time_t)sel_wait;
00777     tv.tv_usec = 1000000UL * (sel_wait - (double)tv.tv_sec);
00778     start = uclock();
00779     memset (read, 0, sizeof(read));
00780     FD_SET (STDIN_FILENO, &read[0]);
00781
00782     if (select_s (sel_size, read, NULL, NULL, &tv) < 0)
00783     {
00784       perror ("select");
00785       break;
00786     }
00787
00788     diff = uclock() - start;
00789     if (debug)
00790        SOCK_DEBUGF ((", diff: %.6fs", (double)diff/(double)UCLOCKS_PER_SEC));
00791
00792     fputc ('.', stderr);
00793     usleep (100000UL);
00794
00795     if (FD_ISSET(0,&read[0]))
00796     {
00797       int ch = getch();
00798       fputc (ch, stderr);
00799       if (ch == 'q')
00800          break;
00801     }
00802   }
00803   return (0);
00804 }
00805 #endif
Generated on Wed Jan 25 15:42:39 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/SETTOD.C Source File

SRC/SETTOD.C

Go to the documentation of this file.
00001
00016 #if !defined(__DJGPP__)  /* allready have settimeofday() */
00017
00018 #include <errno.h>       /* EINVAL */
00019 #include <sys/wtime.h>   /* time func/types */
00020
00021 #include "wattcp.h"
00022 #include "misc.h"
00023 #include "settod.h"
00024
00025 int MS_CDECL settimeofday (struct timeval *tv, ...)
00026 {
00027   if (tv)
00028   {
00029     time_t t       = (time_t)tv->tv_sec;
00030     struct tm *tmp = localtime (&t);
00031
00032     if (tmp && tmp->tm_year >= 80)
00033     {
00034 #if defined(WIN32)
00035       /* todo */
00036 #else
00037       struct dosdate_t newdate;
00038       struct dostime_t newtime;
00039
00040       newdate.year    = (WORD)(tmp->tm_year + 1900);
00041       newdate.month   = (BYTE)(tmp->tm_mon + 1);
00042       newdate.day     = (BYTE)(tmp->tm_mday);
00043       newtime.hour    = (BYTE)(tmp->tm_hour);
00044       newtime.minute  = (BYTE)(tmp->tm_min);
00045       newtime.second  = (BYTE)(tmp->tm_sec);
00046       newtime.hsecond = (BYTE)(tv->tv_usec / 10000ul);
00047       if (_dos_setdate(&newdate) == 0  && /* int 21h fxn 2Bh */
00048           _dos_settime(&newtime) == 0)    /* int 21h fxn 2Dh */
00049         return (0);
00050 #endif
00051     }
00052   }
00053   SOCK_ERRNO (EINVAL);
00054   return (-1);
00055 }
00056 #endif /* !__DJGPP__ */
Generated on Wed Jan 25 15:42:39 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/SETTOD.H Source File

SRC/SETTOD.H

Go to the documentation of this file.
00001
00011 #ifndef _w32_SETTIMEOFDAY_H
00012 #define _w32_SETTIMEOFDAY_H
00013
00014 #if !defined(__DJGPP__) /* djgpp already has [g|s]ettimeofday() */
00015
00016 extern int MS_CDECL settimeofday (struct timeval *tv, ...);
00017
00018 #endif
00019 #endif
Generated on Wed Jan 25 15:42:39 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/SHUTDOWN.C Source File

SRC/SHUTDOWN.C

Go to the documentation of this file.
00001
00005 /*  BSD sockets functionality for Waterloo TCP/IP
00006  *
00007  *  Copyright (c) 1997-2002 Gisle Vanem <giva@bgnett.no>
00008  *
00009  *  Redistribution and use in source and binary forms, with or without
00010  *  modification, are permitted provided that the following conditions
00011  *  are met:
00012  *  1. Redistributions of source code must retain the above copyright
00013  *     notice, this list of conditions and the following disclaimer.
00014  *  2. Redistributions in binary form must reproduce the above copyright
00015  *     notice, this list of conditions and the following disclaimer in the
00016  *     documentation and/or other materials provided with the distribution.
00017  *  3. All advertising materials mentioning features or use of this software
00018  *     must display the following acknowledgement:
00019  *       This product includes software developed by Gisle Vanem
00020  *       Bergen, Norway.
00021  *
00022  *  THIS SOFTWARE IS PROVIDED BY ME (Gisle Vanem) AND CONTRIBUTORS ``AS IS''
00023  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00024  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00025  *  ARE DISCLAIMED.  IN NO EVENT SHALL I OR CONTRIBUTORS BE LIABLE FOR ANY
00026  *  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00027  *  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00028  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00029  *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00030  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00031  *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00032  *
00033  *  Version
00034  *
00035  *  0.5 : Dec 18, 1997 : G. Vanem - created
00036  */
00037
00038 #include "socket.h"
00039
00040 #if defined(USE_BSD_API)
00041
00042 #define SHUT_RD   0    /* Further receives are disallowed */
00043 #define SHUT_WR   1    /* Further sends are disallowed */
00044 #define SHUT_RDWR 2    /* Further sends and receives are disallowed */
00045
00046 int W32_CALL shutdown (int s, int how)
00047 {
00048   Socket *socket = _socklist_find (s);
00049
00050 #if defined(USE_DEBUG)
00051   static char fmt[] = "\nshutdown:%d/??";
00052   static char rrw[] = "r w rw";
00053
00054   how &= 3;
00055   fmt [sizeof(fmt)-3] = rrw [2*how];
00056   fmt [sizeof(fmt)-2] = rrw [2*how+1];
00057 #endif
00058
00059   SOCK_PROLOGUE (socket, fmt, s);
00060
00061   switch (how)
00062   {
00063     case SHUT_RD:
00064          socket->so_error    = ESHUTDOWN;
00065          socket->so_state   |=  SS_CANTRCVMORE;
00066       /* socket->so_options &= ~SO_ACCEPTCONN; */
00067
00071          return (0);
00072
00073     case SHUT_WR:
00074          socket->so_error    = ESHUTDOWN;
00075          socket->so_state   |=  SS_CANTSENDMORE;
00076          socket->so_state   &= ~SS_ISLISTENING;
00077       /* socket->so_options &= ~SO_ACCEPTCONN; */
00078
00083          return (0);
00084
00085     case SHUT_RDWR:
00086          socket->so_error    = ESHUTDOWN;
00087          socket->so_state   |= (SS_CANTRCVMORE | SS_CANTSENDMORE);
00088          socket->so_state   &= ~SS_ISLISTENING;
00089       /* socket->so_options &= ~SO_ACCEPTCONN; */
00090          return (0);
00091   }
00092
00093   SOCK_ERRNO (EINVAL);
00094   return (-1);
00095 }
00096 #endif  /* USE_BSD_API */
Generated on Wed Jan 25 15:42:39 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/SIGNAL.C Source File

SRC/SIGNAL.C

Go to the documentation of this file.
00001
00005 /*  BSD sockets functionality for Waterloo TCP/IP
00006  *
00007  *  Copyright (c) 1997-2002 Gisle Vanem <giva@bgnett.no>
00008  *
00009  *  Redistribution and use in source and binary forms, with or without
00010  *  modification, are permitted provided that the following conditions
00011  *  are met:
00012  *  1. Redistributions of source code must retain the above copyright
00013  *     notice, this list of conditions and the following disclaimer.
00014  *  2. Redistributions in binary form must reproduce the above copyright
00015  *     notice, this list of conditions and the following disclaimer in the
00016  *     documentation and/or other materials provided with the distribution.
00017  *  3. All advertising materials mentioning features or use of this software
00018  *     must display the following acknowledgement:
00019  *       This product includes software developed by Gisle Vanem
00020  *       Bergen, Norway.
00021  *
00022  *  THIS SOFTWARE IS PROVIDED BY ME (Gisle Vanem) AND CONTRIBUTORS ``AS IS''
00023  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00024  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00025  *  ARE DISCLAIMED.  IN NO EVENT SHALL I OR CONTRIBUTORS BE LIABLE FOR ANY
00026  *  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00027  *  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00028  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00029  *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00030  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00031  *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00032  *
00033  *  Version
00034  *
00035  *  0.5 : Dec 18, 1997 : G. Vanem - created
00036  */
00037
00038 #include "socket.h"
00039
00040 #if defined(USE_BSD_API)
00041
00042 #include "nochkstk.h"
00043
00044 #if defined(__HIGHC__)  /* Metaware's HighC have SIGBREAK == SIGQUIT */
00045   #undef SIGBREAK
00046 #elif defined(__DMC__)  /* Digital Mars have SIGBREAK == SIGINT */
00047   #undef SIGBREAK
00048 #endif
00049
00050 /*
00051  * I'm not sure what the benefit of using sigprocmask() on djgpp is.
00052  * So leave it alone for the moment.
00053  */
00054 #if defined(__DJGPP__)
00055   #define USE_SIGMASK  0
00056 #else
00057   #define USE_SIGMASK  0
00058 #endif
00059
00060 struct signal_table {
00061        void      (*old)(int);
00062        int         sig_num;
00063        const char *sig_name;
00064        BOOL        caught;  /* we caught this signal */
00065        BOOL        exit;    /* exit if app doesn't have a signal-handler */
00066      };
00067
00068 static struct signal_table sig_tab[] = {
00069     { NULL, SIGINT,   "SIGINT",  FALSE, TRUE },
00070 #if defined(SIGBREAK)
00071     { NULL, SIGBREAK, "SIGBREAK",FALSE, TRUE }, /* Watcom */
00072 #endif
00073 #if defined(SIGQUIT)
00074     { NULL, SIGQUIT,  "SIGQUIT", FALSE, TRUE },  /* should we trap this? */
00075 #endif
00076 #if defined(SIGPIPE)
00077     { NULL, SIGPIPE,  "SIGPIPE", FALSE, FALSE }, /* djgpp */
00078 #endif
00079 #if defined(SIGALRM) && 0  /* Should we hook this? */
00080     { NULL, SIGALRM,  "SIGALRM", FALSE, FALSE }, /* djgpp */
00081 #endif
00082   };
00083
00084 static int signal_depth = 0; /* Our running signal "depth" */
00085
00086 /*
00087  * We block all signals from being raised while running our
00088  * loops (connect etc.). Postpone all original signal-handlers until
00089  * we're done.
00090  */
00091 #if (USE_SIGMASK == 0)
00092 /*
00093  * Our signal catcher. Set 'caught' flag.
00094  */
00095 static void MS_CDECL sig_catch (int sig)
00096 {
00097   int i;
00098
00099   for (i = 0; i < DIM(sig_tab); i++)
00100       if (sig == sig_tab[i].sig_num)
00101       {
00102         sig_tab[i].caught = TRUE;
00103         break;
00104       }
00105   signal (sig, SIG_IGN);    /* ignore until we restore it */
00106 }
00107 #endif
00108
00109 /*
00110  * Signal handling for most loops where we can be interrupted
00111  * by user pressing ^C/^Break (generating SIGINT/SIGBREAK).
00112  */
00113 int _sock_sig_setup (void)
00114 {
00115 #if (USE_SIGMASK)
00116   static sigset_t old_mask, new_mask;
00117 #endif
00118   int i;
00119
00120   if (signal_depth > 0 ||
00121       ++signal_depth > 1)
00122      return (0);
00123
00124   _sock_start_timer();
00125
00126 #if (USE_SIGMASK)
00127   sigemptyset (&new_mask);
00128 #endif
00129
00130   for (i = 0; i < DIM(sig_tab); i++)
00131   {
00132     int sig = sig_tab[i].sig_num;
00133
00134     sig_tab[i].caught = FALSE;
00135
00136 #if (USE_SIGMASK)
00137     sigaddset (&new_mask, sig);
00138     sigprocmask (SIG_SETMASK, &new_mask, &old_mask);
00139 #else
00140     sig_tab[i].old = signal (sig, sig_catch);
00141 #endif
00142   }
00143   return (0);
00144 }
00145
00146 /*
00147  * Return number of blocked signal that are pending/caught.
00148  */
00149 int _sock_sig_pending (void)
00150 {
00151   int i, num;
00152
00153 #if (USE_SIGMASK)
00154   sigset_t pending;
00155
00156   sigpending (&pending);
00157   for (i = num = 0; i < DIM(sig_tab); i++)
00158       if (sigismember (&pending, sig_tab[i].sig_num))
00159          num++;
00160 #else
00161   for (i = num = 0; i < DIM(sig_tab); i++)
00162       if (sig_tab[i].caught)
00163          num++;
00164 #endif
00165   return (num);
00166 }
00167
00168 /*
00169  * Unhook signal-handlers and raise() signals we caught.
00170  */
00171 int _sock_sig_restore (void)
00172 {
00173   int i;
00174
00175   if (signal_depth == 0 ||
00176       --signal_depth > 0)
00177      return (0);
00178
00179   _sock_stop_timer();
00180
00181   for (i = 0; i < DIM(sig_tab); i++)
00182   {
00183     int sig = sig_tab[i].sig_num;
00184
00185 #if (USE_SIGMASK)
00186     sigset_t pending, new_set;
00187
00188     if (sigpending(&pending) == 0 &&
00189         sigismember(&pending,sig))
00190     {
00191       /* The signal became pending while we blocked it.
00192        * I.e. ^C was pressed, so act on it.
00193        */
00194       sigemptyset (&new_set);
00195       sigaddset (&new_set, sig);
00196
00197       SOCK_DEBUGF ((", raising %s", sig_tab[i].sig_name));
00198       SOCK_ENTER_SCOPE();
00199       sigprocmask (SIG_UNBLOCK, &new_set, NULL);
00200       SOCK_LEAVE_SCOPE();
00201     }
00202 #else
00203     signal (sig, sig_tab[i].old);
00204     if (!sig_tab[i].caught)
00205        continue;
00206
00207     sig_tab[i].caught = FALSE;
00208     if (sig_tab[i].exit &&
00209         (sig_tab[i].old == SIG_DFL ||
00210          sig_tab[i].old == SIG_IGN ||
00211          sig_tab[i].old == sig_handler_watt))
00212     {
00213       char buf[30];
00214
00215       strcpy (buf, "\nTerminating on ");
00216       strcat (buf, sig_tab[i].sig_name);
00217       sock_sig_exit (buf, sig);
00218       /* no return */
00219     }
00220     SOCK_DEBUGF ((", raising %s", sig_tab[i].sig_name));
00221     SOCK_ENTER_SCOPE();
00222     raise (sig);
00223     SOCK_LEAVE_SCOPE();
00224     return (-1);
00225 #endif
00226   }
00227   return (0);
00228 }
00229
00230 /*
00231  * Raise SIGPIPE/SIGURG if signal defined (not needed yet).
00232  * Return -1 with errno = EPIPE.
00233  */
00234 int _sock_sig_epipe (void)
00235 {
00236 #if defined(SIGPIPE)
00237   raise (SIGPIPE);
00238 #endif
00239   SOCK_ERRNO (EPIPE);
00240   return (-1);
00241 }
00242 #endif  /* USE_BSD_API */
Generated on Wed Jan 25 15:42:39 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/SOCK_DBU.C Source File

SRC/SOCK_DBU.C

Go to the documentation of this file.
00001
00004 #include <stdio.h>
00005
00006 #include "copyrigh.h"
00007 #include "wattcp.h"
00008 #include "strings.h"
00009 #include "misc.h"
00010 #include "timer.h"
00011 #include "pcdbug.h"
00012 #include "pcbuf.h"
00013
00014 void sock_debugdump (const sock_type *s)
00015 {
00016 #if defined(USE_DEBUG)
00017   const _tcp_Socket *tcp = &s->tcp;
00018
00019   if (s->raw.ip_type == IP4_TYPE)
00020      return;
00021
00022 #if defined(__SMALL16__)
00023   (*_printf) ("next       %04X\n",      s->tcp.next);
00024 #elif defined(__LARGE__)
00025   (*_printf) ("next       %04X:%04X\n", FP_SEG(s->tcp.next), FP_OFF(s->tcp.next));
00026 #else
00027   (*_printf) ("next       %08lX\n",     (DWORD)s->tcp.next);
00028 #endif
00029
00030   (*_printf) ("type       %d\n", s->tcp.ip_type);
00031
00032   (*_printf) ("stat/error %s\n", s->tcp.err_msg ? s->tcp.err_msg : "(none)");
00033   (*_printf) ("usr-timer  %08lX (%sexpired)\n",
00034               s->tcp.usertimer, chk_timeout(s->tcp.usertimer) ? "" : "not ");
00035
00036   switch (s->tcp.ip_type)
00037   {
00038     case UDP_PROTO:
00039          (*_printf) ("udp rxdata  %u `%.*s'\n",
00040                      s->tcp.rx_datalen, s->tcp.rx_datalen, s->tcp.rx_data);
00041          break;
00042     case TCP_PROTO:
00043          (*_printf) ("tcp rxdata  %u `%.*s'\n",
00044                      tcp->rx_datalen, tcp->rx_datalen, tcp->rx_data);
00045          (*_printf) ("tcp state  %u (%s)\n",
00046                      tcp->state, tcpStateName(tcp->state));
00047          break;
00048   }
00049 #else
00050   ARGSUSED (s);
00051 #endif
00052 }
Generated on Wed Jan 25 15:42:39 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/SOCK_IN.C Source File

SRC/SOCK_IN.C

Go to the documentation of this file.
00001
00011 #include <stdio.h>
00012
00013 #include "copyrigh.h"
00014 #include "wattcp.h"
00015 #include "language.h"
00016 #include "misc.h"
00017 #include "timer.h"
00018 #include "wdpmi.h"
00019 #include "pctcp.h"
00020
00021 /*
00022  * ip user level timer stuff
00023  *   void ip_timer_init (void *s, int delayseconds)
00024  *   int  ip_timer_expired (void *s)
00025  *  - 0 if not expired
00026  */
00027 void ip_timer_init (sock_type *s, unsigned seconds)
00028 {
00029   if (seconds)
00030        s->tcp.usertimer = set_timeout (1000UL * seconds);
00031   else s->tcp.usertimer = 0;
00032 }
00033
00034 int ip_timer_expired (const sock_type *s)
00035 {
00036   if (!s->tcp.usertimer)
00037      return (0);
00038   return chk_timeout (s->tcp.usertimer);
00039 }
00040
00041 /*
00042  * _ip_delay0 called by macro sock_wait_established()
00043  *
00044  */
00045 int _ip_delay0 (sock_type *s, int timeout_sec, UserHandler fn, int *statusptr)
00046 {
00047   int status = -1;
00048
00049   ip_timer_init (s, timeout_sec);
00050   do
00051   {
00052 #if !defined(USE_UDP_ONLY)
00053     if (s->tcp.ip_type == TCP_PROTO && tcp_established(&s->tcp))
00054     {
00055       status = 0;
00056       break;
00057     }
00058 #endif
00059
00060     if (!tcp_tick(s))
00061     {
00062       if (s->tcp.err_msg == NULL)
00063           s->tcp.err_msg = _LANG("Host refused connection");
00064       status = -1;       /* get an early reset */
00065       break;
00066     }
00067     if (ip_timer_expired(s))
00068     {
00069       if (s->tcp.err_msg == NULL)
00070           s->tcp.err_msg = _LANG("Open timed out");
00071       if (!(s->tcp.locflags & LF_NOCLOSE))
00072          sock_close (s);
00073       status = -1;
00074       break;
00075     }
00076     if (fn && (status = (*fn)(s)) != 0)
00077        break;
00078
00079     if (s->tcp.usr_yield)
00080          (*s->tcp.usr_yield)();
00081     else WATT_YIELD();
00082
00083     if (s->tcp.ip_type == UDP_PROTO)
00084     {
00085       status = 0;
00086       break;
00087     }
00088   }
00089   while (1);
00090
00091   if (statusptr)
00092      *statusptr = status;
00093   return (status);
00094 }
00095
00096 /*
00097  * _ip_delay1 called by macro sock_wait_input()
00098  */
00099 int _ip_delay1 (sock_type *s, int timeoutseconds, UserHandler fn, int *statusptr)
00100 {
00101   int status = -1;
00102
00103   ip_timer_init (s, timeoutseconds);
00104
00105 #if !defined(USE_UDP_ONLY)
00106   sock_flush (s);    /* new enhancement */
00107 #endif
00108
00109   do
00110   {
00111     if (sock_dataready(s))
00112     {
00113       status = 0;
00114       break;
00115     }
00116     if (s->tcp.locflags & LF_GOT_FIN)
00117     {
00118       status = 1;
00119       break;
00120     }
00121     if (!tcp_tick(s))
00122     {
00123       status = 1;
00124       break;
00125     }
00126
00127     if (ip_timer_expired(s))
00128     {
00129       if (s->tcp.err_msg == NULL)
00130           s->tcp.err_msg = _LANG("Connection timed out");
00131       if (!(s->tcp.locflags & LF_NOCLOSE))
00132          sock_close (s);
00133       status = -1;
00134       break;
00135     }
00136     if (fn && (status = (*fn)(s)) != 0)
00137        break;
00138
00139     if (s->tcp.usr_yield)
00140         (*s->tcp.usr_yield)();
00141     else WATT_YIELD();
00142   }
00143   while (1);
00144
00145   if (statusptr)
00146      *statusptr = status;
00147   return (status);
00148 }
00149
00150 /*
00151  * _ip_delay2 called by macro sock_wait_closed();
00152  */
00153 int _ip_delay2 (sock_type *s, int timeoutseconds, UserHandler fn, int *statusptr)
00154 {
00155   int status = -1;
00156
00157   if (s->tcp.ip_type != TCP_PROTO)
00158   {
00159     if (statusptr)
00160        *statusptr = 1;
00161     return (1);
00162   }
00163
00164 #if !defined(USE_UDP_ONLY)
00165   ip_timer_init (s, timeoutseconds);
00166
00167   do
00168   {
00169     /* in this situation we know user is not planning to read rx_data
00170      */
00171     s->tcp.rx_datalen = 0;
00172
00173     if (!tcp_tick(s))
00174     {
00175       status = 1;
00176       break;
00177     }
00178     if (ip_timer_expired(s))
00179     {
00180       if (s->tcp.err_msg == NULL)
00181           s->tcp.err_msg = _LANG("Connection timed out");
00182       TCP_ABORT (&s->tcp);
00183       status = -1;
00184       break;
00185     }
00186     if (fn && (status = (*fn)(s)) != 0)
00187        break;
00188
00189     if (s->tcp.usr_yield)
00190         (*s->tcp.usr_yield)();
00191     else WATT_YIELD();
00192   }
00193   while (1);
00194
00195   if (statusptr)
00196      *statusptr = status;
00197
00198 #else
00199   ARGSUSED (fn);
00200   ARGSUSED (timeoutseconds);
00201 #endif
00202   return (status);
00203 }
00204
00205 int sock_timeout (sock_type *s, int sec)
00206 {
00207   if (s->tcp.ip_type != TCP_PROTO)
00208      return (1);
00209
00210 #if !defined(USE_UDP_ONLY)
00211   if (s->tcp.state != tcp_StateESTAB)
00212      return (2);
00213
00214   s->tcp.timeout = set_timeout (1000UL * sec);
00215 #else
00216   ARGSUSED (sec);
00217 #endif
00218   return (0);
00219 }
00220
00221 int sock_established (sock_type *s)
00222 {
00223   switch (s->tcp.ip_type)
00224   {
00225     case UDP_PROTO:
00226          return (1);
00227
00228 #if !defined(USE_UDP_ONLY)
00229     case TCP_PROTO:
00230          return (s->tcp.state == tcp_StateESTAB ||
00231                  s->tcp.state == tcp_StateESTCL ||
00232                  s->tcp.state == tcp_StateCLOSWT);
00233 #endif
00234     default:
00235          return (0);
00236   }
00237 }
00238
Generated on Wed Jan 25 15:42:39 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/SOCK_INI.C Source File

SRC/SOCK_INI.C

Go to the documentation of this file.
00001
00019 #include <stdio.h>
00020 #include <stdlib.h>
00021 #include <signal.h>
00022 #include <setjmp.h>
00023 #include <float.h>
00024 #include <math.h>
00025 #include <time.h>
00026 #include <io.h>
00027
00028 #ifdef __HIGHC__
00029 #include <init.h>  /* _mwenv(), PL_ENV */
00030 #endif
00031
00032 #if defined (__DJGPP__)
00033 #include <sys/exceptn.h>
00034 #endif
00035
00036 #include "copyrigh.h"
00037 #include "wattcp.h"
00038 #include "strings.h"
00039 #include "language.h"
00040 #include "misc.h"
00041 #include "timer.h"
00042 #include "wdpmi.h"
00043 #include "x32vm.h"
00044 #include "powerpak.h"
00045 #include "pcbootp.h"
00046 #include "pcrarp.h"
00047 #include "pcdhcp.h"
00048 #include "pcconfig.h"
00049 #include "pcmulti.h"
00050 #include "pcicmp.h"
00051 #include "pctcp.h"
00052 #include "pcarp.h"
00053 #include "pcsed.h"
00054 #include "pcqueue.h"
00055 #include "pcpkt.h"
00056 #include "pcdbug.h"
00057 #include "netaddr.h"
00058 #include "syslog2.h"
00059 #include "udp_dom.h"
00060 #include "bsdname.h"
00061 #include "bsddbug.h"
00062 #include "ip4_frag.h"
00063 #include "ip6_in.h"
00064 #include "printk.h"
00065 #include "sock_ini.h"
00066
00067 #if (DOSX & PHARLAP)
00068 #include <mw/exc.h>
00069 #endif
00070
00071 #if defined(WATT32_DOS_DLL)
00072 /* #include <exc.h> */
00073 #endif
00074
00075 #if defined(USE_TFTP)
00076 #include "tftp.h"
00077 #endif
00078
00079 #if defined(USE_BSD_API)
00080 #include "socket.h"
00081 #include "get_xby.h"
00082 #endif
00083
00084 #if defined(USE_BIND)
00085 #include "resolver.h"
00086 #endif
00087
00088 #if defined(USE_ECHO_DISC)
00089 #include "echo.h"
00090 #endif
00091
00092 #if defined(USE_PPPOE)
00093 #include "pppoe.h"
00094 #endif
00095
00096 #if defined(USE_IDNA)
00097 #include "idna.h"
00098 #endif
00099
00100 #if defined(USE_DYNIP_CLI)
00101 #include "dynip.h"
00102 #endif
00103
00104 #if defined(WIN32)
00105 #include "winpcap.h"
00106 #endif
00107
00108 #if defined(__HIGHC__)  /* Metaware's HighC have SIGBREAK == SIGQUIT */
00109 #undef SIGBREAK
00110 #endif
00111
00112 #include "nochkstk.h"
00113
00114 BOOL _bootp_on       = FALSE;
00115 BOOL _dhcp_on        = FALSE;
00116 BOOL _dhcp6_on       = FALSE;
00117 BOOL _rarp_on        = FALSE;
00118 BOOL _do_mask_req    = FALSE;
00119 BOOL _watt_do_exit   = TRUE;
00120 BOOL _watt_no_config = FALSE;
00122 WattUserConfigFunc _watt_user_config_fn = NULL;
00123
00124 BOOL survive_eth = 0;
00129 #if defined(USE_DHCP)
00130   BOOL survive_bootp = TRUE;
00131 #else
00132   BOOL survive_bootp = FALSE;
00133 #endif
00134
00135 #if defined(USE_RARP)
00136   BOOL survive_dhcp = TRUE;
00137 #else
00138   BOOL survive_dhcp = FALSE;
00139 #endif
00140
00141 BOOL survive_rarp = FALSE;
00142 BOOL _watt_is_init     = FALSE;
00144 static BOOL tcp_is_init = FALSE;
00145 static int  old_break   = -1;
00184 WattUserConfigFunc _watt_user_config (WattUserConfigFunc fn)
00185 {
00186   WattUserConfigFunc old_fn = _watt_user_config_fn;
00187
00188   _watt_user_config_fn = fn;
00189   return (old_fn);
00190 }
00191
00196 static int do_exit (int code)
00197 {
00198   if (_watt_do_exit)
00199      exit (code);
00200   return (code);
00201 }
00202
00206 #if !defined(MAKE_TSR)
00207
00208 static BOOL use_except = TRUE;
00209
00210 #if (DOSX & (DOS4GW|X32VM))
00211
00212 static jmp_buf            exc_jmp;
00213 static struct FAULT_STRUC exc_buf;
00214
00215 static void pre_except_handler (const struct FAULT_STRUC *exc)
00216 {
00217   exc_buf = *exc;
00218   longjmp (exc_jmp, SIGSEGV);
00219 }
00220
00221 #if !defined(__CCDL__) && !defined(__BORLANDC__)
00222 static void do_traceback (void)
00223 {
00224   _printk_safe = TRUE;
00225   _printk ("\r\nException %d at %04X:%08X\r\n",
00226            exc_buf.fault_num, exc_buf.cs, exc_buf.eip);
00227
00228   _printk ("  EAX %08X  EBX %08X  ECX %08X  EDX %08X\r\n",
00229            exc_buf.eax, exc_buf.ebx, exc_buf.ecx, exc_buf.edx);
00230
00231   _printk ("  ESI %08X  EDI %08X  EBP %08X  ESP %08X\r\n",
00232            exc_buf.esi, exc_buf.edi, exc_buf.ebp, exc_buf.esp);
00233
00234   _printk ("  DS %04X  ES %04X  FS %04X  GS %04X  SS %04X  EFLAGS %08X\r\n",
00235            exc_buf.ds, exc_buf.es, exc_buf.fs, exc_buf.gs, exc_buf.ss,
00236            exc_buf.eflags);
00237
00238   _printk_flush();
00239
00240   if (!exc_buf.mode)  /* exception in protected mode */
00241   {
00242     stack_rewind (exc_buf.eip, exc_buf.ebp);
00243     _printk_flush();
00244   }
00245 }
00246 #endif   /* __CCDL__ */
00247 #endif   /* DOS4GW|X32VM */
00248
00249
00250 #if defined (__DJGPP__)
00251 static void except_handler (int sig)
00252 {
00253   static BOOL been_here = FALSE;
00254   static jmp_buf exc_buf;
00255
00256   _watt_fatal_error = TRUE;
00257
00258   if (been_here)
00259   {
00260     been_here = FALSE;
00261     signal (sig, SIG_DFL);
00262     __djgpp_exception_state_ptr = &exc_buf;
00263   }
00264   else  /* save exception context in case of reentry */
00265   {
00266     memcpy (&exc_buf, __djgpp_exception_state_ptr, sizeof(exc_buf));
00267     been_here = TRUE;
00268     psignal (sig, "TCP/IP shutdown");
00269     rundown_run();
00270
00271 #if 0
00272
00273     StackWalk (exc_buf[0].__eip, exc_buf[0].__ebp);
00274 #endif
00275   }
00276   raise (SIGABRT);
00277 }
00278
00279 #elif (DOSX & PHARLAP)
00280 static void except_handler (excReg *regs)
00281 {
00282   _watt_fatal_error = TRUE;
00283   rundown_run();
00284   _exit (-1);
00285   ARGSUSED (regs);
00286 }
00287
00288 #else
00289 /*
00290  * Note: Watcom's extension to SIGFPE is undocumented.
00291  * This is dead code on Windows since except_handler()
00292  * isn't installed yet.
00293  */
00294 static void except_handler (int sig, int code)
00295 {
00296 #if defined(__WATCOMC__)
00297   if (sig == SIGFPE && code == FPE_IOVERFLOW)
00298   {
00299     _fpreset();
00300     outsnl (_LANG("Ignoring SIGFPE (FPE_IOVERFLOW)"));
00301     return;
00302   }
00303 #endif
00304
00305 #if !defined(WIN32)
00306   /* Nothing is really fatal under Watt-32/Win32 */
00307   _watt_fatal_error = TRUE;
00308 #endif
00309
00310 #if defined(SIGFPE)
00311   if (sig == SIGFPE)
00312   {
00313 #if defined(__WATCOMC__)
00314     outs (_LANG("Trapping SIGFPE code 0x"));
00315     outhex (code);
00316 #else
00317     outsnl (_LANG("Trapping SIGFPE."));
00318 #endif
00319   }
00320   else
00321 #endif
00322
00323 #if defined(SIGSEGV)
00324   if (sig == SIGSEGV)
00325   {
00326     outsnl (_LANG("Trapping SIGSEGV"));
00327 #if (DOSX & (DOS4GW|X32VM)) && !defined(__CCDL__) && !defined(__BORLANDC__)
00328     do_traceback();
00329 #endif
00330   }
00331 #endif
00332
00333   rundown_run();
00334
00335 #if (DOSX) /* don't pull in iob for small/large */
00336   fflush (stdout);
00337   fflush (stderr);
00338 #endif
00339
00340   ARGSUSED (code);
00341 #if defined(__POCC__)
00342   exit (-1);
00343 #else
00344   _exit (-1);
00345 #endif
00346 }
00347 #endif  /* __DJGPP__ */
00348
00349
00354 static void setup_sig_handlers (void)
00355 {
00356 #if (DOSX & (DOS4GW|X32VM))
00357   volatile int sig;
00358 #endif
00359
00360 #if defined(WIN32)     /* no need for a special exc-handler (yet?) */
00361   use_except = FALSE;
00362 #else
00363   if (getenv("WATT32-NOEXC") ||    /* don't trap exceptions */
00364       getenv("WATT32-NOEXCEPT"))
00365      use_except = FALSE;
00366 #endif
00367
00368   if (!use_except)
00369      return;
00370
00371 #if (DOSX & PHARLAP)
00372   InstallExcHandler (except_handler);
00373
00374 #elif (DOSX & X32VM)
00375   _printk_init (2000, NULL);
00376   _x32_fault_intercept (pre_except_handler);
00377   sig = setjmp (exc_jmp);
00378   if (sig)
00379      except_handler (sig, 0);
00380
00381 #elif (DOSX & DOS4GW)
00382   signal (SIGSEGV, (void(*)(int))except_handler);
00383   signal (SIGFPE, (void(*)(int))except_handler);
00384
00385   _printk_init (2000, NULL);
00386   dpmi_except_handler (pre_except_handler); /* Only effective for Causeway */
00387   sig = setjmp (exc_jmp);
00388   if (sig)
00389      except_handler (sig, 0);
00390
00391 #elif defined(__DJGPP__)
00392   signal (SIGSEGV, except_handler);
00393   signal (SIGTRAP, except_handler);
00394   signal (SIGFPE, except_handler);
00395   signal (SIGILL, except_handler);
00396
00397 #else
00398   /*
00399    * SIGSEGV may not be effective under all environments.
00400    * PowerPak definetely supports SIGSEGV.
00401    */
00402   #ifdef SIGSEGV
00403     signal (SIGSEGV, (void(*)(int))except_handler);
00404   #endif
00405   #ifdef SIGFPE
00406     signal (SIGFPE, (void(*)(int))except_handler);
00407   #endif
00408 #endif
00409 }
00410
00411 static void restore_sig_handlers (void)
00412 {
00413   if (!_watt_cbroke)
00414      signal (SIGINT, SIG_DFL);
00415
00416   if (old_break >= 0)
00417      set_cbreak (old_break);
00418
00419   if (!use_except)
00420      return;
00421
00422 #if (DOSX & DOS4GW)
00423   signal (SIGSEGV, SIG_DFL);
00424   signal (SIGFPE, SIG_DFL);
00425
00426 #elif defined(__DJGPP__)
00427   signal (SIGSEGV, SIG_DFL);
00428   signal (SIGTRAP, SIG_DFL);
00429   signal (SIGFPE, SIG_DFL);
00430   signal (SIGILL, SIG_DFL);
00431
00432 #elif defined(__BORLANDC__) && defined(SIGSEGV) && defined(SIGFPE)
00433   signal (SIGSEGV, SIG_DFL);
00434   signal (SIGFPE, SIG_DFL);
00435 #endif
00436 }
00437 #endif  /* MAKE_TSR */
00438
00439
00444 static void tcp_shutdown (void)
00445 {
00446   if (!tcp_is_init)
00447      return;
00448
00449 #if !defined(USE_UDP_ONLY)
00450   while (_tcp_allsocs)
00451         TCP_ABORT (_tcp_allsocs);   /* Sends RST if needed */
00452   _tcp_allsocs = NULL;
00453 #endif
00454   _udp_allsocs = NULL;
00455
00456 #if defined(USE_DHCP)
00457   /*
00458    * If DHCP-config saved to disk and remaining lease is above min.,
00459    * do nothing. Otherwise be nice and release our address
00460    */
00461   DHCP_release (FALSE);
00462 #endif
00463
00464 #if defined(USE_PPPOE)
00465   pppoe_exit();
00466 #endif
00467
00468   tcp_is_init = FALSE;
00469 }
00470
00471
00481 static int tcp_init (void)
00482 {
00483   int rc = WERR_NO_DRIVER;
00484
00485   if (!tcp_is_init)
00486   {
00487     tcp_is_init = TRUE;
00488     rc = _eth_init();          /* initialize LAN-card */
00489     if (rc == 0)
00490     {
00491       last_nameserver  = 0;    /* reset the nameserver table */
00492       last_cookie = 0;         /* eat all remaining crumbs */
00493       if (!init_localport())   /* clear local ports in-use */
00494          return (WERR_NO_MEM);
00495
00496       /* I not already set, try asking a DOS network extension
00497        * for a host-name.
00498        */
00499       if (!strcmp(hostname,"random-pc"))
00500          _get_machine_name (hostname, sizeof(hostname));
00501     }
00502   }
00503   return (rc);
00504 }
00505
00509 static void tcp_post_init (void)
00510 {
00511   DWORD max_rwin;
00512   int   MTU;
00513
00514   if (!tcp_is_init)       /* tcp_init() not called */
00515      return;
00516
00517 #if defined(USE_BSD_API)
00518   ReadEthersFile();       /* requires gethostbyname() */
00519 #endif
00520
00521 #if defined(USE_PROFILER)
00522   if (profile_enable)
00523      profile_init();
00524 #endif
00525
00526 #if defined(USE_IPV6)
00527   _ip6_post_init();
00528 #endif
00529
00530 #if defined(USE_DEBUG)
00531   if (debug_on >= 3)
00532      rundown_dump();
00533 #endif
00534
00535   MTU = pkt_get_mtu();    /* driver knows correct MTU (includes MAC-header) */
00536   if (MTU > 0)
00537      _mtu = MTU;
00538
00539   if (_mtu > ETH_MAX_DATA)
00540       _mtu = ETH_MAX_DATA;
00541
00542   if (_mss > MSS_MAX)
00543       _mss = MSS_MAX;
00544
00545   /* Work around a limitation of NDIS3PKT. It only allocates 6 buffers
00546    * per VDD (DOS-box). Thus receiving a burts of RWIN/MSS packets, they
00547    * could all get lost. Clamp our advertised RWIN.
00548    *
00549    * Note: bandwidth <= 1.3 * MTU / (RTT * sqrt(Loss))
00550    */
00551   max_rwin = 6 * _mss;
00552   if (_eth_ndis3pkt && tcp_recv_win > max_rwin)
00553      tcp_recv_win = max_rwin;
00554
00555   if (usr_post_init)      /* tell hook(s) we're done */
00556     (*usr_post_init)();
00557 }
00558
00565 static int tcp_do_boot (BOOL try_bootp, BOOL try_dhcp, BOOL try_rarp)
00566 {
00567   if (try_bootp)
00568   {
00569 #if defined(USE_BOOTP)
00570     if (BOOTP_do_boot())
00571        return (0);
00572
00573     outsnl (_LANG("failed"));
00574     if (!survive_bootp)
00575        return (WERR_BOOTP_FAIL);
00576 #else
00577     outsnl ("BOOTP needed, but library wasn't built with \"USE_BOOTP\"");
00578 #endif
00579
00580 #if defined(USE_DHCP)
00581     try_dhcp = TRUE;
00582 #endif
00583
00584 #if defined(USE_RARP)
00585     try_rarp = TRUE;
00586 #endif
00587   }
00588
00589   if (try_dhcp)
00590   {
00591 #if defined(USE_DHCP)
00592     if (DHCP_do_boot())
00593        return (0);
00594
00595     outsnl (_LANG("failed"));
00596     if (!survive_dhcp)
00597        return (WERR_DHCP_FAIL);
00598 #else
00599     outsnl ("DHCP needed, but library wasn't built with \"USE_DHCP\"");
00600 #endif
00601
00602 #if defined(USE_RARP)
00603     try_rarp = TRUE;
00604 #endif
00605   }
00606
00607   if (try_rarp)
00608   {
00609 #if defined(USE_RARP)
00610     if (_dorarp())
00611        return (0);
00612
00613     outsnl (_LANG("failed"));
00614     if (!survive_rarp)
00615        return (WERR_RARP_FAIL);
00616 #else
00617     outsnl ("RARP needed, but library wasn't built with \"USE_RARP\"");
00618 #endif
00619   }
00620   return (WERR_NO_IPADDR);  /* all attempts failed */
00621 }
00622
00623
00624 #if defined(USE_DEBUG)
00625 /*
00626  * A guard against this common error; The wattlib user forgot to rebuild
00627  * using the latest <tcp.h>.
00628  */
00629 static void check_sock_sizes (size_t tcp_Sock_size, size_t udp_Sock_size)
00630 {
00631   if (tcp_Sock_size > 0 && tcp_Sock_size < sizeof(_tcp_Socket))
00632   {
00633     (*_printf) ("Watt-32 development error: sizeof(_tcp_Socket) in "
00634                 "<tcp.h> too small. %d bytes needed\n", SIZEOF(_tcp_Socket));
00635     exit (-1);
00636   }
00637   if (udp_Sock_size > 0 && udp_Sock_size < sizeof(_udp_Socket))
00638   {
00639     (*_printf) ("Watt-32 development error: sizeof(_udp_Socket) in "
00640                 "<tcp.h> too small. %d bytes needed\n", SIZEOF(_udp_Socket));
00641     exit (-1);
00642   }
00643 }
00644 #endif
00645
00646
00647 /*
00648  * Return error text for watt_sock_init() result.
00649  */
00650 const char * sock_init_err (int rc)
00651 {
00652   enum eth_init_result rc2 = rc;
00653
00654   switch (rc2)
00655   {
00656     case WERR_ILL_DOSX:
00657          return _LANG ("Illegal DOS-extender and library combination");
00658
00659     case WERR_NO_MEM:
00660          return _LANG ("No memory for buffers");
00661
00662     case WERR_PKT_ERROR:
00663          return _LANG ("Error in PKTDRVR interface");
00664
00665     case WERR_NO_DRIVER:
00666          return _LANG ("No PKTDRVR found");
00667
00668     case WERR_BOOTP_FAIL:
00669          return _LANG ("BOOTP protocol failed");
00670
00671     case WERR_DHCP_FAIL:
00672          return _LANG ("DHCP protocol failed");
00673
00674     case WERR_RARP_FAIL:
00675          return _LANG ("RARP protocol failed");
00676
00677     case WERR_NO_IPADDR:
00678          return _LANG ("Failed to get an IP-address");
00679
00680     case WERR_PPPOE_DISC:
00681          return _LANG ("Timeout in PPPoE discovery");
00682
00683     case WERR_NO_ERROR:
00684          break;
00685   }
00686   return _LANG ("No error");
00687 }
00688
00689
00695 static BOOL sock_init_called = FALSE;
00696
00697 int watt_sock_init (size_t tcp_Sock_size, size_t udp_Sock_size)
00698 {
00699   static int rc = 0;
00700
00701   if (sock_init_called)  /* return previous result */
00702      return (rc);
00703
00704   sock_init_called = TRUE;
00705
00706 #if defined(USE_CRTDBG) || defined(USE_FORTIFY)
00707   memdbg_init();
00708 #endif
00709
00710 #if defined(WIN32)
00711   /* Nothing to do here */
00712 #elif defined(__HIGHC__)
00713   if (_mwenv != PL_ENV)
00714   {
00715     outsnl (_LANG("\7Only Pharlap DOS extender supported"));
00716     return do_exit (rc = WERR_ILL_DOSX);
00717   }
00718 #elif defined(WATCOM386)
00719   if (!dpmi_init())
00720      return do_exit (rc = WERR_ILL_DOSX);
00721 #endif
00722
00723 #if (DOSX & POWERPAK)
00724   if (!powerpak_init())
00725   {
00726     puts ("\7PowerPak initialisation failed");
00727     return do_exit (rc = WERR_ILL_DOSX);
00728   }
00729 #endif
00730
00731 #if defined(USE_DEBUG)
00732   check_sock_sizes (tcp_Sock_size, udp_Sock_size);
00733 #else
00734   ARGSUSED (tcp_Sock_size);
00735   ARGSUSED (udp_Sock_size);
00736 #endif
00737
00738 #if defined(USE_DEBUG) && defined(WATT32_DOS_DLL)
00739   _printf = import_export.printf;
00740 #endif
00741
00742
00743   /* DOSX: Set DOS far-ptr, get CPU type, use BSWAP
00744    *       instruction on 486+CPUs, setup DOS transfer buffer.
00745    * ALL:  Find DOS/Win-version, init timers etc.
00746    */
00747   init_misc();
00748
00749 #if !defined(MAKE_TSR)
00750   setup_sig_handlers();
00751 #endif
00752
00753   /* Init PKTDRVR, get ether-addr, set config-hook for
00754    * parsing TCP-values
00755    */
00756   rc = tcp_init();
00757
00758   if (rc && !survive_eth)  /* if survive we pretend all is ok and go on */
00759      return do_exit (rc);  /* else failed */
00760
00761   _watt_is_init = TRUE;
00762   start_time    = set_timeout (0);
00763   start_day     = get_day_num();
00764
00765
00766   /* Setup the ARP daemon, GvB 2002-09
00767    */
00768   _arp_init();
00769
00770   /* Prepare to parse WATTCP.CFG config options related
00771    * to DHCP, SYSLOG, BIND, TFTP, ECHO/DISCARD clients, PPPoE and IPv6.
00772    */
00773 #if defined(USE_DHCP)
00774   DHCP_init();
00775 #endif
00776
00777 #if defined(USE_BSD_API)
00778   syslog_init();
00779 #endif
00780
00781 #if defined (USE_BIND)
00782   res_init0();
00783 #endif
00784
00785 #if defined(USE_TFTP)
00786   tftp_init();
00787 #endif
00788
00789 #if defined(USE_ECHO_DISC)
00790   echo_discard_init();
00791 #endif
00792
00793 #if defined(USE_PPPOE)
00794   pppoe_init();
00795 #endif
00796
00797 #if defined(USE_DYNIP_CLI)
00798   dynip_init();
00799 #endif
00800
00801 #if defined(USE_IPV6)
00802   _ip6_init();
00803 #endif
00804
00805 #if defined(USE_IDNA)
00806   iconv_init (0);
00807 #endif
00808
00809   old_break = tcp_cbreak (0x10);
00810
00811   /* The only atexit() handler
00812    */
00813   atexit ((void(*)(void))sock_exit);
00814
00815 #if !defined(MAKE_TSR)
00816   RUNDOWN_ADD (restore_sig_handlers, 3);
00817 #endif
00818
00819   if (_watt_no_config && !_watt_user_config_fn)
00820   {
00821     if (!my_ip_addr)
00822     {
00823 #if defined(USE_BOOTP)
00824       _bootp_on = TRUE;   /* if no fixed IP, try BOOTP/DHCP/RARP */
00825 #endif
00826 #if defined(USE_DHCP)
00827       _dhcp_on = TRUE;
00828 #endif
00829 #if defined(USE_RARP)
00830       _rarp_on = TRUE;
00831 #endif
00832     }
00833     else if (debug_on)
00834       outsnl (_LANG("Fixed IP configuration."));
00835   }
00836
00837   else if (!tcp_config(NULL))
00838   {
00839 #if defined(USE_BOOTP)
00840     _bootp_on = TRUE;     /* if no config file try BOOTP/DHCP/RARP */
00841 #endif
00842 #if defined(USE_DHCP)
00843     _dhcp_on = TRUE;
00844 #endif
00845 #if defined(USE_RARP)
00846     _rarp_on = TRUE;
00847 #endif
00848   }
00849
00850 #if defined(USE_DEBUG)
00851   if (_dbugxmit)          /* if dbug_init() called */
00852   {
00853     dbug_open();
00854 #if defined(USE_BSD_API)
00855     _sock_dbug_open();
00856 #endif
00857   }
00858 #endif
00859
00860
00861 #if defined(USE_DHCP)
00862   /*
00863    * If we read previously configured values okay, skip the below booting.
00864    */
00865   if (_dhcp_on && DHCP_read_config())
00866   {
00867     _dhcp_on  = FALSE;
00868     _bootp_on = FALSE;
00869     _rarp_on  = FALSE;
00870   }
00871 #endif
00872
00873   /* Test and fix configured values
00874    */
00875   tcp_post_init();
00876
00877   if (_bootp_on || _dhcp_on || _rarp_on)
00878   {
00879     rc = tcp_do_boot (_bootp_on, _dhcp_on, _rarp_on);
00880     if (rc && !survive_eth)
00881        return do_exit (rc);
00882   }
00883
00884
00885 #if defined(USE_PPPOE)
00886   if (!pppoe_start())
00887   {
00888     outsnl (_LANG("Timeout waiting for PADS/PADO"));
00889     rc = WERR_PPPOE_DISC;
00890     if (!survive_eth)
00891        return do_exit (rc);
00892   }
00893 #endif
00894
00895   if (!my_ip_addr)   /* all boot attempts failed */
00896   {
00897     outsnl (_LANG("All attempt (config-file/DHCP/BOOTP/RARP) to get "
00898                   "a IP-address failed.\r\n"
00899                   "Check your configuration."));
00900
00903     rc = WERR_NO_IPADDR;
00904     if (!survive_eth)
00905        return do_exit (rc);
00906   }
00907
00908   if (_pkt_inf)  /* Warn only if we have a pktdrvr/WinPcap instance */
00909   {
00910 #if defined(WIN32)
00911     if (my_ip_addr && !pkt_check_address(my_ip_addr))
00912        (*_printf) ("Warning: using same IP-address (%s) as Winsock.\n\7",
00913                    _inet_ntoa(NULL,my_ip_addr));
00914 #endif
00915
00916 #if defined(USE_DEBUG)
00917     if (sin_mask == 0)
00918        outsnl ("Warning: \"NETMASK\" is 0.0.0.0 !");
00919
00920     if (!_arp_check_gateways())
00921        outsnl ("Warning: multiple or no default gateway!");
00922 #endif
00923   }
00924
00925   if (dynamic_host && !reverse_lookup_myip())
00926      outsnl (_LANG("Cannot reverse resolve local IP-address. "
00927                    "Set \"DYNAMIC_HOST\" = 0."));
00928
00929 #if defined(USE_MULTICAST)
00930   if (_multicast_on)
00931   {
00932     /* all multicast level 2 systems must join at startup
00933      */
00934     join_mcast_group (MCAST_ALL_SYST);
00935   }
00936 #endif
00937
00938 #if defined(USE_FRAGMENTS)
00939   /*
00940    * Add a daemon to check for IP-fragment time-outs.
00941    */
00942   addwattcpd (chk_timeout_frags);
00943 #endif
00944
00945   /* if "ICMP_MASK_REQ = 1" in wattcp.cfg, send an ICMP_MASK_REQ.
00946    */
00947   if (_do_mask_req)
00948      icmp_send_mask_req();
00949
00950 #if defined(USE_TFTP)
00951   /*
00952    * If application supplied a tftp_writer hook, try to load
00953    * the specified BOOT-file.
00954    */
00955   if (tftp_writer)
00956      tftp_boot_load();
00957 #endif
00958
00959 #if defined(USE_ECHO_DISC)
00960   echo_discard_start();       /* start echo/discard services */
00961 #endif
00962
00963 #if defined(USE_DYNIP_CLI)
00964   dynip_exec();
00965 #endif
00966
00967   return (rc);
00968 }
00969
00970 /*
00971  * Old compatibility (if user didn't include <tcp.h>
00972  */
00973 #undef sock_init
00974 int sock_init (void)
00975 {
00976   return watt_sock_init (0, 0);
00977 }
00978
00979
00985 void MS_CDECL sock_exit (void)
00986 {
00987   if (_watt_is_init || sock_init_called)
00988   {
00989     _watt_is_init = sock_init_called = FALSE;
00990
00991     if (!_watt_fatal_error)
00992        tcp_shutdown();
00993
00994     /* Closed the PKTDRVR etc. No effect if already done.
00995      */
00996     rundown_run();
00997   }
00998 }
00999
01000
01004 void sock_sig_exit (const char *msg, int sig)
01005 {
01006 #if defined(SIGBREAK)
01007   if (sig == SIGBREAK) /* should only happen for Watcom (from signal.c) */
01008      sig = SIGINT;
01009 #endif
01010
01011   if (sig == SIGINT)
01012      _watt_cbroke++;
01013
01014   sock_exit();   /* calls registered rundown functions */
01015
01016   if (msg)
01017      outsnl (msg);
01018
01019 #if (DOSX)  /* don't pull in _streams[] for SMALL/LARGE model */
01020   fflush (stdout);
01021   fflush (stderr);
01022 #endif
01023
01024
01025 #if defined(__HIGHC__)
01026  /*
01027   * If "#pragma on(check_stack)" is in effect somewhere, we're sure
01028   * to crash in an atexit() function. It's not nice, but bypass them
01029   * by calling _exit(). Application should hook SIGINT itself to clean
01030   * itself up. Same applies for djgpp apps.
01031   */
01032   sig = 0;  /* calls exit() */
01033
01034 #elif defined(__DJGPP__)
01035  /*
01036   * Some error (in Watt-32 or djgpp's crt?) causes the INT 1B
01037   * vector not always to be restored when running with CWSDPMI. This
01038   * causes a page fault in CWSDPMI. Not nice, but circumvent this by
01039   * calling _exit(). Not sure if toggling the exceptions will help, so
01040   * leave them alone. NTVDM doesn't seem to mind we calling _exit()...
01041   */
01042 /* __djgpp_exception_toggle(); */
01043   sig = 0;
01044
01045 #elif !defined(__WATCOMC__)
01046   sig = 0;
01047 #endif
01048
01049 #if (defined(__BORLANDC__) || defined(__TURBOC__)) && !defined(__FLAT__)
01050   _stklen = 0x1000;   /* avoid stack-overflow during exit() */
01051 #endif
01052
01053 #if !defined(__POCC__)
01054   if (sig == SIGINT)
01055     _exit (-1);
01056   else
01057 #endif
01058     exit (-1);
01059 }
01060
01061
01062 /*
01063  * Make sure user links the correct C-libs
01064  */
01065 #if defined(WATCOM386)
01066   #if defined(__SW_3R)
01067     #pragma library ("clib3r.lib");
01068     #pragma library ("math387r.lib");
01069
01070   #else /* __SW_3S */
01071     #pragma library ("clib3s.lib");
01072     #pragma library ("math387s.lib");
01073   #endif
01074
01075 #elif defined(_MSC_VER) && (_MSC_VER >= 1200) && 0
01076   #if defined(_DEBUG)
01077     #pragma comment (library, "wattcpvc_imp_d.lib")
01078   #else
01079     #pragma comment (library, "wattcpvc_imp.lib")
01080   #endif
01081
01082 #elif defined(_MSC_VER) && (_MSC_VER >= 700) && 0
01083   #if defined(__SMALL__)
01084     #pragma comment (library, "wattcpMS.lib")
01085   #elif defined(__LARGE__)
01086     #pragma comment (library, "wattcpML.lib")
01087   #elif defined(__386__)
01088     #pragma comment (library, "wattcpMF.lib")
01089   #endif
01090
01091 #elif defined(__DMC__) && 0
01092   #if defined(WIN32)
01093     #pragma comment (lib, "wattcpd_imp.lib")
01094   #elif defined(__SMALL16__)
01095     #pragma comment (lib, "wattcpDS.lib")
01096   #elif defined(__LARGE__)
01097     #pragma comment (lib, "wattcpDL.lib")
01098   #elif defined(DMC386)
01099     #pragma comment (lib, "wattcpDF.lib")
01100   #endif
01101 #endif
01102
Generated on Wed Jan 25 15:42:39 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/SOCK_INI.H Source File

SRC/SOCK_INI.H

Go to the documentation of this file.
00001
00003 #ifndef _w32_SOCK_INI_H
00004 #define _w32_SOCK_INI_H
00005
00006 enum eth_init_result {    /* pass to sock_init_err() */
00007      WERR_NO_ERROR,
00008      WERR_ILL_DOSX,       /* Watcom/HighC: illegal DOS-extender */
00009      WERR_NO_MEM,         /* All: No memory for misc. buffers */
00010      WERR_NO_DRIVER,      /* All: No network driver found (PKTDRVR/WinPcap) */
00011      WERR_PKT_ERROR,      /* All: General error in PKTDRVR/WinPcap interface */
00012      WERR_BOOTP_FAIL,     /* All: BOOTP protocol failed */
00013      WERR_DHCP_FAIL,      /* All: DHCP protocol failed */
00014      WERR_RARP_FAIL,      /* All: RARP protocol failed */
00015      WERR_NO_IPADDR,      /* All: Failed to find an IP-address */
00016      WERR_PPPOE_DISC      /* All: PPPoE discovery failed (timeout) */
00017    };
00018
00019 #define _bootp_on      NAMESPACE (_bootp_on)
00020 #define _dhcp_on       NAMESPACE (_dhcp_on)
00021 #define _dhcp6_on      NAMESPACE (_dhcp6_on)
00022 #define _rarp_on       NAMESPACE (_rarp_on)
00023 #define _do_mask_req   NAMESPACE (_do_mask_req)
00024
00025 #define survive_eth    NAMESPACE (survive_eth)
00026 #define survive_bootp  NAMESPACE (survive_bootp)
00027 #define survive_dhcp   NAMESPACE (survive_dhcp)
00028 #define survive_rarp   NAMESPACE (survive_rarp)
00029
00030 W32_DATA int  _bootp_on;    /* boot-up through BOOTP and/or DHCP */
00031 W32_DATA int  _dhcp_on;
00032 W32_DATA int  _dhcp6_on;
00033 W32_DATA int  _rarp_on;
00034 W32_DATA BOOL _do_mask_req;
00035 W32_DATA BOOL _watt_do_exit;
00036 W32_DATA BOOL _watt_is_init;
00037 W32_DATA BOOL _watt_no_config;
00038
00039 W32_DATA BOOL survive_eth, survive_bootp, survive_dhcp, survive_rarp;
00040
00041 W32_FUNC int           watt_sock_init (size_t tcp_sz, size_t udp_sz);
00042 W32_FUNC void MS_CDECL sock_exit      (void);
00043 W32_FUNC const char   *sock_init_err  (int rc);
00044 W32_FUNC void          sock_sig_exit  (const char *msg, int sig) ATTR_NORETURN();
00045
00046 #if !defined(sock_init) && defined(TEST_PROG)
00047 #define sock_init()  watt_sock_init (0, 0)
00048 #endif
00049
00050 #endif
Generated on Wed Jan 25 15:42:39 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/SOCK_IO.C Source File

SRC/SOCK_IO.C

Go to the documentation of this file.
00001
00007 #include <stdio.h>
00008 #include <stdlib.h>
00009 #include <string.h>
00010
00011 #include "copyrigh.h"
00012 #include "wattcp.h"
00013 #include "strings.h"
00014 #include "misc.h"
00015 #include "pcconfig.h"
00016 #include "pctcp.h"
00017
00018 /*
00019  * sock_putc - put a character
00020  *    - no expansion but flushes on CR/LF
00021  *    - returns character
00022  */
00023 BYTE sock_putc (sock_type *s, BYTE c)
00024 {
00025 #if !defined(USE_UDP_ONLY)
00026   if (c == '\n' || c == '\r')
00027      sock_flushnext (s);
00028 #endif
00029   sock_write (s, &c, 1);
00030   return (c);
00031 }
00032
00033
00034 /*
00035  * sock_puts - does not append carriage return in binary mode
00036  *           - returns length.
00037  *           - only accepts ASCII strings.
00038  */
00039 int sock_puts (sock_type *s, const BYTE *data)
00040 {
00041   int len;
00042
00043 #if defined(USE_BSD_API)
00044   if (s->raw.ip_type == IP4_TYPE)
00045      return (0);   /* not supported yet */
00046 #endif
00047
00048   len = strlen ((const char*)data);
00049
00050   if (!(s->tcp.sockmode & SOCK_MODE_BINARY)) /* udp/tcp ASCII mode */
00051   {
00052     BYTE tmp [MAX_IP4_DATA];
00054     if (len > 0)  /* merge in a newline */
00055     {
00056       len = min (len, SIZEOF(tmp)-2);  /* May truncate, tough luck */
00057       memcpy (tmp, data, len);
00058       tmp [len++] = '\r';
00059       tmp [len++] = '\n';
00060       data = tmp;
00061     }
00062     else
00063     {
00064       data = (BYTE*)"\r\n";
00065       len  = 2;
00066     }
00067     sock_write (s,data, len);
00068   }
00069   else
00070   {
00071 #if !defined(USE_UDP_ONLY)
00072     sock_flushnext (s);
00073 #endif
00074     len = sock_write (s, data, len);
00075   }
00076   return (len);
00077 }
00078
00079
00080 /*
00081  * sock_gets - read a {\r|\n} terminated string from a UDP/TCP socket.
00082  *    - return length of returned string
00083  *    - removes end of line terminator(s)
00084  *    - Quentin Smart and Mark Phillips fixed some problems
00085  *
00086  * BIG WARNING: Don't use sock_gets() for packetised protocols like
00087  *              SSH. Only suitable for ASCII orientented protocols
00088  *              like POP3/SMTP/NNTP etc.
00089  */
00090 int sock_gets (sock_type *s, BYTE *data, int bmax)
00091 {
00092   int   len = 0, frag = 0;
00093   BYTE *nl_p, *cr_p, eol;
00094
00095 #if defined(USE_BSD_API)
00096   if (s->raw.ip_type == IP4_TYPE)
00097      return (0);   /* raw sockets not supported */
00098 #endif
00099
00100 #if !defined(USE_UDP_ONLY)
00101   if (s->udp.ip_type == TCP_PROTO &&
00102       s->tcp.missed_seq[0] != s->tcp.missed_seq[1])
00103      frag = s->tcp.missed_seq[1] - s->tcp.recv_next;
00104 #endif
00105
00106   if (s->tcp.sockmode & SOCK_MODE_SAWCR)
00107   {
00108     s->tcp.sockmode &= ~SOCK_MODE_SAWCR;
00109     if (s->tcp.rx_datalen > 0 &&
00110         (*s->tcp.rx_data == '\n' || *s->tcp.rx_data == '\0'))
00111     {
00112       memmove (s->tcp.rx_data, s->tcp.rx_data + 1, frag + s->tcp.rx_datalen);
00113       s->tcp.rx_datalen--;
00114     }
00115   }
00116
00117   /* Return if there is nothing in the buffer.
00118    */
00119   if (s->tcp.rx_datalen == 0)
00120      return (0);
00121
00122   /* If there is space for all the data, then copy all of it,
00123    * otherwise, only copy what the space will allow (taking
00124    * care to reserve space for the null terminator.
00125    */
00126   --bmax;
00127   if (bmax > s->tcp.rx_datalen)
00128       bmax = s->tcp.rx_datalen;
00129   memcpy (data, s->tcp.rx_data, bmax);
00130   data [bmax] = '\0';
00131
00132   /* At this point, data is a null-terminated string,
00133    * containing as much of the data as is possible.
00134    */
00135   len = bmax;
00136
00137   /* Because we are in ASCII mode, we assume that the
00138    * sender will be consistent in which kind of CRLF is
00139    * sent (e.g. one and only one of \r\n, \r0, \r, or \n).
00140    * So if both \r and \n are found, we assume that they
00141    * are always next to each other, and \n\r is invalid.
00142    */
00143
00144   /* Zero the first occurance of \r and \n in data.
00145    */
00146   cr_p = (BYTE*) memchr (data, '\r', bmax);
00147   if (cr_p)
00148      *cr_p = '\0';
00149
00150   nl_p = (BYTE*) memchr (data, '\n', bmax);
00151   if (nl_p)
00152      *nl_p = '\0';
00153
00154 #if !defined(USE_UDP_ONLY)
00155   /*
00156    * Handle flushed end of strings EE 02.02.28
00157    */
00158   if (s->tcp.ip_type == TCP_PROTO)
00159   {
00160     if ((s->tcp.locflags & LF_GOT_PUSH) && !cr_p)
00161     {
00162       cr_p = data + bmax;
00163       s->tcp.locflags &= ~LF_GOT_PUSH;
00164     }
00165
00166     /* Return if we did not find '\r' or '\n' yet, but still had room,
00167      * *and* the connection can get more data!
00168      */
00169     if (!cr_p && !nl_p &&
00170         (bmax > s->tcp.rx_datalen) &&
00171         ((UINT)s->tcp.rx_datalen < s->tcp.max_rx_data) &&
00172         (s->tcp.state != tcp_StateLASTACK) &&
00173         (s->tcp.state != tcp_StateCLOSED))
00174     {
00175       *data = '\0';
00176       return (0);
00177     }
00178   }
00179 #endif
00180
00181   /* If we did find a terminator, then stop there.
00182    */
00183   if (cr_p || nl_p)
00184   {
00185     /* Find the length of the first line of data in 'data'.
00186      */
00187     len = (int) (nl_p == NULL ? (char*)cr_p - (char*)data :
00188                  cr_p == NULL ? (char*)nl_p - (char*)data :
00189                  nl_p < cr_p  ? (char*)nl_p - (char*)data :
00190                                 (char*)cr_p - (char*)data);
00191
00192     /* We found a terminator character ...
00193      */
00194     bmax = len + 1;
00195
00196     /* If '\r' at end of data, might get a '\0' or '\n' in next packet
00197      */
00198     if (cr_p && s->tcp.rx_datalen == bmax)
00199        s->tcp.sockmode |= SOCK_MODE_SAWCR;
00200
00201     /* ... and it could have been "\r\0" or "\r\n".
00202      */
00203     eol = s->tcp.rx_data [bmax];
00204     if ((s->tcp.rx_datalen > bmax) &&
00205         (eol == '\0' || (cr_p && eol == '\n')))
00206        bmax++;
00207   }
00208
00209   /* Remove the first line from the buffer.
00210    */
00211   s->tcp.rx_datalen -= bmax;
00212   if (frag || s->tcp.rx_datalen > 0)
00213      memmove (s->tcp.rx_data, s->tcp.rx_data + bmax, frag + s->tcp.rx_datalen);
00214
00215 #if !defined(USE_UDP_ONLY)
00216   /*
00217    * Update window if less than MSS/2 free in receive buffer
00218    */
00219   if (s->tcp.ip_type == TCP_PROTO &&
00220       s->tcp.state != tcp_StateCLOSED &&
00221       (s->tcp.max_rx_data - s->tcp.rx_datalen) < s->tcp.max_seg/2)
00222     TCP_SENDSOON (&s->tcp);
00223 #endif
00224
00225   return (len);
00226 }
00227
00228 /*
00229  * Return a single character.
00230  * Returns EOF on fail (no data or connection closed).
00231  */
00232 int sock_getc (sock_type *s)
00233 {
00234   BYTE ch = 0;
00235   return (sock_read (s, &ch, 1) < 1 ? EOF : ch);
00236 }
00237
00246 WORD sock_dataready (sock_type *s)
00247 {
00248   char *p;
00249   int   len = s->tcp.rx_datalen;
00250
00251 #if defined(USE_BSD_API)
00252   if (s->raw.ip_type == IP4_TYPE)
00253      return (0);   /* not supported yet */
00254 #endif
00255
00256   if (len && !(s->tcp.sockmode & SOCK_MODE_BINARY))  /* ASCII mode */
00257   {
00258     p = (char*)s->tcp.rx_data;
00259
00260     if (s->tcp.sockmode & SOCK_MODE_SAWCR)  /* !! S. Lawson */
00261     {
00262       s->tcp.sockmode &= ~SOCK_MODE_SAWCR;
00263       if (*p == '\n' || *p == '\0')
00264       {
00265         s->tcp.rx_datalen = --len;
00266         memmove (p, p+1, s->tcp.rx_datalen);
00267         if (!len)
00268            return (0);
00269       }
00270     }
00271
00272     if ((UINT)len == s->tcp.max_rx_data)
00273        return (len);
00274
00275     if (s->tcp.ip_type == TCP_PROTO)         /* GV 99.12.02 */
00276     {
00277       if (s->tcp.state == tcp_StateLASTACK)  /* EE 99.07.02 */
00278          return (len);
00279
00280       /* S. Lawson - happens if final ACK arrives before app reads data
00281        */
00282       if (s->tcp.state == tcp_StateCLOSED)
00283          return (len);
00284     }
00285
00286     /* check for terminating `\r' and/or `\n'
00287      */
00288     if (memchr(p, '\r', len))
00289        return (len);
00290     if (memchr(p, '\n', len))              /* EE added 99/04/30 */
00291        return (len);
00292     return (0);
00293   }
00294   return (len);
00295 }
00296
00297 #ifdef NOT_YET
00298
00301 int sock_putcw (sock_type *s, wchar_t ch)
00302 {
00303 }
00304
00308 int sock_putsw (sock_type *s, const wchar_t *data)
00309 {
00310 }
00311
00315 int sock_getsw (sock_type *s, wchar_t *data, int n)
00316 {
00317 }
00318
00322 wchar_t sock_getcw (sock_type *s)
00323 {
00324 }
00325 #endif
00326
Generated on Wed Jan 25 15:42:39 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/SOCK_PRN.C Source File

SRC/SOCK_PRN.C

Go to the documentation of this file.
00001
00004 #include <stdio.h>
00005 #include <stdarg.h>
00006 #include <string.h>
00007
00008 #include "copyrigh.h"
00009 #include "wattcp.h"
00010 #include "strings.h"
00011 #include "language.h"
00012 #include "pcconfig.h"
00013 #include "pctcp.h"
00014
00015 int MS_CDECL sock_printf (sock_type *s, const char *fmt, ...)
00016 {
00017   char    buf [tcp_MaxBufSize];
00018   int     len;
00019   va_list args;
00020
00021   va_start (args, fmt);
00022
00023 #if defined(VSNPRINTF)
00024   len = VSNPRINTF (buf, sizeof(buf)-1, fmt, args);
00025
00026   /* Some versions of snprintf return -1 if they'd truncate
00027    * the output. Others return <buf_size> or greater.
00028    */
00029   if (len < 0 || len >= SIZEOF(buf)-1)
00030   {
00031     outsnl (_LANG("ERROR: sock_printf() overrun"));
00032     len = sizeof(buf)-1;
00033     buf [len] = '\0';
00034   }
00035 #else
00036   len = vsprintf (buf, fmt, args);
00037   if (len > SIZEOF(buf))
00038   {
00039     outsnl (_LANG("ERROR: sock_printf() overrun"));
00040     return (0);
00041   }
00042 #endif
00043
00044   sock_puts (s, (const BYTE*)buf);
00045
00046   va_end (args);
00047   return (len);
00048 }
00049
Generated on Wed Jan 25 15:42:39 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/SOCK_SCN.C Source File

SRC/SOCK_SCN.C

Go to the documentation of this file.
00001
00005 #include <stdio.h>
00006 #include <stdarg.h>
00007 #include <string.h>
00008
00009 #include "copyrigh.h"
00010 #include "wattcp.h"
00011 #include "misc.h"
00012 #include "pctcp.h"
00013
00014 /*
00015  * MSC/DMC/DJGPP 2.01 doesn't have vsscanf().
00016  * On Windows there's nothing to be done :-(
00017  */
00018 #if defined(WIN32) && !defined(__MINGW32__)
00019   static int vsscanf (const char *buf, const char *fmt, va_list arglist)
00020   {
00021     ARGSUSED (buf);
00022     ARGSUSED (fmt);
00023     ARGSUSED (arglist);
00024     return (0);
00025   }
00026 #elif defined(__DJGPP__) && (DJGPP_MINOR < 2)
00027   static int vsscanf (const char *buf, const char *fmt, va_list arglist)
00028   {
00029     FILE *fil = stdin;
00030     fil->_ptr = (char*) buf;
00031     return _doscan (fil, fmt, arglist);
00032   }
00033 #elif defined(_MSC_VER) || defined(__DMC__)
00034   static int vsscanf (const char *buf, const char *fmt, va_list arglist)
00035   {
00036     extern _input (FILE*, const char*, va_list);
00037     FILE *fil = stdin;
00038     fil->_ptr = (char*) buf;
00039     return _input (fil, fmt, arglist);
00040   }
00041 #endif
00042
00043 /*
00044  * sock_scanf - Read a line and return number of fields matched.
00045  *
00046  * BIG WARNING: Don't use this for packetised protocols like
00047  *              SSH. Only suitable for ASCII orientented protocols
00048  *              like POP3/SMTP/NNTP etc.
00049  *
00050  * NOTE: Don't use {\r\n} in 'fmt' (it's stripped in sock_gets).
00051  */
00052 int MS_CDECL sock_scanf (sock_type *s, const char *fmt, ...)
00053 {
00054   char buf [tcp_MaxBufSize];
00055   int  fields = 0;
00056   int  status, len;
00057
00058   while ((status = sock_dataready(s)) == 0)
00059   {
00060     if (status == -1)
00061        return (-1);
00062
00063     len = sock_gets (s, (BYTE*)buf, sizeof(buf));
00064     if (len > 0)
00065     {
00066       va_list args;
00067       va_start (args, fmt);
00068       fields = vsscanf (buf, fmt, args);
00069       va_end (args);
00070       break;
00071     }
00072   }
00073   return (fields);
00074 }
00075
Generated on Wed Jan 25 15:42:39 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/SOCK_SEL.C Source File

SRC/SOCK_SEL.C

Go to the documentation of this file.
00001
00004 #include <stdio.h>
00005
00006 #include "copyrigh.h"
00007 #include "wattcp.h"
00008 #include "pcbuf.h"
00009 #include "pctcp.h"
00010
00011 /*
00012  * sock_sselect - returns one of several constants indicating
00013  *                SOCKESTABLISHED - tcp connection has been established
00014  *                SOCKDATAREAY    - tcp/udp data ready for reading
00015  *                SOCKCLOSED      - socket has been closed
00016  */
00017 int sock_sselect (const sock_type *s, int waitstate)
00018 {
00019   /* are we connected ?
00020    */
00021   if (waitstate == SOCKDATAREADY && s->tcp.rx_datalen > 0)
00022      return (SOCKDATAREADY);
00023
00024   if (s->tcp.ip_type == 0)
00025      return (SOCKCLOSED);
00026
00027   if (waitstate == SOCKESTABLISHED)
00028   {
00029     if (s->tcp.ip_type == UDP_PROTO      ||
00030         s->tcp.state   == tcp_StateESTAB ||
00031         s->tcp.state   == tcp_StateESTCL ||
00032         s->tcp.state   == tcp_StateCLOSWT)
00033        return (SOCKESTABLISHED);
00034   }
00035   return (0);
00036 }
00037
00038 /*
00039  * Returns 'simplified' enum telling what state the tcp socket is currently
00040  * in, GvB 2002-09
00041  */
00042 enum TCP_SIMPLE_STATE tcp_simple_state (const _tcp_Socket *s)
00043 {
00044   if (s->ip_type != TCP_PROTO ||
00045       s->state == tcp_StateCLOSED)
00046      return (TCP_CLOSED);
00047
00048   if (s->state == tcp_StateLISTEN)
00049      return (TCP_LISTENING);
00050
00051   if (s->state < tcp_StateESTAB)
00052      return (TCP_OPENING);
00053
00054   if (s->state == tcp_StateESTAB)
00055      return (TCP_OPEN);
00056
00057   return (TCP_CLOSING);
00058 }
00059
Generated on Wed Jan 25 15:42:39 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/SOCKET.C Source File

SRC/SOCKET.C

Go to the documentation of this file.
00001
00005 /*  BSD sockets functionality for Waterloo TCP/IP.
00006  *
00007  *  Copyright (c) 1997-2002 Gisle Vanem <giva@bgnett.no>
00008  *
00009  *  Redistribution and use in source and binary forms, with or without
00010  *  modification, are permitted provided that the following conditions
00011  *  are met:
00012  *  1. Redistributions of source code must retain the above copyright
00013  *     notice, this list of conditions and the following disclaimer.
00014  *  2. Redistributions in binary form must reproduce the above copyright
00015  *     notice, this list of conditions and the following disclaimer in the
00016  *     documentation and/or other materials provided with the distribution.
00017  *  3. All advertising materials mentioning features or use of this software
00018  *     must display the following acknowledgement:
00019  *       This product includes software developed by Gisle Vanem
00020  *       Bergen, Norway.
00021  *
00022  *  THIS SOFTWARE IS PROVIDED BY ME (Gisle Vanem) AND CONTRIBUTORS ``AS IS''
00023  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00024  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00025  *  ARE DISCLAIMED.  IN NO EVENT SHALL I OR CONTRIBUTORS BE LIABLE FOR ANY
00026  *  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00027  *  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00028  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00029  *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00030  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00031  *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00032  *
00033  *  Version
00034  *
00035  *  0.5 : Dec 18, 1997 : G. Vanem - created
00036  *  0.6 : Aug 06, 2002 : G. Vanem - added AF_INET6 support
00037  */
00038
00039 #include "socket.h"
00040 #include "pcdbug.h"
00041 #include "pcicmp6.h"
00042 #include "udp_dom.h"
00043
00044 #if defined(USE_BSD_API)
00045
00046 #ifdef __DJGPP__
00047   #include <sys/resource.h>
00048   #include <sys/fsext.h>
00049   #include <unistd.h>
00050   #if (DJGPP_MINOR >= 4)
00051   #include <libc/fd_props.h>
00052   #endif
00053
00054   /* in fsext.c */
00055   extern int _fsext_demux (__FSEXT_Fnumber func, int *rv, va_list _args);
00056 #endif
00057
00058 static int     sk_block = 0;          /* sock_daemon() semaphore */
00059 static int     sk_last  = SK_FIRST+1; /* highest socket number + 1 */
00060 static Socket *sk_list  = NULL;
00061 static DWORD   raw_seq  = 0;
00062
00063 static int (*tcp_syn_hook) (_tcp_Socket **tcp)    = NULL;
00064 static int (*ip4_raw_hook) (const in_Header *ip)  = NULL;
00065
00066 #if defined(USE_IPV6)
00067 static int (*ip6_raw_hook) (const in6_Header *ip) = NULL;
00068 #endif
00069
00073 #define SOCK_HASH_SIZE 64  /* must be 2^n */
00074
00075 static Socket *sk_hashes [SOCK_HASH_SIZE];
00076
00077 #if 0
00078   static __inline Socket *sock_hash_get (int fd)
00079   {
00080     return sk_hashes [fd & (SOCK_HASH_SIZE-1)];
00081   }
00082   static __inline void sock_hash_add (int fd, Socket *sock)
00083   {
00084     sk_hashes [fd & (SOCK_HASH_SIZE-1)] = sock;
00085   }
00086 #else
00087   #define sock_hash_get(fd)       sk_list
00088   #define sock_hash_add(fd,sock)  ((void)0)
00089 #endif
00090
00094 void *_sock_calloc (size_t size, const char *file, unsigned line)
00095 {
00096   void *ptr;
00097
00098 #if defined(WATCOM386) && 0  /* find DOS4GW bug! */
00099   int rc = _heapset (0xCC);
00100
00101   if (rc != _HEAPOK && rc != _HEAPEMPTY)
00102      SOCK_FATAL (("%s (%u) Fatal: heap corrupt\n", file, line));
00103 #endif
00104
00105 #if defined(USE_FORTIFY)
00106   ptr = Fortify_calloc (size, 1, file, line);
00107 #elif defined(_CRTDBG_MAP_ALLOC)  /* MSVC _DEBUG */
00108   ptr = _calloc_dbg (size, 1, _NORMAL_BLOCK, file, (int)line);
00109 #else
00110   ptr = calloc (size, 1);
00111 #endif
00112
00113   if (!ptr)
00114   {
00115 #if defined(WATCOM386) && 0  /* find DOS4GW bug! */
00116     struct _heapinfo hi;
00117     _heapwalk (&hi);
00118 #endif
00119     SOCK_FATAL (("%s (%u) Fatal: Allocation failed\n", file, line));
00120   }
00121
00122   ARGSUSED (file);
00123   ARGSUSED (line);
00124   return (ptr);
00125 }
00126
00127
00143 static fd_set inuse [NUM_SOCK_FDSETS];  /* MAX_SOCKETS/8 = 625 bytes */
00144
00145 static int sock_alloc_fd (char **err)
00146 {
00147   static char errbuf[100];
00148   int    fd;
00149
00150   *err = NULL;
00151   errbuf[0] = '\0';
00152
00153 #if defined(__DJGPP__) && defined(USE_FSEXT)
00154   fd = __FSEXT_alloc_fd (_fsext_demux);
00155
00156   if (fd < 0)
00157   {
00158     sprintf (errbuf, "FSEXT_alloc_fd() failed; %s", strerror(errno));
00159     *err = errbuf;
00160     return (-1);
00161   }
00162
00163   if (FD_ISSET(fd,&inuse[0]))
00164   {
00165     sprintf (errbuf, "Reusing existing socket %d", fd);
00166     *err = errbuf;
00167     return (-1);
00168   }
00169
00170 #if (DJGPP_MINOR >= 4) && 0
00171   {
00172     char dev_name[20];
00173
00174     snprintf (dev_name, sizeof(dev_name), "/dev/socket/%d", fd);
00175     __set_fd_properties (fd, dev_name, 0);     /* last arg? */
00176     __set_fd_flags (fd, FILE_DESC_TEMPORARY);  /* auto close socket */
00177   }
00178 #endif
00179
00180 #else
00181   for (fd = SK_FIRST; fd < sk_last; fd++)
00182       if (!FD_ISSET(fd,&inuse[0]) &&  /* not marked as in-use */
00183           !_socklist_find(fd))        /* don't use a dying socket */
00184          break;
00185
00186 #endif /* __DJGPP__ && USE_FSEXT */
00187
00188   if (fd < MAX_SOCKETS)
00189   {
00190     if (fd == sk_last)
00191        sk_last++;
00192
00193     FD_SET (fd, &inuse[0]);
00194     return (fd);
00195   }
00196
00197   /* No vacant bits in 'inuse' array. djgpp (and DOS) could theoretically
00198    * return a file-handle > 'MAX_SOCKETS-1'.
00199    */
00200   *err = "No more sockets";
00201   return (-1);
00202 }
00203
00213 BOOL _sock_dos_fd (int s)
00214 {
00215   if (s >= fileno(stdin) && s <= fileno(stderr)) /* 0..2 (redirected) */
00216      return (TRUE);
00217
00218   if (s > fileno(stderr) && isatty(s))
00219      return (TRUE);
00220
00221 #if defined(WIN32)
00222   {
00223     HANDLE hnd = (HANDLE) _get_osfhandle (s);
00224     if (hnd != INVALID_HANDLE_VALUE)
00225     {
00226       CloseHandle (hnd);
00227       return (TRUE);
00228     }
00229   }
00230 #endif
00231
00232   return (FALSE);
00233 }
00234
00243 int _sock_set_rcv_buf (sock_type *s, size_t len)
00244 {
00245   len = min (len+8,USHRT_MAX);  /* add room for head/tail markers */
00246   return sock_setbuf (s, (BYTE*)malloc(len), len);
00247 }
00248
00252 void _sock_free_rcv_buf (sock_type *s)
00253 {
00254   if (s->tcp.rx_data &&   /* if xx_open() called */
00255       s->tcp.rx_data != &s->tcp.rx_buf[0])
00256   {
00257     *(DWORD*)(s->tcp.rx_data-4) = 0;  /* clear marker */
00258     free (s->tcp.rx_data-4);
00259     s->tcp.rx_data    = &s->tcp.rx_buf[0];
00260     s->tcp.rx_datalen = 0;
00261   }
00262 }
00263
00269 static __inline Socket *sk_list_del (int s)
00270 {
00271   Socket *sock, *last, *next;
00272
00273   for (sock = last = sock_hash_get(s); sock; last = sock, sock = next)
00274   {
00275     next = sock->next;
00276     if (sock->fd != s)
00277        continue;
00278
00279     if (sock == sk_list)
00280          sk_list    = next;
00281     else last->next = next;
00282     sock_hash_add (s, NULL);
00283     free (sock);
00284     return (next);
00285   }
00286   return (NULL);
00287 }
00288
00293 const sock_type *__get_sock_from_s (int s, int proto)
00294 {
00295   Socket *sock = _socklist_find (s);
00296
00297   if (!sock)
00298      return (NULL);
00299
00300   if (proto == UDP_PROTO)
00301      return (sock_type*) sock->udp_sock;
00302
00303   if (proto == TCP_PROTO)
00304      return (sock_type*) sock->tcp_sock;
00305
00306   if (proto == IPPROTO_IP)
00307      return (sock_type*) sock->raw_sock;
00308
00309   return (NULL);
00310 }
00311
00316 static __inline BOOL other_tcp_listeners (const Socket *_this)
00317 {
00318   const Socket *sock;
00319
00320   for (sock = sk_list; sock; sock = sock->next)
00321       if (sock->so_type == SOCK_STREAM       &&
00322           (sock->so_options & SO_ACCEPTCONN) &&
00323           sock != _this)
00324         return (TRUE);
00325   return (FALSE);
00326 }
00327
00328 void _sock_set_syn_hook (int (*func)(_tcp_Socket**))
00329 {
00330   tcp_syn_hook = func;
00331 }
00332
00337 static __inline BOOL other_raw_socks (const Socket *_this)
00338 {
00339   const Socket *sock;
00340
00341   for (sock = sk_list; sock; sock = sock->next)
00342       if (sock->so_type == SOCK_RAW && sock != _this)
00343          return (TRUE);
00344   return (FALSE);
00345 }
00346
00351 static BOOL mcast_set  = FALSE;
00352 static BOOL promis_set = FALSE;
00353
00354 BOOL _sock_set_normal_rx_mode (const Socket *_this)
00355 {
00356   const Socket *sock;
00357   BOOL  rc = TRUE;
00358
00359 #if defined(USE_MULTICAST)
00360   if (num_multicast_active() > 0)
00361      return (rc);
00362 #endif
00363
00364   for (sock = sk_list; sock; sock = sock->next)
00365       if (sock != _this &&
00366           (sock->so_family == AF_INET6 || sock->so_type == SOCK_PACKET))
00367          break;
00368
00369   if (!sock)
00370   {
00371     rc = pkt_set_rcv_mode (RXMODE_BROADCAST);
00372     if (!rc)
00373        SOCK_DEBUGF (("\n  setting normal rx-mode failed; %s",
00374                      pkt_strerror(_pkt_errno)));
00375     _pkt_forced_rxmode = RXMODE_BROADCAST;
00376     mcast_set = FALSE;
00377   }
00378   return (rc);
00379 }
00380
00381 BOOL _sock_set_mcast_rx_mode (void)
00382 {
00383   BOOL rc = TRUE;
00384
00385   if (!mcast_set)
00386 #if defined(USE_IPV6)
00387      rc = _ip6_pkt_init();
00388 #else
00389      rc = pkt_set_rcv_mode (RXMODE_MULTICAST2);
00390 #endif
00391
00392   mcast_set = TRUE;
00393   return (rc);
00394 }
00395
00396 BOOL _sock_set_promisc_rx_mode (void)
00397 {
00398   BOOL rc = TRUE;
00399
00400   if (!promis_set)
00401      rc = pkt_set_rcv_mode (RXMODE_PROMISCOUS);
00402   promis_set = TRUE;
00403   return (rc);
00404 }
00405
00409 static void sock_raw_del (Socket *sock)
00410 {
00411 #if defined(USE_IPV6)
00412   if (sock->so_family == AF_INET6)
00413   {
00414     _raw6_Socket *raw, *next;
00415
00416     if (!other_raw_socks(sock))
00417        ip6_raw_hook = NULL;
00418
00419     for (raw = sock->raw6_sock; raw; raw = next)
00420     {
00421       raw->ip_type = 0;
00422       next = raw->next;
00423       free (raw);
00424     }
00425     sock->raw6_sock = NULL;
00426   }
00427   else
00428 #endif
00429   {
00430     _raw_Socket *raw, *next;
00431
00432     if (!other_raw_socks(sock))
00433        ip4_raw_hook = NULL;
00434
00435     for (raw = sock->raw_sock; raw; raw = next)
00436     {
00437       raw->ip_type = 0;
00438       next = raw->next;
00439       free (raw);
00440     }
00441     sock->raw_sock = NULL;
00442   }
00443 }
00444
00448 static BOOL sock_packet_add (Socket *sock)
00449 {
00450   sock_packet_pool *p = SOCK_CALLOC (sizeof(*p));
00451
00452   sock->packet_pool = p;
00453   if (!sock->packet_pool)
00454      return (FALSE);
00455   pktq_init (&p->queue, sizeof(p->buf[0]), DIM(p->buf), (char*)p->buf);
00456   return (TRUE);
00457 }
00458
00459 static void sock_packet_del (Socket *sock)
00460 {
00461   if (sock->packet_pool)
00462   {
00463  /* SOCK_DEBUGF ((", num-drops %lu", sock->packet_pool->queue.num_drop); */
00464     free (sock->packet_pool);
00465   }
00466   sock->packet_pool = NULL;
00467   _eth_recv_peek = sock->old_eth_peek;
00468 }
00469
00470 /*
00471  * Receiver for SOCK_PACKET sockets
00472  */
00473 static int sock_packet_peek (const union link_Packet *pkt)
00474 {
00475   Socket *sock, *last = NULL;
00476
00477   for (sock = sk_list; sock; sock = sock->next)
00478       if (sock->so_type == SOCK_PACKET && sock->packet_pool)
00479       {
00480         struct pkt_ringbuf     *q = &sock->packet_pool->queue;
00481         struct sock_packet_buf *rx;
00482         size_t len;
00483
00484 #if defined(USE_DEBUG)
00485         if (!pktq_check (q))
00486         {
00487           TCP_CONSOLE_MSG (0, ("%s(%u): SOCK_PACKET queue munged, "
00488                            "fd %d\n", __FILE__, __LINE__, sock->fd));
00489           pktq_clear (q);
00490           continue;
00491         }
00492 #endif
00493         if (pktq_in_index(q) == q->out_index)   /* no room */
00494         {
00495           q->num_drop++;
00496           TCP_CONSOLE_MSG (0, ("SOCK_PACKET drops %lu\n", q->num_drop));
00497           continue;
00498         }
00499
00500         rx = (struct sock_packet_buf*) pktq_in_buf (q);
00501
00502         if (_eth_last.rx.size > 0)   /* Only for Win32 or USE_FAST_PKT */
00503              len = _eth_last.rx.size;
00504         else len = sizeof(rx->rx_buf) - 4;
00505
00506         memcpy (rx->rx_buf, pkt, len);
00507         rx->rx_len = len;
00508         pktq_inc_in (q);
00509         last = sock;
00510       }
00511
00512   if (last && last->old_eth_peek && last->old_eth_peek != _eth_recv_peek)
00513      return (*last->old_eth_peek) ((void*)pkt);
00514   return (1);
00515 }
00516
00520 static char get_pkt_type_eth (const eth_Header *eth)
00521 {
00522   if (!memcmp(&_eth_addr,&eth->destination,_eth_mac_len))
00523      return (PACKET_HOST);
00524   if (!memcmp(&eth->destination,&_eth_brdcast,_eth_mac_len))
00525      return (PACKET_BROADCAST);
00526   if ((eth->destination[0] & 1) == 1)
00527      return (PACKET_MULTICAST);
00528   return (PACKET_OTHERHOST);     /* To someone else */
00529 }
00530
00531 static char get_pkt_type_fddi (const fddi_Header *fddi)
00532 {
00533   if (!memcmp(&_eth_addr,&fddi->destination,_eth_mac_len))
00534      return (PACKET_HOST);
00535   if (!memcmp(&fddi->destination,&_eth_brdcast,_eth_mac_len))
00536      return (PACKET_BROADCAST);
00537   if ((fddi->destination[0] & 1) == 1)
00538      return (PACKET_MULTICAST);
00539   return (PACKET_OTHERHOST);     /* To someone else */
00540 }
00541
00542 static char get_pkt_type_tok (const tok_Header *tok)
00543 {
00544   if (!memcmp(&_eth_addr,&tok->destination,_eth_mac_len))
00545      return (PACKET_HOST);
00546   if (!memcmp(&tok->destination,&_eth_brdcast,_eth_mac_len))
00547      return (PACKET_BROADCAST);
00548   if ((tok->destination[0] & 1) == 1)
00549      return (PACKET_MULTICAST);
00550   return (PACKET_OTHERHOST);     /* To someone else */
00551 }
00552
00553 static char get_pkt_type_arc (const arcnet_Header *arc)
00554 {
00555   ARGSUSED (arc);
00556   return (PACKET_HOST);
00557 }
00558
00559 static char get_pkt_type (const union link_Packet *pkt)
00560 {
00561  switch (_pktdevclass)
00562  {
00563    case PDCLASS_TOKEN:
00564         return get_pkt_type_tok (&pkt->tok.head);
00565    case PDCLASS_FDDI:
00566         return get_pkt_type_fddi (&pkt->fddi.head);
00567    case PDCLASS_ARCNET:
00568         return get_pkt_type_arc (&pkt->arc.head);
00569    case PDCLASS_ETHER:
00570         return get_pkt_type_eth (&pkt->eth.head);
00571    default:
00572         return (PACKET_HOST);  /* to us (assuming PPP/SLIP) */
00573   }
00574 }
00575
00580 unsigned sock_packet_receive (Socket *sock, void *buf, unsigned len,
00581                               struct sockaddr *from, int *fromlen)
00582 {
00583   struct pkt_ringbuf     *q;
00584   struct sock_packet_buf *rx;
00585
00586   if (!sock->packet_pool)
00587      return (0);
00588
00589   q = &sock->packet_pool->queue;
00590   if (q->in_index == q->out_index)  /* no elements */
00591      return (0);
00592
00593   rx  = (struct sock_packet_buf*) pktq_out_buf (q);
00594   len = min (len, rx->rx_len);
00595   memcpy (buf, rx->rx_buf, len);
00596
00597   if (from && fromlen)
00598   {
00599     struct sockaddr_ll *sa = (struct sockaddr_ll*) from;
00600     BYTE   hw_type, hw_len;
00601
00602     _eth_get_hwtype (&hw_type, &hw_len);
00603     memset (from, 0, sizeof(*sa));
00604     sa->sll_halen    = hw_len;
00605     sa->sll_hatype   = hw_type;
00606     sa->sll_protocol = *(WORD*) ((char*)buf+_pkt_ip_ofs-2);
00607     sa->sll_ifindex  = 1;
00608     sa->sll_family   = AF_PACKET;
00609     sa->sll_pkttype  = get_pkt_type ((const union link_Packet*)buf);
00610     *fromlen = sizeof (*sa);
00611   }
00612   pktq_inc_out (q);
00613   return (len);
00614 }
00615
00616 /*
00617  * Needed by select_s().
00618  */
00619 unsigned sock_packet_rbused (Socket *sock)
00620 {
00621   if (!sock->packet_pool)
00622      return (0);
00623   return pktq_queued (&sock->packet_pool->queue);
00624 }
00625
00626 unsigned sock_packet_transmit (Socket *socket, const void *buf, unsigned len,
00627                                const struct sockaddr *to, int tolen)
00628 {
00629   const struct sockaddr_ll *sa = (const struct sockaddr_ll*) to;
00630   BYTE *tx;
00631   int   rc;
00632
00633   if (len <= _pkt_ip_ofs)
00634   {
00635     SOCK_ERRNO (EINVAL);
00636     return (-1);
00637   }
00638   tx = _eth_formatpacket (sa ? &sa->sll_addr : NULL,
00639                           sa ? sa->sll_protocol : 0);
00640   tx -= _pkt_ip_ofs;
00641   len = min (len, sizeof(union link_Packet));
00642   memcpy (tx, buf, len);
00643   rc = _eth_send (len - _pkt_ip_ofs, NULL, __FILE__, __LINE__);
00644   if (rc <= 0)
00645      return (-1);
00646
00647   ARGSUSED (socket);
00648   ARGSUSED (tolen);   /* already checked by caller */
00649   return (rc + _pkt_ip_ofs);
00650 }
00651
00652
00653 /*
00654  * Clear 'fd' from the inuse array. For djgpp only:
00655  *  Free the socket from File-System Extension system.
00656  *  Free the duplicated handle from DOS's System File Table.
00657  */
00658 static void sock_close_fd (int fd)
00659 {
00660   if (fd >= SK_FIRST && fd < MAX_SOCKETS)
00661   {
00662     FD_CLR (fd, &inuse[0]);
00663     if (fd == sk_last-1)
00664        sk_last--;
00665   }
00666
00667 #if defined(__DJGPP__) && defined(USE_FSEXT)
00668   __FSEXT_set_function (fd, NULL);
00669   if (fd >= SK_FIRST && _close(fd) < 0)
00670      SOCK_DEBUGF (("  _close() failed; %s", strerror(errno)));
00671 #endif
00672 }
00673
00680 Socket *_sock_del_fd (int fd, const char *file, unsigned line)
00681 {
00682   Socket    *sock, *next = NULL;
00683   sock_type *sk;
00684
00685   SOCK_DEBUGF (("\n  _sock_del_fd:%d", fd));
00686
00687   if (fd < SK_FIRST || fd >= sk_last || !FD_ISSET(fd,&inuse[0]))
00688   {
00689     SOCK_FATAL (("%s (%u) Fatal: socket %d not inuse\n", file, line, fd));
00690     return (NULL);
00691   }
00692
00693   sock = _socklist_find (fd);
00694   if (!sock)
00695   {
00696     SOCK_FATAL (("%s (%u) Fatal: socket %d not in list\n", file, line, fd));
00697     goto not_inuse;
00698   }
00699
00700   if (sock->cookie != SAFETY_TCP)  /* Aaarg! marker destroyed */
00701   {
00702     SOCK_FATAL (("%s (%u) fatal: socket %d (%p) overwritten\n",
00703                  file, line, fd, sock));
00704     goto not_inuse;
00705   }
00706
00707   switch (sock->so_type)
00708   {
00709     case SOCK_STREAM:
00710          sk = (sock_type*) sock->tcp_sock;
00711          if (sk)
00712          {
00713            reuse_localport (sk->tcp.myport); /* clear 'lport_inuse' bit now */
00714            TCP_ABORT (&sk->tcp);
00715            _sock_free_rcv_buf (sk);
00716          }
00717          DO_FREE (sock->tcp_sock);
00718          if (!other_tcp_listeners(sock))
00719             _sock_set_syn_hook (NULL);
00720          break;
00721
00722     case SOCK_DGRAM:
00723          sk = (sock_type*) sock->udp_sock;
00724          if (sk)
00725          {
00726            reuse_localport (sk->udp.myport);  /* redundant? */
00727            sock_abort (sk);
00728            _sock_free_rcv_buf (sk);
00729          }
00730          DO_FREE (sock->udp_sock);
00731          break;
00732
00733     case SOCK_RAW:
00734          sock_raw_del (sock);
00735          break;
00736
00737     case SOCK_PACKET:
00738          sock_packet_del (sock);
00739          break;
00740
00741     default:
00742          SOCK_DEBUGF (("\n  _sock_del_fd:%d: unknown type %d",
00743                        fd, sock->so_type));
00744          break;
00745   }
00746
00747   DO_FREE (sock->local_addr);
00748   DO_FREE (sock->remote_addr);
00749   DO_FREE (sock->ip_opt);
00750   DO_FREE (sock->bcast_pool);
00751   DO_FREE (sock->packet_pool);
00752
00753   /* Check if any remaining IPv6/PACKET sockets.
00754    */
00755   if ((sock->so_family == AF_INET6 || sock->so_type == SOCK_PACKET) &&
00756       _pkt_rxmode > RXMODE_BROADCAST && /* current Rx-mode not broadcast */
00757       _pkt_forced_rxmode < 0)           /* we didn't force a specific mode */
00758      _sock_set_normal_rx_mode (sock);   /* Then set normal Rx-mode */
00759
00760   next = sk_list_del (fd);  /* delete socket from linked list */
00761
00762   if (sk_list == NULL)      /* no more sockets, hook not needed */
00763      _bsd_socket_hook = NULL;
00764
00765 not_inuse:
00766   sock_close_fd (fd);
00767   ARGSUSED (file);
00768   ARGSUSED (line);
00769   return (next);
00770 }
00771
00772 #ifdef NOT_USED
00773
00777 static int sock_find_fd (const Socket *socket)
00778 {
00779   const Socket *sock;
00780
00781   for (sock = sock_hash_get(socket->fd); sock; sock = sock->next)
00782       if (sock == socket)
00783          return (sock->fd);
00784   return (-1);
00785 }
00786
00791 static Socket *sock_find_udp (const _udp_Socket *udp)
00792 {
00793   Socket *sock;
00794
00795   for (sock = sk_list; sock; sock = sock->next)
00796       if (sock->udp_sock == udp)
00797          return (sock);
00798   return (NULL);
00799 }
00800 #endif  /* NOT_USED */
00801
00805 static void *sock_find_tcp (const _tcp_Socket *tcp)
00806 {
00807   Socket *sock;
00808
00809   for (sock = sk_list; sock; sock = sock->next)
00810       if (sock->tcp_sock == tcp)
00811          return (void*)sock;
00812   return (NULL);
00813 }
00814
00818 int _sock_chk_sockaddr (Socket *socket, const struct sockaddr *sa, int len)
00819 {
00820   int sa_len = (socket->so_family == AF_INET6) ? sizeof(struct sockaddr_in6) :
00821                                                  sizeof(struct sockaddr_in);
00822   if (!sa || len < sa_len)
00823   {
00824     SOCK_DEBUGF ((", EINVAL"));
00825     SOCK_ERRNO (EINVAL);
00826     return (-1);
00827   }
00828
00829   if (socket->so_type == SOCK_PACKET)
00830   {
00831     SOCK_DEBUGF ((", SOCK_PACKET, EAFNOSUPPORT"));
00832     SOCK_ERRNO (EAFNOSUPPORT);
00833     return (-1);
00834   }
00835
00836   /* Easy way to reconnect a UDP socket.
00837    */
00838   if (sa->sa_family == AF_UNSPEC && socket->so_type == SOCK_DGRAM)
00839   {
00840     socket->so_state &= ~(SS_ISDISCONNECTING | SS_CANTSENDMORE);
00841     socket->udp_sock->rx_datalen = 0;  /* flush recv buf */
00842     if (socket->remote_addr)
00843        free (socket->remote_addr);
00844     socket->remote_addr = NULL;
00845
00846     SOCK_DEBUGF ((", AF_UNSPEC, EAFNOSUPPORT"));
00847     SOCK_ERRNO (EAFNOSUPPORT);
00848     return (-1);
00849   }
00850
00851   if (sa->sa_family != socket->so_family)
00852   {
00853     SOCK_DEBUGF ((", different families"));
00854     SOCK_ERRNO (EAFNOSUPPORT);
00855     return (-1);
00856   }
00857
00858   VERIFY_RW (sa, len);
00859   return (0);
00860 }
00861
00865 static struct _raw_Socket *find_free_raw_sock (Socket *sock)
00866 {
00867   struct _raw_Socket *raw;
00868
00869   if (!sock->raw_sock)
00870      SOCK_FATAL (("find_raw_sock() called for non-raw sock, so_type %d\n",
00871                  sock->so_type));
00872
00873   for (raw = sock->raw_sock; raw; raw = raw->next)
00874       if (!raw->used)
00875          return (raw);
00876   return (NULL);
00877 }
00878
00879 #if defined(USE_IPV6)
00880 static struct _raw6_Socket *find_free_raw6_sock (Socket *sock)
00881 {
00882   struct _raw6_Socket *raw;
00883
00884   if (!sock->raw6_sock)
00885      SOCK_FATAL (("find_raw6_sock() called for non-raw sock, so_type %d\n",
00886                  sock->so_type));
00887
00888   for (raw = sock->raw6_sock; raw; raw = raw->next)
00889       if (!raw->used)
00890          return (raw);
00891   return (NULL);
00892 }
00893 #endif
00894
00904 static int sock_raw4_recv (const in_Header *ip)
00905 {
00906   Socket      *sock;
00907   _raw_Socket *raw;
00908   int          num_enqueued = 0;
00909   size_t       len = ntohs (ip->length);
00910
00911   /* Early drop; jumbo packets won't match any raw-sockets
00912    */
00913   if (len > sizeof(sock->raw_sock->rx_data))
00914      return (0);
00915
00916   /* Should SOCK_RAW allow packets not destined to us *and* not
00917    * broadcast?
00918    */
00919 #if 0
00920   {
00921     DWORD ip_dst = ntohl (ip->destination);
00922
00923     /* Not addressed to us or not (limited) broadcast
00924      */
00925     if (!_ip4_is_local_addr(ip_dst) && !_ip4_is_ip_brdcast(ip))
00926        return (0);
00927   }
00928 #endif
00929
00930   for (sock = sk_list; sock; sock = sock->next)
00931   {
00932     if (sock->so_type != SOCK_RAW)
00933        continue;
00934
00935     if (sock->so_proto == IPPROTO_IP)
00936        goto enqueue;   /* socket matches every IP-protocol, enqueue */
00937
00938     if (ip->proto != sock->so_proto)  /* isn't what we want */
00939        continue;
00940
00941   enqueue:
00942     raw = find_free_raw_sock (sock);
00943     if (!raw)
00944     {
00945 #if 0 /* maybe user didn't bother to read it. Ignore it. */
00946       SOCK_DEBUGF (("\n  socket:%d, dropped raw (IP4), proto %d, id %04X",
00947                     sock->fd, ip->proto, ntohs(ip->identification)));
00948 #endif
00949       continue;
00950     }
00951
00952     /* Copy IP-header to raw_sock.ip
00953      */
00954     memcpy (&raw->ip, ip, sizeof(*ip));
00955
00956     /* Copy any options and rest of IP-packet
00957      */
00958     memcpy (&raw->rx_data[0], ip+1, min(len,sizeof(raw->rx_data)));
00959     raw->used    = TRUE;
00960     raw->seq_num = ++raw_seq;
00961     num_enqueued++;
00962
00963     if (sock->so_options & SO_DEBUG)
00964     {
00965       /*\todo Add SOCK_RAW debug */
00966     }
00967   }
00968   return (num_enqueued);
00969 }
00970
00971 #if defined(USE_IPV6)
00972 static int sock_raw6_recv (const in6_Header *ip)
00973 {
00974   Socket       *sock;
00975   _raw6_Socket *raw;
00976   int           num_enqueued = 0;
00977   int           num_dropped  = 0;
00978   const void   *dest         = &ip->destination[0];
00979   size_t        len          = ntohs (ip->len);
00980
00981   /* Jumbo packets won't match any raw-sockets
00982    */
00983   if (len > sizeof(sock->raw6_sock->rx_data))
00984      return (0);
00985
00986   /* Not addressed to us or not multicast
00987    */
00988   if (memcmp(&in6addr_my_ip,dest,sizeof(in6addr_my_ip)) &&
00989       !IN6_IS_ADDR_MULTICAST(dest))
00990      return (0);
00991
00992   for (sock = sk_list; sock; sock = sock->next)
00993   {
00994     if (ip->next_hdr == IPPROTO_TCP && sock->so_type == SOCK_STREAM)
00995        continue;
00996
00997     if (ip->next_hdr == IPPROTO_UDP && sock->so_type == SOCK_DGRAM)
00998        continue;
00999
01000     if (sock->so_type != SOCK_RAW ||
01001         (ip->next_hdr != sock->so_proto && sock->so_proto != IPPROTO_IP))
01002        continue;
01003
01004     raw = find_free_raw6_sock (sock);
01005     if (!raw)
01006     {
01007       num_dropped++;
01008       SOCK_DEBUGF (("\n  socket:%d, dropped raw (IP6), proto %d",
01009                     sock->fd, ip->next_hdr));
01010     }
01011     else
01012     {
01013       /* Copy IP-header to raw6_sock.ip
01014        */
01015       memcpy (&raw->ip6, ip, sizeof(*ip));
01016
01017       /* Copy rest of IP-packet (no optios)
01018        */
01019       memcpy (&raw->rx_data[0], ip+1, min(len,sizeof(raw->rx_data)));
01020       raw->used    = TRUE;
01021       raw->seq_num = ++raw_seq;
01022       num_enqueued++;
01023
01024       if (sock->so_options & SO_DEBUG)
01025       {
01026         /*\todo Add SOCK_RAW debug */
01027       }
01028     }
01029   }
01030
01031   if (num_dropped > 0)
01032      STAT (ip4stats.ips_idropped++);
01033
01034   return (num_enqueued);
01035 }
01036 #endif  /* USE_IPV6 */
01037
01042 static void do_keepalive (Socket *sock)
01043 {
01044   if (sock->keepalive == 0)
01045   {
01046     if (tcp_keep_idle)
01047        sock->keepalive = set_timeout (1000 * tcp_keep_idle);
01048   }
01049   else if (sock->tcp_sock->locflags & LF_KEEPALIVE)
01050   {
01051     sock->keepalive = 0UL;
01052   }
01053   else if (chk_timeout(sock->keepalive))
01054   {
01055     _tcp_keepalive (sock->tcp_sock);
01056     SOCK_DEBUGF (("\n  sock_keepalive:%d", sock->fd));
01057     sock->keepalive = 0UL;
01058   }
01059 }
01060
01065 static void * MS_CDECL socket_op_demux (enum BSD_SOCKET_OPS op, ...)
01066 {
01067   const _tcp_Socket *tcp;
01068   void   *rc = NULL;
01069   Socket *sock;
01070   va_list args;
01071
01072   va_start (args, op);
01073
01074   switch (op)
01075   {
01076     case BSO_FIND_SOCK:  /* return a 'Socket*' from '_tcp_Socket*' */
01077          tcp = va_arg (args, const _tcp_Socket*);
01078          if (tcp->ip_type == TCP_PROTO)
01079               rc = sock_find_tcp (tcp);
01080          else rc = NULL;
01081          break;
01082
01083     case BSO_RST_CALLBACK:  /* RST received in _tcp_handler() */
01084          tcp  = va_arg (args, const _tcp_Socket*);
01085          sock = sock_find_tcp (tcp);
01086          if (sock)
01087          {
01088            sock->so_error = ECONNRESET;
01089            SOCK_DEBUGF (("\n  TCP-reset:%d", sock->fd));
01090            if (tcp->rx_datalen == 0)
01091            {
01092              sock->so_state |= SS_CONN_REFUSED|SS_CANTSENDMORE|SS_CANTRCVMORE;
01093              sock->close_time  = time (NULL);
01094              sock->linger_time = TCP_LINGERTIME/40;  /* 3 sec */
01095            }
01096          }
01097          else
01098            SOCK_DEBUGF (("\n  TCP-reset for unknown socket??"));
01099          break;
01100
01101     case BSO_SYN_CALLBACK:  /* filtering SYNs in _sock_append() */
01102          if (tcp_syn_hook)
01103               rc = (void*) (*tcp_syn_hook) (va_arg(args,_tcp_Socket**));
01104          else rc = (void*) 1;   /* ret-val doesn't matter */
01105          break;
01106
01107     case BSO_IP4_RAW:
01108          if (ip4_raw_hook)
01109             rc = (void*) (*ip4_raw_hook) (va_arg(args,const in_Header*));
01110          break;
01111
01112     case BSO_IP6_RAW:
01113 #if defined(USE_IPV6)
01114          if (ip6_raw_hook)
01115             rc = (void*) (*ip6_raw_hook) (va_arg(args,const in6_Header*));
01116 #endif
01117          break;
01118
01119     case BSO_DEBUG:       /* \todo trace the in/out state etc. */
01120 #if 0
01121          sk = va_arg (args, const sock_type*);
01122          if (sk->tcp.ip_type == TCP_PROTO)
01123          {
01124            UINT st_in  = va_arg (args, UINT);
01125            UINT st_out = va_arg (args, UINT);
01126            (*_printf) ("TCP: %s -> %s\n", st_in, st_out);
01127          }
01128          socket_debugdump (sk);
01129 #endif
01130          break;
01131
01132     default:
01133          SOCK_FATAL (("%s (%u) Fatal: Unknown op-code %d\n",
01134                      __FILE__, __LINE__, op));
01135          break;
01136   }
01137   va_end (args);
01138   return (rc);
01139 }
01140
01148 static Socket *tcp_sock_daemon (Socket *sock)
01149 {
01150   Socket      *next = sock->next;
01151   _tcp_Socket *tcp  = sock->tcp_sock;
01152   int  s     = sock->fd;
01153   int  state = tcp->state;
01154
01155   if (sock->so_options & SO_KEEPALIVE)
01156      do_keepalive (sock);
01157
01158   if (state == tcp_StateRESOLVE ||
01159       state == tcp_StateSYNSENT)        /* opening active tcp session */
01160   {
01161     sock->so_state |= SS_ISCONNECTING;
01162   }
01163   else if (state == tcp_StateESTAB)        /* established tcp session */
01164   {
01165     sock->so_state |=  SS_ISCONNECTED;
01166     sock->so_state &= ~SS_ISCONNECTING;
01167     sock->so_state &= ~SS_ISDISCONNECTING;
01168   }
01169   else if (state >= tcp_StateTIMEWT)             /* dying tcp session */
01170   {
01171     sock_type *sk = (sock_type*)tcp;
01172     BOOL closing  = (sock->so_state & (SS_ISDISCONNECTING | SS_CANTSENDMORE));
01173
01174     sock->so_state &= ~(SS_ISCONNECTED | SS_ISCONNECTING);
01175     DO_FREE (sock->ip_opt);
01176
01177     if (sock->close_time && (sock->so_state & SS_CANTRCVMORE))
01178     {
01179       /* Flush any remaining Rx data received after shutdown(0) called.
01180        */
01181       sock_fastread (sk, NULL, -1);
01182     }
01183
01184     if (closing && sk->tcp.ip_type == 0) /* fully closed, refused or aborted */
01185     {
01186       BOOL expired = FALSE;
01187
01188       if (!sock_rbused(sk))
01189          _sock_free_rcv_buf (sk);   /* free memory not needed anymore */
01190
01191       if (sock->close_time)         /* close_s() called */
01192          expired = (time(NULL) - sock->close_time >= (time_t)sock->linger_time);
01193
01194       /* If linger-period expired and fully closed, delete the TCB
01195        */
01196       if (expired && state == tcp_StateCLOSED)
01197       {
01198         SOCK_DEBUGF (("\n  tcp_sock_daemon del:%d, lport %d", s, tcp->myport));
01199         next = SOCK_DEL_FD (s);
01200       }
01201     }
01202   }
01203   return (next);
01204 }
01205
01206
01216 static Socket *udp_sock_daemon (Socket *sock)
01217 {
01218   Socket      *next = sock->next;
01219   _udp_Socket *udp  = sock->udp_sock;
01220
01221   if ((sock->so_state & (SS_ISDISCONNECTING | SS_CANTSENDMORE)) &&
01222       (udp->rx_datalen == 0 || udp->ip_type == 0))
01223   {
01224     SOCK_DEBUGF (("\n  udp_sock_daemon del:%d", sock->fd));
01225     next = SOCK_DEL_FD (sock->fd);
01226   }
01227   return (next);
01228 }
01229
01236 static void sock_daemon (void)
01237 {
01238   Socket *sock, *next = NULL;
01239
01240   /* If we're in a critical region (e.g. connect() or select_s()) where
01241    * we don't want our socket-list to change, do this later.
01242    */
01243   if (sk_block)
01244      return;
01245
01246   for (sock = sk_list; sock; sock = next)
01247   {
01248     next = sock->next;
01249
01250     if (!FD_ISSET(sock->fd,&inuse[0]))
01251        continue;
01252
01253     if (sock->local_addr == NULL)  /* not bound to anything yet */
01254        continue;
01255
01256     switch (sock->so_type)
01257     {
01258       case SOCK_STREAM:
01259            if (sock->tcp_sock)
01260               next = tcp_sock_daemon (sock);
01261            break;
01262       case SOCK_DGRAM:
01263            if (sock->udp_sock)
01264               next = udp_sock_daemon (sock);
01265            break;
01266     }
01267   }
01268 }
01269
01270
01276 void _sock_crit_start (void)
01277 {
01278   if (sk_block < INT_MAX)
01279     ++sk_block;
01280 }
01281
01286 void _sock_crit_stop (void)
01287 {
01288   if (sk_block > 0)
01289   {
01290     --sk_block;
01291
01292 #ifdef SIGALRM
01293 #endif
01294
01295     if (sk_block == 0)
01296        sock_daemon();  /* run blocked sock_daemon() */
01297   }
01298 }
01299
01300
01301 #if defined(USE_FORTIFY) && defined(USE_DEBUG)
01302
01306 static void sock_fortify_exit (void)
01307 {
01308   const Socket *sock;
01309
01310   if (!_sock_dbug_active())
01311      return;
01312
01313   for (sock = sk_list; sock; sock = sock->next)
01314   {
01315     const char *type  = "<?>";
01316     const void *wsock = NULL;
01317     const _tcp_Socket *tcp;
01318
01319     if (sock->cookie != SAFETY_TCP ||
01320         sock->fd < SK_FIRST        ||
01321         sock->fd >= sk_last)
01322     {
01323       SOCK_DEBUGF (("\nsk_list munged; sock->fd = %d", sock->fd));
01324       return;
01325     }
01326
01327     switch (sock->so_type)
01328     {
01329       case SOCK_STREAM:
01330            type  = "TCP";
01331            wsock = sock->tcp_sock;
01332            break;
01333
01334       case SOCK_DGRAM:
01335            type  = "UDP";
01336            wsock = sock->udp_sock;
01337            break;
01338
01339       case SOCK_PACKET:
01340            type  = "Packet";
01341            wsock = sock->packet_pool;
01342            break;
01343
01344       case SOCK_RAW:
01345 #if defined(USE_IPV6)
01346            if (sock->so_family == AF_INET6)
01347            {
01348              type  = "Raw6";
01349              wsock = sock->raw6_sock;
01350            }
01351            else
01352 #endif
01353            {
01354              type  = "Raw";
01355              wsock = sock->raw_sock;
01356            }
01357            break;
01358     }
01359
01360     SOCK_DEBUGF (("\n%2d: inuse %d, type %s, watt-sock %08lX",
01361                   sock->fd, FD_ISSET(sock->fd,&inuse[0]) ? 1 : 0,
01362                   type, (DWORD)wsock));
01363
01364     tcp = sock->tcp_sock;
01365     if (tcp)
01366     {
01367       if (sock->so_state & SS_ISDISCONNECTING)
01368            SOCK_DEBUGF ((" (closed"));
01369       else if (sock->so_state & SS_ISLISTENING)
01370            SOCK_DEBUGF ((" (listening"));
01371       else SOCK_DEBUGF ((" (aborted?"));
01372       SOCK_DEBUGF ((", %s)", tcpStateName(tcp->state)));
01373     }
01374   }
01375
01376   SOCK_DEBUGF ((" \n"));
01377   Fortify_OutputStatistics();
01378   Fortify_LeaveScope();
01379 }
01380 #endif /* USE_FORTIFY && USE_DEBUG */
01381
01382
01383 #if defined(USE_DEBUG) && defined(ERRNO_VENDOR_VERSION)
01384
01387 static const char *vendor_version (void)
01388 {
01389   static char buf[10];
01390
01391 #if defined(__DJGPP__)
01392   sprintf (buf, "%d.%02d", __DJGPP__, __DJGPP_MINOR__);
01393 #elif defined(__DMC__)
01394   sprintf (buf, "%X.%X", __DMC__ >> 8, __DMC__ & 0xFF);
01395 #elif defined(__WATCOMC__)
01396   sprintf (buf, "%d.%d", __WATCOMC__/100, __WATCOMC__ % 100);
01397 #elif defined(__BORLANDC__)
01398   sprintf (buf, "%X.%X", __BORLANDC__ >> 8, __BORLANDC__ & 0xFF);
01399 #elif defined(__TURBOC__)
01400   sprintf (buf, "%X.%X", (__TURBOC__ >> 8) - 1, __TURBOC__ & 0xFF);
01401 #elif defined(_MSC_VER)
01402   sprintf (buf, "%d.%d", _MSC_VER/100, _MSC_VER % 100);
01403 #elif defined(__MINGW32__)
01404   sprintf (buf, "%d.%d", __MINGW32_MAJOR_VERSION, __MINGW32_MINOR_VERSION);
01405 #elif defined(__CCDL__)
01406   sprintf (buf, "%d.%d", __CCDL__/100, __CCDL__ % 100);
01407 #else
01408   buf[0] = '\0';
01409 #endif
01410   return (buf);
01411 }
01412
01417 static void check_errno_version (void)
01418 {
01419   const char *ver = vendor_version();
01420
01421   if (*ver && strcmp(ver,ERRNO_VENDOR_VERSION))
01422   {
01423     char *root = getenv ("WATT_ROOT");
01424
01425     if (!root)
01426        root = "$(WATT_ROOT)";
01427     (*_printf) ("\nWarning: %s\\inc\\sys\\*.err was created with a "
01428                 "different compiler\n"
01429                 "version (%s vs %s). Rebuilt %s\\util\\*_err.exe and "
01430                 "Watt-32 library.\n", root, ERRNO_VENDOR_VERSION, ver, root);
01431     BEEP();
01432   }
01433 }
01434 #endif  /* USE_DEBUG && ERRNO_VENDOR_VERSION */
01435
01436
01446 static BOOL init_sockets (void)
01447 {
01448   static int sk_result = -1;
01449
01450   if (sk_result >= 0)
01451      return (sk_result);
01452
01453   /* Hack to make linker pull in our strerror().
01454    */
01455   pull_neterr_module = 0;
01456
01457   _watt_do_exit = 0;
01458   sk_result = (watt_sock_init(0,0) == 0);
01459   if (!sk_result)
01460      return (FALSE);
01461
01462 #if defined(USE_DEBUG) && defined(ERRNO_VENDOR_VERSION)
01463   check_errno_version();
01464 #endif
01465
01466 #ifdef __DJGPP__
01467   {
01468     struct rlimit r;
01469
01470     getrlimit (RLIMIT_NOFILE, &r);
01471     r.rlim_max = MAX_SOCKETS;     /* We don't know this before we try it */
01472     setrlimit (RLIMIT_NOFILE, &r);
01473   }
01474   sk_last = MAX_SOCKETS;
01475 #else
01476   sk_last = SK_FIRST+1;
01477 #endif  /* __DJGPP__ */
01478
01479   sk_list = NULL;
01480   memset (&inuse[0], 0, sizeof(inuse));
01481   memset (&sk_hashes, 0, sizeof(sk_hashes));
01482
01483   addwattcpd (sock_daemon);
01484
01485 #if defined(USE_FORTIFY) && defined(USE_DEBUG)
01486   Fortify_EnterScope();
01487   Fortify_SetOutputFunc (bsd_fortify_print);
01488   RUNDOWN_ADD (sock_fortify_exit, 140);
01489 #endif
01490   return (TRUE);
01491 }
01492
01497 Socket *_socklist_find (int s)
01498 {
01499   Socket *sock;
01500
01501   if (!init_sockets())
01502      return (NULL);
01503
01504   for (sock = sock_hash_get(s); sock; sock = sock->next)
01505       if (sock->fd == s)
01506          return (sock);
01507   return (NULL);
01508 }
01509
01513 static BOOL sock_raw_add (Socket *sock, int family)
01514 {
01515   int i;
01516
01517 #if defined(USE_IPV6)
01518   if (family == AF_INET6)
01519   {
01520     for (i = 0; i < MAX_RAW6_BUFS; i++)
01521     {
01522       _raw6_Socket *raw6 = SOCK_CALLOC (sizeof(*raw6));
01523
01524       if (!raw6)
01525       {
01526         if (i == 0)        /* Failing to allocate 1 buffer is fatal */
01527            return (FALSE);
01528
01529         if (i > 0)
01530            break;
01531       }
01532       raw6->ip_type   = IP6_TYPE;
01533       raw6->next      = sock->raw6_sock;
01534       sock->raw6_sock = raw6;
01535     }
01536     return (TRUE);
01537   }
01538 #endif
01539   if (family == AF_INET)
01540   {
01541     for (i = 0; i < MAX_RAW_BUFS; i++)
01542     {
01543       _raw_Socket *raw = SOCK_CALLOC (sizeof(*raw));
01544
01545       if (!raw)
01546       {
01547         if (i == 0)
01548            return (FALSE);
01549
01550         if (i > 0)
01551            break;
01552       }
01553       raw->ip_type   = IP4_TYPE;
01554       raw->next      = sock->raw_sock;
01555       sock->raw_sock = raw;
01556     }
01557     return (TRUE);
01558   }
01559   return (FALSE);
01560 }
01561
01565 static Socket *socklist_add (int s, int type, int proto, int family)
01566 {
01567   Socket *sock = SOCK_CALLOC (sizeof(*sock));
01568   void   *proto_sk;
01569   BOOL    okay;
01570
01571   if (!sock)
01572      return (NULL);
01573
01574   switch (proto)
01575   {
01576     case IPPROTO_TCP:
01577          /* Only tcp times out on inactivity
01578           */
01579          sock->timeout     = sock_delay;
01580          sock->linger_time = TCP_LINGERTIME;
01581          sock->tcp_sock    = SOCK_CALLOC (sizeof(*sock->tcp_sock));
01582          proto_sk          = sock->tcp_sock;
01583          if (!sock->tcp_sock)
01584             goto fail;
01585          break;
01586
01587     case IPPROTO_UDP:
01588          sock->udp_sock = SOCK_CALLOC (sizeof(*sock->udp_sock));
01589          proto_sk       = sock->udp_sock;
01590          if (!sock->udp_sock)
01591             goto fail;
01592          break;
01593
01594     default:  /* type == SOCK_RAW/SOCK_PACKET */
01595          proto_sk = NULL;
01596          if (type == SOCK_PACKET)
01597               okay = sock_packet_add (sock);
01598          else okay = sock_raw_add (sock, family);
01599          if (!okay)
01600             goto fail;
01601          break;
01602   }
01603
01604 #if defined(__DJGPP__) && defined(USE_FSEXT)
01605   if (!__FSEXT_set_data(s,sock))
01606   {
01607     SOCK_FATAL (("%s (%d) Fatal: cannot grow FSEXT table\n",
01608                 __FILE__, __LINE__));
01609     goto fail;
01610   }
01611 #else
01612   ARGSUSED (proto_sk);
01613 #endif
01614
01615   /* Link 'sock' into the 'sk_list'
01616    */
01617   sock->next = sk_list;
01618   sk_list    = sock;
01619   sock_hash_add (s, sock);
01620
01621   sock->fd         = s;
01622   sock->so_type    = type;
01623   sock->so_proto   = proto;
01624   sock->so_family  = family;
01625   sock->so_state   = SS_UNCONNECTED;
01626   sock->send_lowat = DEFAULT_SEND_LOWAT;
01627   sock->recv_lowat = DEFAULT_RECV_LOWAT;
01628   sock->ip_ttl     = IPDEFTTL;
01629   sock->ip_tos     = 0;
01630   sock->cookie     = SAFETY_TCP;
01631   return (sock);
01632
01633 fail:
01634   if (proto_sk)
01635      free (proto_sk);
01636   else if (type == SOCK_PACKET)
01637     sock_packet_del (sock);
01638   else
01639     sock_raw_del (sock);
01640
01641   free (sock);
01642   return (NULL);
01643 }
01644
01648 static int set_proto (int type, BOOL is_ip6, int *proto)
01649 {
01650 #if defined(USE_IPV6)
01651   if (is_ip6 && !_sock_set_mcast_rx_mode())
01652   {
01653     SOCK_ERRNO (ENETDOWN);
01654     SOCK_DEBUGF (("\nsocket: ENETDOWN; %s", pkt_strerror(_pkt_errno)));
01655     return (-1);
01656   }
01657 #endif
01658
01659   if (type == SOCK_STREAM)
01660   {
01661     if (*proto == 0)
01662         *proto = IPPROTO_TCP;
01663
01664     else if (*proto != IPPROTO_TCP)
01665     {
01666       SOCK_ERRNO (EPROTONOSUPPORT);
01667       SOCK_DEBUGF (("\nsocket: invalid STREAM protocol (%d)", *proto));
01668       return (-1);
01669     }
01670   }
01671   else if (type == SOCK_DGRAM)
01672   {
01673     if (*proto == 0)
01674         *proto = IPPROTO_UDP;
01675
01676     else if (*proto != IPPROTO_UDP)
01677     {
01678       SOCK_ERRNO (EPROTONOSUPPORT);
01679       SOCK_DEBUGF (("\nsocket: invalid DGRAM protocol (%d)", *proto));
01680       return (-1);
01681     }
01682   }
01683   else if (type == SOCK_RAW)
01684   {
01685     if (*proto == IPPROTO_RAW)          /* match all IP-protocols */
01686         *proto = IPPROTO_IP;
01687
01688 #if defined(USE_IPV6)
01689     if (is_ip6)
01690         ip6_raw_hook = sock_raw6_recv; /* hook for _ip6_handler() */
01691     else
01692 #endif
01693         ip4_raw_hook = sock_raw4_recv; /* hook for _ip4_handler() */
01694   }
01695   else if (type == SOCK_PACKET)
01696   {
01697     *proto = 0;
01698     if (!_sock_set_promisc_rx_mode())
01699     {
01700       SOCK_ERRNO (ENETDOWN);
01701       SOCK_DEBUGF (("\nsocket: ENETDOWN; %s", pkt_strerror(_pkt_errno)));
01702       return (-1);
01703     }
01704   }
01705   ARGSUSED (is_ip6);
01706   return (0);
01707 }
01708
01719 int W32_CALL socket (int family, int type, int protocol)
01720 {
01721   Socket *sock = NULL;
01722   char   *err  = NULL;
01723   char   *fam;
01724   int     s;
01725   BOOL    is_ip6;
01726
01727   if (!init_sockets())
01728   {
01729     SOCK_ERRNO (ENETDOWN);
01730     return (-1);
01731   }
01732
01733   if (family != AF_UNSPEC &&
01734       family != AF_INET   &&
01735       family != AF_PACKET
01736 #if defined(USE_IPV6)
01737    && family != AF_INET6
01738 #endif
01739      )
01740   {
01741     SOCK_DEBUGF (("\nsocket: invalid family (%d)", family));
01742     SOCK_ERRNO (EAFNOSUPPORT);
01743     return (-1);
01744   }
01745
01746   if (type != SOCK_STREAM &&
01747       type != SOCK_DGRAM  &&
01748       type != SOCK_PACKET &&
01749       type != SOCK_RAW)
01750   {
01751     SOCK_DEBUGF (("\nsocket: invalid type (%d)", type));
01752     SOCK_ERRNO (ESOCKTNOSUPPORT);
01753     return (-1);
01754   }
01755
01756   if (family == AF_PACKET)
01757   {
01758     type   = SOCK_PACKET;
01759     family = AF_UNSPEC;   /* !! is this correct? */
01760     /* protocol ignored; could be ETH_P_ALL */
01761   }
01762
01763   if (type == SOCK_RAW && (protocol < IPPROTO_IP || protocol > IPPROTO_RAW))
01764   {
01765     SOCK_DEBUGF (("\nsocket: invalid SOCK_RAW proto (%d)", protocol));
01766     SOCK_ERRNO (EINVAL);
01767     return (-1);
01768   }
01769
01770   is_ip6 = (family == AF_INET6);
01771   fam    = (is_ip6 ? "6" : "");
01772
01773   if (set_proto(type, is_ip6, &protocol) < 0)
01774      return (-1);
01775
01776   s = sock_alloc_fd (&err);
01777   if (s >= 0)
01778      sock = socklist_add (s, type, protocol, family);
01779
01780   switch (type)
01781   {
01782     case SOCK_STREAM:
01783          SOCK_DEBUGF (("\nsocket: fam:AF_INET%s type:STREAM, proto %d, %d",
01784                        fam, protocol, s));
01785          break;
01786     case SOCK_DGRAM:
01787          SOCK_DEBUGF (("\nsocket: fam:AF_INET%s type:DGRAM, proto %d, %d",
01788                        fam, protocol, s));
01789          break;
01790     case SOCK_RAW:
01791          SOCK_DEBUGF (("\nsocket: fam:AF_INET%s type:RAW, proto %d, %d",
01792                        fam, protocol, s));
01793          break;
01794     case SOCK_PACKET:
01795          SOCK_DEBUGF (("\nsocket: fam:AF_UNSPEC type:PACKET, %d", s));
01796          break;
01797   }
01798
01799   if (err)     /* sock_alloc_fd() failed */
01800   {
01801     SOCK_DEBUGF ((", EMFILE; %s", err));
01802     SOCK_ERRNO (EMFILE);
01803     return (-1);
01804   }
01805
01806   if (!sock)   /* socklist_add() failed */
01807   {
01808     if (s >= 0)
01809        sock_close_fd (s);
01810     SOCK_DEBUGF ((", ENOMEM"));
01811     SOCK_ERRNO (ENOMEM);
01812     return (-1);
01813   }
01814
01815   if (type == SOCK_PACKET)
01816   {
01817     sock->old_eth_peek = _eth_recv_peek;
01818     _eth_recv_peek = (int (*)(void*)) sock_packet_peek;
01819   }
01820
01821   _bsd_socket_hook = socket_op_demux;
01822   ARGSUSED (fam);
01823   return (s);
01824 }
01825
01837 static int stream_cancel (const _tcp_Socket *tcp, BYTE icmp_type, int error)
01838 {
01839   Socket *socket;
01840   BOOL    should_drop = (icmp_type == ICMP_UNREACH &&
01841                          tcp->stress >= tcp->rigid) ||
01842                         (tcp->ip_type == 0);   /* already aborted */
01843
01844   for (socket = sk_list; socket; socket = socket->next)
01845       if (socket->so_type == SOCK_STREAM &&
01846           tcp == socket->tcp_sock && should_drop)
01847       {
01848         socket->so_state |= SS_CONN_REFUSED;
01849         socket->so_error  = error;
01850         return (1);
01851       }
01852   return (0);
01853 }
01854
01855 static int dgram_cancel (const _udp_Socket *udp, BYTE icmp_type, int error)
01856 {
01857   Socket *socket;
01858   int     num = 0;
01859
01860   for (socket = sk_list; socket; socket = socket->next)
01861       if (socket->so_type == SOCK_DGRAM && udp == socket->udp_sock)
01862       {
01863         socket->so_state |= SS_CONN_REFUSED;
01864         socket->so_error  = error;
01865         num++;
01866       }
01867   ARGSUSED (icmp_type);
01868   return (num);
01869 }
01870
01871 #if defined(USE_DEBUG)
01872 static __inline const char *ip_proto_str (WORD prot)
01873 {
01874   switch (prot)
01875   {
01876     case UDP_PROTO:
01877          return ("UDP");
01878     case TCP_PROTO:
01879          return ("TCP");
01880     case ICMP_PROTO:
01881          return ("ICMP");
01882     case IGMP_PROTO:
01883          return ("IGMP");
01884     default:
01885          return ("unknown");
01886   }
01887 }
01888 #endif
01889
01890 /*
01891  * Handler for lower layer ICMP messages/errors.
01892  * Return number of BSD-sockets the ICMP-event matched
01893  * (retval not used yet).
01894  */
01895 static int icmp_callback (sock_type *s, BYTE icmp_type, BYTE icmp_code)
01896 {
01897   const char *type_str = "??";
01898   int   error;
01899
01900   if (icmp_type == ICMP_UNREACH)
01901        error = (icmp_code == ICMP_UNREACH_NET ||
01902                 icmp_code == ICMP_UNREACH_NET_UNKNOWN ||
01903                 icmp_code == ICMP_UNREACH_NET_PROHIB) ?
01904                ENETUNREACH : EHOSTUNREACH;
01905   else error = ECONNREFUSED;
01906
01907   if (icmp_type < DIM(icmp_type_str))
01908      type_str = icmp_type_str [icmp_type];
01909
01910   SOCK_DEBUGF (("\n  icmp_callback (s=%08lX, IP-proto %s, %s, code %d)",
01911                 (DWORD)s, ip_proto_str(s->udp.ip_type), type_str, icmp_code));
01912
01913   if (icmp_type == ICMP_UNREACH || icmp_type == ICMP_PARAMPROB)
01914   {
01915     if (s->udp.ip_type == UDP_PROTO)
01916        return dgram_cancel (&s->udp, icmp_type, error);
01917
01918     if (s->udp.ip_type == TCP_PROTO)
01919        return stream_cancel (&s->tcp, icmp_type, error);
01920   }
01921   ARGSUSED (type_str);
01922   return (0);
01923 }
01924
01928 int _UDP_open (Socket *socket, struct in_addr host, WORD loc_port, WORD rem_port)
01929 {
01930   DWORD ip = ntohl (host.s_addr);
01931
01932   loc_port = ntohs (loc_port);
01933   rem_port = ntohs (rem_port);
01934
01935   if (!udp_open (socket->udp_sock, loc_port, ip, rem_port, NULL))
01936      return (0);
01937
01938   _sock_set_rcv_buf ((sock_type*)socket->udp_sock, DEFAULT_UDP_SIZE);
01939   socket->udp_sock->icmp_callb = (icmp_upcall) icmp_callback;
01940   return (1);
01941 }
01942
01943 int _UDP_listen (Socket *socket, struct in_addr host, WORD port)
01944 {
01945   _udp_Socket *udp = socket->udp_sock;
01946   DWORD        addr;
01947
01948   port = ntohs (port);
01949
01950   if (socket->so_state & SS_PRIV)
01951   {
01952     int   size = sizeof(recv_buf) * MAX_DGRAMS;
01953     void *pool = malloc (size);
01954
01955     if (!pool)
01956     {
01957       SOCK_FATAL (("%s (%d) Fatal: Allocation failed\n",
01958                   __FILE__, __LINE__));
01959       SOCK_ERRNO (ENOMEM);
01960       return (-1);
01961     }
01962     socket->bcast_pool = (recv_buf**) pool;
01963     socket->pool_size  = size;
01964
01965     /* Mapping `INADDR_ANY' to `INADDR_BROADCAST' causes udp_demux()
01966      * to demux to the correct watt-socket; s->hisaddr = IP_BCAST_ADDR in
01967      * passive socket demux loop.
01968      */
01969     if (host.s_addr == INADDR_ANY)
01970          addr = INADDR_BROADCAST;
01971     else addr = ntohl (host.s_addr);
01972
01973     udp_listen (udp, port, addr, 0, NULL);
01974
01975     /* Setup _recvdaemon() to enqueue broadcast/"unconnected" messages
01976      */
01977     sock_recv_init ((sock_type*)udp, pool, size);
01978   }
01979   else
01980   {
01981     addr = ntohl (host.s_addr);
01982     udp_listen (udp, port, addr, 0, NULL);
01983   }
01984   udp->icmp_callb = (icmp_upcall) icmp_callback;
01985   return (1);
01986 }
01987
01988
01992 int _TCP_open (Socket *socket, struct in_addr host, WORD loc_port, WORD rem_port)
01993 {
01994   DWORD dest = ntohl (host.s_addr);
01995
01996   loc_port = ntohs (loc_port);
01997   rem_port = ntohs (rem_port);
01998
01999   if (!tcp_open (socket->tcp_sock, loc_port, dest, rem_port, NULL))
02000      return (0);
02001
02002   if (socket->so_state & SS_NBIO)
02003      socket->tcp_sock->locflags |= LF_NOCLOSE;
02004
02017   /* Advertise a large rcv-win from the next ACK on.
02018    */
02019   _sock_set_rcv_buf ((sock_type*)socket->tcp_sock, tcp_recv_win);
02020   socket->tcp_sock->icmp_callb = (icmp_upcall) icmp_callback;
02021   return (1);
02022 }
02023
02024 int _TCP_listen (Socket *socket, struct in_addr host, WORD port)
02025 {
02026   DWORD addr     = ntohl (host.s_addr);
02027   WORD  loc_port = ntohs (port);
02028
02029   tcp_listen (socket->tcp_sock, loc_port, addr, 0, NULL, 0);
02030   socket->tcp_sock->icmp_callb = (icmp_upcall) icmp_callback;
02031   return (1);
02032 }
02033
02034 #if defined(USE_IPV6)
02035 int _TCP6_open (Socket *socket, const void *dst, WORD loc_port, WORD rem_port)
02036 {
02037   _tcp_Socket *tcp = socket->tcp_sock;
02038   UINT         rtt;
02039
02040   SIO_TRACE (("_TCP6_open"));
02041
02042   WATT_LARGE_CHECK (tcp, sizeof(*tcp));
02043   _tcp_unthread (tcp, FALSE);    /* just in case not totally closed */
02044
02045   memset (tcp, 0, sizeof(*tcp));
02046   tcp->state = tcp_StateCLOSED;  /* otherwise is tcp_StateLISTEN on failure */
02047
02048   if (!_eth_is_init) /* GvB 2002-09, Lets us survive without a working eth */
02049   {
02050     SOCK_ERRNO (ENETDOWN);
02051     tcp->err_msg = _LANG (_eth_not_init);
02052     return (0);
02053   }
02054
02055   if (IN6_ARE_ADDR_EQUAL(dst,&in6addr_any) || IN6_IS_ADDR_MULTICAST(dst))
02056   {
02057     SOCK_ERRNO (EINVAL);
02058     sprintf (tcp->err_buf, _LANG("Illegal destination (%s)"), _inet6_ntoa(dst));
02059     tcp->err_msg = tcp->err_buf;
02060     return (0);
02061   }
02062
02063   if (!icmp6_neigh_solic (dst, &tcp->his_ethaddr))  /* This blocks! */
02064   {
02065     SOCK_ERRNO (EHOSTUNREACH);
02066     strcpy (tcp->err_buf, _LANG("Neighbor Solic failed "));
02067     strcat (tcp->err_buf, _inet6_ntoa(dst));
02068     tcp->err_msg = tcp->err_buf;
02069     STAT (ip6stats.ip6s_noroute++);
02070     return (0);
02071   }
02072
02073   _sock_set_rcv_buf ((sock_type*)tcp, tcp_recv_win);
02074
02075   memcpy (&tcp->my6addr, &in6addr_my_ip, sizeof(tcp->my6addr));
02076   memcpy (&tcp->his6addr, dst, sizeof(tcp->his6addr));
02077
02078   loc_port = ntohs (loc_port);
02079   rem_port = ntohs (rem_port);
02080
02081   tcp->is_ip6       = TRUE;
02082   tcp->icmp_callb   = (icmp_upcall) icmp_callback;
02083   tcp->state        = tcp_StateSYNSENT;
02084   tcp->ip_type      = TCP_PROTO;
02085   tcp->max_seg      = _mss;
02086   tcp->cwindow      = 1;
02087   tcp->wwindow      = 0;                           /* slow start VJ algorithm */
02088   tcp->vj_sa        = INIT_VJSA;
02089   tcp->rto          = tcp_OPEN_TO;                 /* added 14-Dec 1999, GV */
02090   tcp->myaddr       = my_ip_addr;
02091   tcp->myport       = find_free_port (loc_port,1); /* get a nonzero port val */
02092   tcp->locflags     = LF_LINGER;                   /* close via TIMEWT state */
02093   tcp->ttl          = _default_ttl;
02094   tcp->hisport      = rem_port;
02095   tcp->send_next    = INIT_SEQ();
02096   tcp->flags        = tcp_FlagSYN;
02097   tcp->unhappy      = TRUE;
02098   tcp->protoHandler = NULL;
02099   tcp->usr_yield    = NULL;
02100
02101   tcp->safetysig    = SAFETY_TCP;                /* marker signatures */
02102   tcp->safetytcp    = SAFETY_TCP;
02103   tcp->next         = _tcp_allsocs;              /* insert into chain */
02104
02105 /* sock_yield (tcp, tcp6_yield); */
02107   _tcp_allsocs    = tcp;
02108
02111   if (tcp_nagle)
02112      tcp->sockmode = SOCK_MODE_NAGLE;
02113   tcp->sockmode |= SOCK_MODE_BINARY;
02114
02115   tcp->timeout = set_timeout (tcp_LONGTIMEOUT);
02116
02117   TCP_SEND (tcp);  /* send opening SYN */
02118
02119   /* find previous RTT replacing RTT set in tcp_send() above
02120    */
02121   if (tcp_rtt_get(tcp, &rtt, NULL))
02122        tcp->rtt_time = set_timeout (rtt);
02123   else tcp->rtt_time = set_timeout (tcp_OPEN_TO);
02124   return (1);
02125 }
02126
02127 int _TCP6_listen (Socket *socket, const void *host, WORD loc_port)
02128 {
02130   ARGSUSED (socket);
02131   ARGSUSED (host);
02132   ARGSUSED (loc_port);
02133   return (0);
02134 }
02135
02136 int _UDP6_open (Socket *socket, const void *host, WORD loc_port, WORD rem_port)
02137 {
02139   _sock_set_rcv_buf ((sock_type*)socket->udp_sock, DEFAULT_UDP_SIZE);
02140   socket->udp_sock->icmp_callb = (icmp_upcall) icmp_callback;
02141   ARGSUSED (host);
02142   ARGSUSED (loc_port);
02143   ARGSUSED (rem_port);
02144   return (0);
02145 }
02146
02147 int _UDP6_listen (Socket *socket, const void *host, WORD port)
02148 {
02150   ARGSUSED (socket);
02151   ARGSUSED (host);
02152   ARGSUSED (port);
02153   return (0);
02154 }
02155 #endif  /* USE_IPV6 */
02156
02157
02158 #ifdef NOT_USED
02159
02164 int _sock_half_open (const _tcp_Socket *s)
02165 {
02166   if (!s || s->ip_type != TCP_PROTO)
02167      return (0);
02168
02169   return (s->state >= tcp_StateFINWT1 &&
02170           s->state <= tcp_StateCLOSED);
02171 }
02172 #endif
02173
02174 #if 0  /* not finished and seldom needed */
02175
02179 int W32_CALL socketpair (int family, int type, int protocol, int usockvec[2])
02180 {
02181   Socket *sock1, *sock2;
02182   int     s1, s2;
02183
02184   if ((s1 = socket (family, type, protocol)) < 0)
02185      return (-errno);
02186
02187   sock1 = socklist_find (s1);
02188
02189   /* Now grab another socket and try to connect the two together.
02190    */
02191   if ((s2 = socket (family, type, protocol)) < 0)
02192   {
02193     close_s (s1);
02194     return (-EINVAL);
02195   }
02196
02197   sock2 = socklist_find (s2);
02198
02199   sock1->conn = sock2;
02200   sock2->conn = sock1;
02201   sock1->so_state = SS_CONNECTED;
02202   sock2->so_state = SS_CONNECTED;
02203
02204   usockvec[0] = s1;
02205   usockvec[1] = s2;
02206   return (0);
02207 }
02208 #endif
02209
02210 #endif /* USE_BSD_API */
Generated on Wed Jan 25 15:42:39 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/SOCKET.H Source File

SRC/SOCKET.H

Go to the documentation of this file.
00001
00004 /*
00005  *  BSD sockets functionality for Waterloo TCP/IP.
00006  *
00007  *  by G. Vanem 1997
00008  */
00009
00010 #ifndef _w32_SOCKET_H
00011 #define _w32_SOCKET_H
00012
00013 #if defined(__TURBOC__) && (__TURBOC__ <= 0x301)
00014   /*
00015    * Prevent tcc <= 2.01 from even looking at this.
00016    */
00017   #define BOOL int
00018 #else
00019
00020 #include <stdio.h>
00021 #include <stdlib.h>
00022 #include <stdarg.h>
00023 #include <stddef.h>
00024 #include <string.h>
00025 #include <signal.h>
00026 #include <setjmp.h>
00027 #include <ctype.h>
00028 #include <time.h>
00029 #include <limits.h>
00030 #include <fcntl.h>
00031 #include <io.h>
00032
00033 #include <sys/socket.h>
00034 #include <sys/ioctl.h>
00035 #include <sys/syslog.h>
00036
00037 #include <net/if.h>
00038 #include <net/if_dl.h>
00039 #include <net/if_arp.h>
00040 #include <net/if_ether.h>
00041 #include <net/if_packe.h>
00042 #include <net/route.h>
00043
00044 #include <netinet/in.h>
00045 #include <netinet/in_systm.h>
00046 #include <netinet/ip.h>
00047 #include <netinet/ip_var.h>
00048 #include <netinet/ip_icmp.h>
00049 #include <netinet/in_pcb.h>
00050 #include <netinet/in_var.h>
00051 #include <netinet/tcp.h>
00052 #include <netinet/tcpip.h>
00053 #include <netinet/ip6.h>
00054 #include <netinet/tcp_time.h>
00055
00056 #include <arpa/inet.h>
00057 #include <arpa/nameser.h>
00058 #include <arpa/tftp.h>
00059 #include <netdb.h>
00060 #include <resolv.h>
00061
00062 #include "wattcp.h"
00063 #include "chksum.h"
00064 #include "wdpmi.h"
00065 #include "misc.h"
00066 #include "timer.h"
00067 #include "strings.h"
00068 #include "sock_ini.h"
00069 #include "language.h"
00070 #include "pcconfig.h"
00071 #include "pcqueue.h"
00072 #include "pcdbug.h"
00073 #include "pcsed.h"
00074 #include "pcpkt.h"
00075 #include "pcstat.h"
00076 #include "pcmulti.h"
00077 #include "pctcp.h"
00078 #include "pcbuf.h"
00079 #include "pcicmp.h"
00080 #include "pcarp.h"
00081 #include "pcrecv.h"
00082 #include "printk.h"
00083 #include "netaddr.h"
00084 #include "ip4_in.h"
00085 #include "ip4_out.h"
00086 #include "ip6_in.h"
00087 #include "ip6_out.h"
00088 #include "rs232.h"
00089 #include "bsddbug.h"
00090 #include "bsdname.h"
00091 #include "gettod.h"
00092
00093
00094 /*
00095  * Various sizes
00096  */
00097 #if (DOSX)
00098   #define MAX_DGRAMS        5              /* # of datagrams for broadcast */
00099   #define MAX_RAW_BUFS      5              /* # of _raw_Socket in list */
00100   #define MAX_RAW6_BUFS     5              /* # of _raw6_Socket in list */
00101   #define MAX_PACKET_BUFS   10
00102   #define MAX_SOCKETS       5000           /* # of sockets to handle */
00103   #define MAX_TCP_RECV_BUF  (1024*1024-1)  /* Max size for SO_RCVBUF */
00104 #else
00105   #define MAX_DGRAMS        2
00106   #define MAX_RAW_BUFS      2
00107   #define MAX_RAW6_BUFS     2
00108   #define MAX_PACKET_BUFS   5
00109   #define MAX_SOCKETS       512
00110   #define MAX_TCP_RECV_BUF  (USHRT_MAX-1)
00111 #endif
00112
00113 #define MAX_TCP_SEND_BUF    (USHRT_MAX-1)   /* for SO_SNDLOWAT/SO_RCVLOWAT */
00114 #define MAX_UDP_RECV_BUF    (USHRT_MAX-1)
00115 #define MAX_UDP_SEND_BUF    (USHRT_MAX-1)
00116 #define MAX_RAW_RECV_BUF    (USHRT_MAX-1)
00117 #define MAX_RAW_SEND_BUF    (USHRT_MAX-1)
00118
00119 #define DEFAULT_SEND_LOWAT  0
00120 #define DEFAULT_RECV_LOWAT  0
00121 #define DEFAULT_UDP_SIZE   (8*1024)
00122
00123
00124 /* Buffer types for AF_PACKET sockets
00125  */
00126 struct sock_packet_buf {
00127        WORD rx_len;
00128        char rx_buf [ETH_MAX+4];   /* add room for end marker */
00129      };
00130
00131 typedef struct sock_packet_pool {
00132         struct pkt_ringbuf     queue;
00133         struct sock_packet_buf buf [MAX_PACKET_BUFS];
00134       } sock_packet_pool;
00135
00136 typedef struct Socket {
00137         int                 fd;
00138         struct Socket      *next;
00139         struct sockaddr_in *local_addr;
00140         struct sockaddr_in *remote_addr;
00141
00142         int                 timeout;
00143         int                 inp_flags;   /* misc. IP-protocol options */
00144         BYTE                ip_tos;
00145         BYTE                ip_ttl;
00146
00147         struct ip_opts     *ip_opt;      /* for setsockopt(s,IP_OPTION,..) */
00148         unsigned            ip_opt_len;  /* output IP-option length */
00149
00150         int                 so_options;  /* SO_KEEPALIVE, SO_ACCEPTCONN etc. */
00151         int                 so_proto;    /* IPPROTO_UDP, IPPROTO_TCP etc. */
00152         int                 so_type;     /* SOCK_STREAM, SOCK_DGRAM etc. */
00153         int                 so_family;   /* address family AF_INET/AF_INET6 */
00154         int                 so_state;    /* internal state, ref SS_* below */
00155         int                 so_error;    /* internal socket errno */
00156         time_t              close_time;  /* we closed at (SOCK_STREAM) */
00157         BOOL                linger_on;   /* user specified lingering */
00158         unsigned            linger_time; /* linger-time (SOCK_STREAM) */
00159         unsigned            fd_duped;    /* FSEXT reference counting */
00160         DWORD               keepalive;   /* keepalive timeout */
00161         DWORD               nb_timer;    /* non-block timer */
00162         _udp_Socket        *udp_sock;    /* actual state and Rx/Tx data is in */
00163         _tcp_Socket        *tcp_sock;    /*  one of these pointers */
00164         _raw_Socket        *raw_sock;    /* points to 1st in linked-list */
00165         _raw6_Socket       *raw6_sock;
00166         recv_buf          **bcast_pool;  /* buffers for INADDR_ANY sockets */
00167         unsigned            pool_size;   /* size of above buffer */
00168
00169         /* For SOCK_PACKET sockets.
00170          */
00171         sock_packet_pool   *packet_pool;
00172         int               (*old_eth_peek) (void*);
00173
00174         /* listen-queue for incoming tcp connections
00175          */
00176         int                 backlog;
00177         _tcp_Socket        *listen_queue [SOMAXCONN];
00178         DWORD               syn_timestamp[SOMAXCONN]; /* got SYN at [msec] */
00179
00180         unsigned            send_lowat;  /* low-water Tx marks */
00181         unsigned            recv_lowat;  /* low-water Rx marks */
00182         DWORD               cookie;      /* memory cookie / marker */
00183
00184       } Socket;
00185
00186
00187 /*
00188  * Let first socket start at 3 in order not to
00189  * confuse sockets with stdin/stdout/stderr handles.
00190  * First socket will always be >= 3 on djgpp thanks to FS-extensions.
00191  */
00192 #define SK_FIRST  3
00193
00194 /*
00195  * Number of 'fd_set' required to hold MAX_SOCKETS.
00196  */
00197 #define NUM_SOCK_FDSETS  ((MAX_SOCKETS+sizeof(fd_set)-1) / sizeof(fd_set))
00198
00199 /*
00200  * Misc. defines
00201  */
00202 #ifndef SIGIO       /* for asynchronous I/O support (not yet) */
00203 #define SIGIO       SIGUSR1
00204 #endif
00205
00206 #ifndef IPPORT_ANY
00207 #define IPPORT_ANY  0
00208 #endif
00209
00210 /*
00211  * Socket state bits (in so_state).
00212  */
00213 #define SS_NOFDREF         0x0001          /* no file table ref any more */
00214 #define SS_UNCONNECTED     SS_NOFDREF      /* or just created socket */
00215 #define SS_ISCONNECTED     0x0002          /* socket connected to a peer */
00216 #define SS_ISCONNECTING    0x0004          /* in process of connecting */
00217 #define SS_ISDISCONNECTING 0x0008          /* in process of disconnecting */
00218 #define SS_CANTSENDMORE    0x0010          /* can't send more data */
00219 #define SS_CANTRCVMORE     0x0020          /* can't receive more data */
00220 #define SS_RCVATMARK       0x0040          /* at mark on input (no used) */
00221
00222 #define SS_PRIV            0x0080          /* privileged for broadcast */
00223 #define SS_NBIO            0x0100          /* non-blocking operations */
00224 #define SS_ASYNC           0x0200          /* async I/O notify (not used) */
00225 #define SS_ISCONFIRMING    0x0400          /* accepting connection req */
00226 #define SS_ISLISTENING     SS_ISCONFIRMING /* non standard */
00227
00228 #define SS_LOCAL_ADDR      0x0800          /* has local address/port (not used) */
00229 #define SS_REMOTE_ADDR     0x1000          /* has remote address/port (not used) */
00230 #define SS_CONN_REFUSED    0x2000          /* connection refused (ICMP_UNREACH etc) */
00231
00232
00233 /*
00234  * Socket macros
00235  */
00236 #define SOCK_CALLOC(sz)  _sock_calloc (sz, __FILE__, __LINE__)
00237 #define SOCK_DEL_FD(fd)  _sock_del_fd (fd, __FILE__, __LINE__)
00238
00239 /*
00240  * Prologue code starting most BSD-socket functions
00241  */
00242 #define SOCK_PROLOGUE(socket, fmt, fd)           \
00243         do {                                     \
00244           SOCK_DEBUGF ((fmt, fd));               \
00245           if (!socket) {                         \
00246              if (_sock_dos_fd(fd)) {             \
00247                 SOCK_DEBUGF ((", ENOTSOCK"));    \
00248                 SOCK_ERRNO (ENOTSOCK);           \
00249                 return (-1);                     \
00250              }                                   \
00251              SOCK_DEBUGF ((", EBADF"));          \
00252              SOCK_ERRNO (EBADF);                 \
00253              return (-1);                        \
00254           }                                      \
00255         } while (0)
00256
00257 #if (DOSX)
00258   #define VERIFY_RW(ptr,len)                     \
00259           do {                                   \
00260             if (!valid_addr((DWORD)(ptr),len)) { \
00261                SOCK_DEBUGF ((", EFAULT "         \
00262                  "(buf %08lXh, len %d)",         \
00263                  (DWORD)(ptr), (int)(len)));     \
00264                SOCK_ERRNO (EFAULT);              \
00265                return (-1);                      \
00266             }                                    \
00267           } while (0)
00268 #else
00269   #define VERIFY_RW(ptr,len) ((void)0)
00270 #endif
00271
00272 /*
00273  * Print error and exit at critical places. Should not be used
00274  * in "production quality" code.
00275  */
00276 #if defined(USE_BSD_FATAL)
00277   #define SOCK_FATAL(arg)  do {                        \
00278                              (*_printf) arg;           \
00279                              fflush (stdout);          \
00280                           /* _watt_fatal_error = 1; */ \
00281                              exit (-1);                \
00282                              /*@-unreachable@*/        \
00283                            } while (0)
00284 #else
00285   #define SOCK_FATAL(arg)  ((void)0)
00286 #endif
00287
00288 /*
00289  * Only djgpp/DMC have (some of) the <fcntl.h> F_?? commands.
00290  * For others, we define some dummy values.
00291  */
00292 #define W32_FCNTL_BASE 100
00293
00294 #ifndef F_DUPFD
00295 #define F_DUPFD   (W32_FCNTL_BASE+0)
00296 #endif
00297
00298 #ifndef F_GETFL
00299 #define F_GETFL   (W32_FCNTL_BASE+1)
00300 #endif
00301
00302 #ifndef F_SETFL
00303 #define F_SETFL   (W32_FCNTL_BASE+2)
00304 #endif
00305
00306 #ifndef F_GETFD
00307 #define F_GETFD   (W32_FCNTL_BASE+3)
00308 #endif
00309
00310 #ifndef F_SETFD
00311 #define F_SETFD   (W32_FCNTL_BASE+4)
00312 #endif
00313
00314 #ifndef F_GETLK
00315 #define F_GETLK   (W32_FCNTL_BASE+5)
00316 #endif
00317
00318 #ifndef F_SETLK
00319 #define F_SETLK   (W32_FCNTL_BASE+6)
00320 #endif
00321
00322 #ifndef F_SETLKW
00323 #define F_SETLKW  (W32_FCNTL_BASE+7)
00324 #endif
00325
00326 #ifndef F_GETOWN
00327 #define F_GETOWN  (W32_FCNTL_BASE+8)
00328 #endif
00329
00330 #ifndef F_SETOWN
00331 #define F_SETOWN  (W32_FCNTL_BASE+9)
00332 #endif
00333
00334
00335 W32_FUNC int close_s  (int s);
00336 W32_FUNC int write_s  (int s, const char *buf, int num);
00337 W32_FUNC int writev_s (int s, const struct iovec *vec, size_t num);
00338 W32_FUNC int recvmsg  (int s, struct msghdr *msg, int flags);
00339 W32_FUNC int read_s   (int s, char *buf, int num);
00340 W32_FUNC int select_s (int n, fd_set *r, fd_set *w, fd_set *x, struct timeval *t);
00341
00342 #if defined(WIN32)
00343 W32_FUNC int W32_CALL select (int num_sockets,
00344                               fd_set *read_events,
00345                               fd_set *write_events,
00346                               fd_set *except_events,
00347                               struct timeval *timeout);
00348 #endif
00349
00350 /*
00351  * Setup trapping of signals and critical sections around loops.
00352  */
00353 extern int  _sock_sig_setup   (void);
00354 extern int  _sock_sig_restore (void);
00355 extern int  _sock_sig_pending (void);
00356 extern int  _sock_sig_epipe   (void);
00357
00358 extern void _sock_crit_start  (void);
00359 extern void _sock_crit_stop   (void);
00360
00361 /*
00362  * Timing of "kernel" times for some socket calls.
00363  */
00364 extern void _sock_start_timer (void);
00365 extern void _sock_stop_timer  (void);
00366
00367 /*
00368  * Things for SOCK_PACKET sockets.
00369  */
00370 extern unsigned sock_packet_transmit (Socket *sock, const void *buf,
00371                                       unsigned len, const struct sockaddr *to,
00372                                       int tolen);
00373
00374 extern unsigned sock_packet_receive (Socket *sock, void *buf, unsigned len,
00375                                      struct sockaddr *from, int *fromlen);
00376
00377 extern unsigned sock_packet_rbused (Socket *sock);
00378
00379 /*
00380  * Allocation, `sk_list' stuff etc.
00381  */
00382 extern void   *_sock_calloc    (size_t size, const char *file, unsigned line);
00383 extern Socket *_sock_del_fd    (int sock, const char *file, unsigned line);
00384 extern Socket *_socklist_find  (int s);
00385 extern BOOL    _sock_dos_fd    (int s);
00386 extern int     _sock_half_open (const _tcp_Socket *tcp);
00387 extern int     _sock_append    (_tcp_Socket **tcp);
00388 extern int     _sock_set_rcv_buf  (sock_type *s, size_t len);
00389 extern void    _sock_free_rcv_buf (sock_type *s);
00390 extern void    _sock_set_syn_hook (int (*func)(_tcp_Socket **));
00391 extern BOOL    _sock_set_promisc_rx_mode (void);
00392 extern BOOL    _sock_set_mcast_rx_mode   (void);
00393 extern BOOL    _sock_set_normal_rx_mode  (const Socket *_this);
00394
00395 /*
00396  * Interface naming stuff.
00397  */
00398 extern const sock_type *__get_sock_from_s (int s, int proto);
00399 extern void             __get_ifname (char *if_name);
00400 extern void             __set_ifname (const char *if_name);
00401 extern int              __scope_ascii_to_id (const char *str);
00402 extern int              __scope_id_to_ascii (int scope);
00403
00404
00405 /*
00406  * Check `sockaddr*' passed to bind()/connect().
00407  */
00408 extern int _sock_chk_sockaddr (Socket *socket, const struct sockaddr *sa, int len);
00409
00410 /*
00411  * Handle UDP/TCP connect()/listen() calls.
00412  */
00413 extern int _TCP_open   (Socket *socket, struct in_addr host, WORD loc_port, WORD rem_port);
00414 extern int _UDP_open   (Socket *socket, struct in_addr host, WORD loc_port, WORD rem_port);
00415 extern int _TCP_listen (Socket *socket, struct in_addr host, WORD loc_port);
00416 extern int _UDP_listen (Socket *socket, struct in_addr host, WORD port);
00417
00418 extern int _TCP6_open  (Socket *socket, const void *host, WORD loc_port, WORD rem_port);
00419 extern int _UDP6_open  (Socket *socket, const void *host, WORD loc_port, WORD rem_port);
00420 extern int _TCP6_listen(Socket *socket, const void *host, WORD loc_port);
00421 extern int _UDP6_listen(Socket *socket, const void *host, WORD port);
00422
00423 #endif  /* old __TURBOC__ */
00424 #endif  /* _w32_SOCKET_H */
00425
Generated on Wed Jan 25 15:42:39 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/SOCKOPT.C Source File

SRC/SOCKOPT.C

Go to the documentation of this file.
00001
00005 /*  BSD sockets functionality for Waterloo TCP/IP
00006  *
00007  *  Copyright (c) 1997-2002 Gisle Vanem <giva@bgnett.no>
00008  *
00009  *  Redistribution and use in source and binary forms, with or without
00010  *  modification, are permitted provided that the following conditions
00011  *  are met:
00012  *  1. Redistributions of source code must retain the above copyright
00013  *     notice, this list of conditions and the following disclaimer.
00014  *  2. Redistributions in binary form must reproduce the above copyright
00015  *     notice, this list of conditions and the following disclaimer in the
00016  *     documentation and/or other materials provided with the distribution.
00017  *  3. All advertising materials mentioning features or use of this software
00018  *     must display the following acknowledgement:
00019  *       This product includes software developed by Gisle Vanem
00020  *       Bergen, Norway.
00021  *
00022  *  THIS SOFTWARE IS PROVIDED BY ME (Gisle Vanem) AND CONTRIBUTORS ``AS IS''
00023  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00024  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00025  *  ARE DISCLAIMED.  IN NO EVENT SHALL I OR CONTRIBUTORS BE LIABLE FOR ANY
00026  *  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00027  *  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00028  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00029  *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00030  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00031  *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00032  *
00033  *  Version
00034  *
00035  *  0.5 : Dec 18, 1997 : G. Vanem - created
00036  *  0.6 : Apr 07, 2000 : Added multicast options IP_ADD_MEMBERSHIP and
00037  *                       IP_DROP_MEMBERSHIP. Vlad Erochine <vlad@paragon.ru>
00038  *  0.7 : Jun 06, 2000 : Added support for SO_SNDLOWAT and SO_RCVLOWAT
00039  */
00040
00041 #include "socket.h"
00042
00043 #if defined(USE_BSD_API)
00044
00045 static int set_sol_opt  (Socket *s, int opt, const void *val, unsigned len);
00046 static int set_raw_opt  (Socket *s, int opt, const void *val, int len);
00047 static int get_sol_opt  (Socket *s, int opt, void *val, int *len);
00048 static int get_raw_opt  (Socket *s, int opt, void *val, int *len);
00049
00050 static int set_tcp_opt  (_tcp_Socket *tcp, int opt, const void *val, int len);
00051 static int set_udp_opt  (_udp_Socket *udp, int opt, const void *val, int len);
00052 static int get_tcp_opt  (_tcp_Socket *tcp, int opt, void *val, int *len);
00053 static int get_udp_opt  (_udp_Socket *udp, int opt, void *val, int *len);
00054
00055 static int set_recv_buf (sock_type *s, DWORD size, BOOL is_tcp);
00056 static int set_xmit_buf (sock_type *s, DWORD size, BOOL is_tcp);
00057 static int raw_rx_buf   (_raw_Socket  *raw, DWORD size);
00058 static int raw6_rx_buf  (_raw6_Socket *raw, DWORD size);
00059 static int raw_tx_buf   (_raw_Socket  *raw, DWORD size);
00060 static int raw6_tx_buf  (_raw6_Socket *raw, DWORD size);
00061 static int set_tx_lowat (Socket *s, unsigned size);
00062 static int set_rx_lowat (Socket *s, unsigned size);
00063 static int get_tx_lowat (const Socket *s, unsigned *size);
00064 static int get_rx_lowat (const Socket *s, unsigned *size);
00065
00066 #if defined(USE_DEBUG)
00067 static const char *sockopt_name (int level, int option);
00068 #endif
00069
00070 int W32_CALL setsockopt (int s, int level, int option, const void *optval, int optlen)
00071 {
00072   Socket *socket = _socklist_find (s);
00073   int     rc;
00074
00075   SOCK_DEBUGF (("\nsetsockopt:%d, %s", s, sockopt_name(level,option)));
00076
00077   if (!socket)
00078   {
00079     if (_sock_dos_fd(s))
00080     {
00081       SOCK_DEBUGF ((", ENOTSOCK"));
00082       SOCK_ERRNO (ENOTSOCK);
00083       return (-1);
00084     }
00085     SOCK_DEBUGF ((", EBADF"));
00086     SOCK_ERRNO (EBADF);
00087     return (-1);
00088   }
00089
00090   VERIFY_RW (optval, optlen);
00091
00092   if ((WORD)level == SOL_SOCKET)
00093      rc = set_sol_opt (socket, option, optval, optlen);
00094
00095 #if 0
00096   else if ((WORD)level == SOL_PACKET)
00097      rc = set_packet_opt (socket, option, optval, optlen);
00098 #endif
00099
00100   else if (level == socket->so_proto && level == IPPROTO_TCP)
00101      rc = set_tcp_opt (socket->tcp_sock, option, optval, optlen);
00102
00103   else if (level == socket->so_proto && level == IPPROTO_UDP)
00104      rc = set_udp_opt (socket->udp_sock, option, optval, optlen);
00105
00106   else if ((level == socket->so_proto && level == IPPROTO_IP)   ||
00107            (level == socket->so_proto && level == IPPROTO_ICMP) ||
00108            socket->so_proto == IPPROTO_UDP)
00109      rc = set_raw_opt (socket, option, optval, optlen);
00110
00111   else
00112   {
00113     SOCK_ERRNO (ENOPROTOOPT);
00114     rc = -1;
00115   }
00116
00117   if (rc < 0)
00118      SOCK_DEBUGF ((", %s", short_strerror(_w32_errno)));
00119
00120   return (rc);
00121 }
00122
00123 int W32_CALL getsockopt (int s, int level, int option, void *optval, int *optlen)
00124 {
00125   Socket *socket = _socklist_find (s);
00126   int     rc;
00127
00128   SOCK_DEBUGF (("\ngetsockopt:%d, %s", s, sockopt_name(level,option)));
00129
00130   if (!socket)
00131   {
00132     if (_sock_dos_fd(s))
00133     {
00134       SOCK_DEBUGF ((", ENOTSOCK"));
00135       SOCK_ERRNO (ENOTSOCK);
00136       return (-1);
00137     }
00138     SOCK_DEBUGF ((", EBADF"));
00139     SOCK_ERRNO (EBADF);
00140     return (-1);
00141   }
00142
00143   VERIFY_RW (optlen, sizeof(u_long));
00144   VERIFY_RW (optval, *optlen);
00145
00146   if ((WORD)level == SOL_SOCKET)
00147      rc = get_sol_opt (socket, option, optval, optlen);
00148
00149 #if 0
00150   else if ((WORD)level == SOL_PACKET)
00151      rc = get_packet_opt (socket, option, optval, optlen);
00152 #endif
00153
00154   else if (level == socket->so_proto && level == IPPROTO_TCP)
00155      rc = get_tcp_opt (socket->tcp_sock, option, optval, optlen);
00156
00157   else if (level == socket->so_proto && level == IPPROTO_UDP)
00158      rc = get_udp_opt (socket->udp_sock, option, optval, optlen);
00159
00160   else if ((level == socket->so_proto && level == IPPROTO_IP)   ||
00161            (level == socket->so_proto && level == IPPROTO_ICMP) ||
00162            socket->so_proto == IPPROTO_UDP)
00163      rc = get_raw_opt (socket, option, optval, optlen);
00164
00165   else
00166   {
00167     SOCK_ERRNO (ENOPROTOOPT);
00168     rc = -1;
00169   }
00170
00171   if (rc < 0)
00172      SOCK_DEBUGF ((", %s", short_strerror(_w32_errno)));
00173
00174   return (rc);
00175 }
00176
00177
00178 static int set_sol_opt (Socket *s, int opt, const void *val, unsigned len)
00179 {
00180   struct timeval *tv   = (struct timeval*) val;
00181   int             on   = *(int*) val;
00182   DWORD           size = (len >= 4) ? *(DWORD*)val :
00183                          (len >= 2) ? *(WORD*)val  :
00184                          (len >= 1) ? *(BYTE*)val  : 0U;
00185   switch (opt)
00186   {
00187     case SO_DEBUG:
00188     case SO_ACCEPTCONN:
00189          if (on)
00190               s->so_options |=  opt;
00191          else s->so_options &= ~opt;
00192          SOCK_DEBUGF ((" %d", s->so_options & opt));
00193          break;
00194
00195     case SO_RCVTIMEO:
00196          if (len != sizeof(*tv) || tv->tv_usec < 0)
00197          {
00198            SOCK_ERRNO (EINVAL);
00199            return (-1);
00200          }
00201          if (tv->tv_sec == 0)        /* i.e. use system default */
00202               s->timeout = sock_delay;
00203          else s->timeout = tv->tv_sec + tv->tv_usec/1000000UL;
00204          SOCK_DEBUGF ((" %d", s->timeout));
00205          break;
00206
00207     case SO_SNDTIMEO:    /* Don't think we need this */
00208          break;
00209
00210     /*
00211      * SO_REUSEADDR enables local address reuse. E.g. used to bind
00212      * multiple sockets to the same port but with different ip-addr.
00213      */
00214     case SO_REUSEADDR:
00215          if (s->tcp_sock && s->so_proto == IPPROTO_TCP)
00216          {
00217            /* This is meaningless unless a local port is bound.
00218             * myport is 0 before a connect() is done.
00219             */
00220            reuse_localport (s->tcp_sock->myport);
00221            return (0);
00222          }
00223          if (s->udp_sock && s->so_proto == IPPROTO_UDP)
00224          {
00225            reuse_localport (s->udp_sock->myport);
00226            return (0);
00227          }
00228          SOCK_ERRNO (ENOPROTOOPT);
00229          return (-1);
00230
00231     /*
00232      * SO_REUSEPORT enables duplicate address and port bindings
00233      * ie, one can bind multiple socks to the same <ip_addr.port> pair
00234      */
00235 /*  case SO_REUSEPORT:  missing in BSD? */
00236     case SO_DONTROUTE:
00237     case SO_BROADCAST:
00238     case SO_USELOOPBACK:
00239     case SO_OOBINLINE:
00240          break;
00241
00242     case SO_DONTLINGER:
00243          s->linger_time = 0;
00244          s->linger_on   = 0;
00245          s->tcp_sock->locflags &= ~LF_LINGER;
00246          break;
00247
00248     case SO_KEEPALIVE:
00249          if (on)
00250               s->so_options |=  SO_KEEPALIVE;
00251          else s->so_options &= ~SO_KEEPALIVE;
00252          SOCK_DEBUGF ((" %d", s->so_options & SO_KEEPALIVE));
00253          break;
00254
00255     case SO_SNDLOWAT:
00256          return set_tx_lowat (s, size);
00257
00258     case SO_RCVLOWAT:
00259          return set_rx_lowat (s, size);
00260
00261     case SO_RCVBUF:
00262          if (size == 0)
00263          {
00264            SOCK_ERRNO (EINVAL);
00265            return (-1);
00266          }
00267          if (s->udp_sock && s->so_proto == IPPROTO_UDP)
00268             return set_recv_buf ((sock_type*)s->udp_sock, size, FALSE);
00269
00270          if (s->tcp_sock && s->so_proto == IPPROTO_TCP)
00271             return set_recv_buf ((sock_type*)s->tcp_sock, size, TRUE);
00272
00273          if (s->raw_sock)
00274             return raw_rx_buf (s->raw_sock, size);
00275
00276          if (s->raw6_sock)
00277             return raw6_rx_buf (s->raw6_sock, size);
00278
00279          SOCK_ERRNO (ENOPROTOOPT);
00280          return (-1);
00281
00282     case SO_SNDBUF:
00283          if (size == 0)
00284          {
00285            SOCK_ERRNO (EINVAL);
00286            return (-1);
00287          }
00288          if (s->udp_sock && s->so_proto == IPPROTO_UDP)
00289             return set_xmit_buf ((sock_type*)s->udp_sock, size, FALSE);
00290
00291          if (s->tcp_sock && s->so_proto == IPPROTO_TCP)
00292             return set_xmit_buf ((sock_type*)s->tcp_sock, size, TRUE);
00293
00294          if (s->raw_sock)
00295             return raw_tx_buf (s->raw_sock, size);
00296
00297          if (s->raw6_sock)
00298             return raw6_tx_buf (s->raw6_sock, size);
00299
00300          SOCK_ERRNO (ENOPROTOOPT);
00301          return (-1);
00302
00303     case SO_LINGER:
00304          {
00305            struct linger *linger = (struct linger*) val;
00306
00307            if (len < sizeof(*linger))
00308            {
00309              SOCK_ERRNO (EINVAL);
00310              return (-1);
00311            }
00312
00313            if (s->so_type != SOCK_STREAM || !s->tcp_sock)
00314            {
00315              SOCK_ERRNO (ENOPROTOOPT);
00316              return (-1);
00317            }
00318
00319            if (linger->l_onoff == 0 && linger->l_linger == 0)
00320            {
00321              s->linger_time = 0;
00322              s->linger_on   = 0;
00323              s->tcp_sock->locflags &= ~LF_LINGER;
00324            }
00325            else if (linger->l_onoff /* && linger->l_linger > 0 */ )
00326            {
00327              unsigned sec = TCP_LINGERTIME;
00328
00329              if (linger->l_linger < 100 * TCP_LINGERTIME)
00330                 sec = linger->l_linger / 100;  /* in 10ms units */
00331
00332              s->linger_time = sec;
00333              s->linger_on   = 1;
00334              s->tcp_sock->locflags |= LF_LINGER;
00335            }
00336            s->so_options |= SO_LINGER;
00337          }
00338          break;
00339
00340     default:
00341          SOCK_ERRNO (ENOPROTOOPT);
00342          return (-1);
00343   }
00344   return (0);
00345 }
00346
00347
00348 static int get_sol_opt (Socket *s, int opt, void *val, int *len)
00349 {
00350   struct timeval *tv;
00351   unsigned       *size = (unsigned*)val;
00352
00353   switch (opt)
00354   {
00355     case SO_DEBUG:
00356     case SO_ACCEPTCONN:
00357          *(int*)val = (s->so_options & opt);
00358          *len = sizeof(int);
00359          break;
00360 #if 0
00361     case SO_OOBINLINE:
00362          if (!s->tcp_sock || s->so_proto != IPPROTO_TCP)
00363          {
00364            SOCK_ERRNO (ENOPROTOOPT);
00365            return (-1);
00366          }
00367          if (s->so_options & SO_OOBINLINE)
00368               *(int*)val = urgent_data ((sock_type*)s->tcp_sock);
00369          else *(int*)val = 0;
00370          break;
00371 #endif
00372
00375     case SO_REUSEADDR:
00376     case SO_DONTROUTE:
00377     case SO_BROADCAST:
00378     case SO_USELOOPBACK:
00379          break;
00380
00381     case SO_DONTLINGER:
00382          *(int*)val = !(s->tcp_sock->locflags & LF_LINGER);
00383          break;
00384
00385     case SO_KEEPALIVE:
00386          if (s->so_options & SO_KEEPALIVE)
00387          {
00388            *(int*)val = tcp_keep_idle;
00389            *len = sizeof(tcp_keep_idle);
00390          }
00391          else
00392          {
00393            *(int*)val = 0;
00394            *len = 0;
00395          }
00396          break;
00397
00398     case SO_SNDLOWAT:
00399          return get_tx_lowat (s, size);
00400
00401     case SO_RCVLOWAT:
00402          return get_rx_lowat (s, size);
00403
00404     case SO_RCVBUF:
00405          if (s->udp_sock && s->so_proto == IPPROTO_UDP)
00406          {
00407            *(int*)val = sock_rbsize ((sock_type*)s->udp_sock);
00408            return (0);
00409          }
00410          if (s->tcp_sock && s->so_proto == IPPROTO_TCP)
00411          {
00412            *(int*)val = sock_rbsize ((sock_type*)s->tcp_sock);
00413            return (0);
00414          }
00415          if (s->raw_sock)
00416          {
00417            *(size_t*)val = sizeof (s->raw_sock->rx_data);
00418            return (0);
00419          }
00420          SOCK_ERRNO (ENOPROTOOPT);
00421          return (-1);
00422
00423     case SO_SNDBUF:
00424          if (s->udp_sock && s->so_proto == IPPROTO_UDP)
00425          {
00426            *(unsigned*)val = 0;  /* UDP doesn't have a Tx-buffer */
00427            return (0);
00428          }
00429          if (s->tcp_sock && s->so_proto == IPPROTO_TCP)
00430          {
00431            *(unsigned*)val = sock_tbsize ((sock_type*)s->tcp_sock);
00432            return (0);
00433          }
00434          if (s->raw_sock)
00435          {
00436            *(unsigned*)val = _mtu;
00437            return (0);
00438          }
00439          SOCK_ERRNO (ENOPROTOOPT);
00440          return (-1);
00441
00442     case SO_LINGER:
00443          {
00444            struct linger *linger = (struct linger*) val;
00445
00446            if (!len || *len < SIZEOF(*linger))
00447            {
00448              SOCK_ERRNO (EINVAL);
00449              return (-1);
00450            }
00451            if (s->so_type != SOCK_STREAM || !s->tcp_sock)
00452            {
00453              SOCK_ERRNO (ENOPROTOOPT);
00454              return (-1);
00455            }
00456            *len = SIZEOF(*linger);
00457            linger->l_onoff  = (s->tcp_sock->locflags & LF_LINGER) ? 1 : 0;
00458            linger->l_linger = 100 * s->linger_time;
00459            SOCK_DEBUGF ((", linger %d, %s",
00460                          linger->l_linger, linger->l_onoff ? "on" : "off"));
00461          }
00462          break;
00463
00464     case SO_SNDTIMEO:
00465          break;
00466
00467     case SO_RCVTIMEO:
00468          if (*len < SIZEOF(*tv))
00469          {
00470            SOCK_ERRNO (EINVAL);
00471            return (-1);
00472          }
00473          tv = (struct timeval*)val;
00474          if (s->timeout == 0)
00475          {
00476            tv->tv_usec = LONG_MAX;
00477            tv->tv_sec  = LONG_MAX;
00478          }
00479          else
00480          {
00481            tv->tv_usec = 0;
00482            tv->tv_sec  = s->timeout;
00483          }
00484          SOCK_DEBUGF ((", timeout %lu.%06ld", (DWORD)tv->tv_sec, tv->tv_usec));
00485          break;
00486
00487     case SO_ERROR:
00488          *(int*)val = s->so_error;
00489          *len = SIZEOF(s->so_error);
00490          SOCK_DEBUGF ((", val %d=%s",
00491                       s->so_error, short_strerror(s->so_error)));
00492          s->so_error = 0;   /* !! should be do this */
00493          break;
00494
00495  /* case SO_STYLE: GNU libc name */
00496     case SO_TYPE:
00497          *(int*)val = s->so_type;
00498          *len = SIZEOF(s->so_type);
00499          SOCK_DEBUGF ((", type %d", s->so_type));
00500          break;
00501
00502     default:
00503          SOCK_ERRNO (ENOPROTOOPT);
00504          return (-1);
00505   }
00506   SOCK_ERRNO (0);
00507   return (0);
00508 }
00509
00510 /*
00511  * set/get TCP-layer options
00512  */
00513 static int set_tcp_opt (_tcp_Socket *tcp, int opt, const void *val, int len)
00514 {
00515   BOOL on = *(BOOL*)val;
00516   UINT MSS;
00517
00518   switch (opt)
00519   {
00520     case TCP_NODELAY:
00521          if (on)   /* disable Nagle's algorithm */
00522               tcp->sockmode &= ~SOCK_MODE_NAGLE;
00523          else tcp->sockmode |= SOCK_MODE_NAGLE;
00524          break;
00525
00526     case TCP_MAXSEG:
00527          MSS = *(DWORD*)val;
00528          MSS = max (MSS, MSS_MIN);
00529          MSS = min (MSS, MSS_MAX);
00530          tcp->max_seg = MSS;
00531          break;
00532
00533     case TCP_NOPUSH:
00534          if (on)
00535               tcp->locflags |=  LF_NOPUSH;
00536          else tcp->locflags &= ~LF_NOPUSH;
00537          break;
00538
00539     case TCP_NOOPT:
00540          if (on)
00541               tcp->locflags |=  LF_NOOPT;
00542          else tcp->locflags &= ~LF_NOOPT;
00543          break;
00544
00545     default:
00546          SOCK_ERRNO (ENOPROTOOPT);
00547          return (-1);
00548   }
00549   ARGSUSED (len);
00550   return (0);
00551 }
00552
00553 static int get_tcp_opt (_tcp_Socket *tcp, int opt, void *val, int *len)
00554 {
00555   switch (opt)
00556   {
00557     case TCP_NODELAY:
00558          if (tcp->sockmode & SOCK_MODE_NAGLE)
00559               *(int*)val = 0;
00560          else *(int*)val = TCP_NODELAY;
00561          *len = SIZEOF(int);
00562          break;
00563
00564     case TCP_MAXSEG:
00565          *(int*)val = tcp->max_seg;
00566          *len = SIZEOF(int);
00567          break;
00568
00569     case TCP_NOPUSH:
00570          *(int*)val = (tcp->locflags & LF_NOPUSH);
00571          *len = SIZEOF(tcp->locflags);
00572          break;
00573
00574     case TCP_NOOPT:
00575          *(int*)val = (tcp->locflags & LF_NOOPT);
00576          *len = SIZEOF(tcp->locflags);
00577          break;
00578
00579     default:
00580          SOCK_ERRNO (ENOPROTOOPT);
00581          return (-1);
00582   }
00583   return (0);
00584 }
00585
00586 /*
00587  * set/get UDP-layer options
00588  */
00589 static int set_udp_opt (_udp_Socket *udp, int opt, const void *val, int len)
00590 {
00591   ARGSUSED (udp);      /* no udp option support yet */
00592   ARGSUSED (opt);
00593   ARGSUSED (val);
00594   ARGSUSED (len);
00595   SOCK_ERRNO (ENOPROTOOPT);
00596   return (-1);
00597 }
00598
00599
00600 static int get_udp_opt (_udp_Socket *udp, int opt, void *val, int *len)
00601 {
00602   ARGSUSED (udp);    /* no udp option support yet */
00603   ARGSUSED (opt);
00604   ARGSUSED (val);
00605   ARGSUSED (len);
00606   SOCK_ERRNO (ENOPROTOOPT);
00607   return (-1);
00608 }
00609
00610 /*
00611  * set/get IP/ICMP-layer (raw/multicast) options
00612  */
00613 static int set_raw_opt (Socket *s, int opt, const void *val, int len)
00614 {
00615 #ifdef USE_MULTICAST
00616   struct ip_mreq *mc_req;
00617   DWORD  ip;
00618 #endif
00619   BOOL on = *(BOOL*)val;
00620
00621   switch (opt)
00622   {
00623     case IP_OPTIONS:
00624          if (!s->ip_opt &&
00625              (s->ip_opt = SOCK_CALLOC (sizeof(*s->ip_opt))) == NULL)
00626          {
00627            SOCK_ERRNO (ENOMEM);
00628            return (-1);
00629          }
00630          if (len == 0 && s->ip_opt)
00631          {
00632            free (s->ip_opt);
00633            s->ip_opt     = NULL;
00634            s->ip_opt_len = 0;
00635          }
00636          else
00637          {
00638            s->ip_opt_len = min ((unsigned)len, sizeof(*s->ip_opt));
00639            if (len > 0)
00640               memcpy (&s->ip_opt->IP_opts[0], val, s->ip_opt_len);
00641          }
00642          break;
00643
00644     case IP_HDRINCL:
00645          if (on)
00646               s->inp_flags |=  INP_HDRINCL;
00647          else s->inp_flags &= ~INP_HDRINCL;
00648          break;
00649
00650     case IP_TOS:
00651          s->ip_tos = *(int*)val;
00652          if (s->tcp_sock)
00653              s->tcp_sock->tos = s->ip_tos;
00654          else if (s->raw_sock)
00655             s->raw_sock->ip.tos = s->ip_tos;
00656          break;
00657
00658     case IP_TTL:
00659     case IP_MULTICAST_TTL:
00660          s->ip_ttl = *(BYTE*)val;
00661          s->ip_ttl = max (1, s->ip_ttl);
00662          if (s->udp_sock)
00663             s->udp_sock->ttl = s->ip_ttl;
00664          else if (s->tcp_sock)
00665             s->tcp_sock->ttl = s->ip_ttl;
00666          else if (s->raw_sock)
00667             s->raw_sock->ip.ttl = s->ip_ttl;
00668          break;
00669
00670     case IP_ADD_MEMBERSHIP:
00671     case IP_DROP_MEMBERSHIP:
00672 #ifdef USE_MULTICAST
00673          _multicast_on = TRUE;
00674          mc_req = (struct ip_mreq*)val;
00675          if (!mc_req || len < SIZEOF(*mc_req))
00676          {
00677            SOCK_ERRNO (EINVAL);
00678            return (-1);
00679          }
00680          ip = ntohl (mc_req->imr_multiaddr.s_addr);
00681          if (!_ip4_is_multicast(ip))
00682          {
00683            SOCK_ERRNO (EINVAL);
00684            return (-1);
00685          }
00686          if (opt == IP_ADD_MEMBERSHIP && !join_mcast_group(ip))
00687          {
00688            SOCK_ERRNO (ENOBUFS);        /* !!correct errno? */
00689            return (-1);
00690          }
00691          if (opt == IP_DROP_MEMBERSHIP && !leave_mcast_group(ip))
00692          {
00693            SOCK_ERRNO (EADDRNOTAVAIL);  /* !!correct errno? */
00694            return (-1);
00695          }
00696 #endif
00697          break;
00698
00699     case IP_MULTICAST_IF:
00700     case IP_MULTICAST_LOOP:
00701     case IP_MULTICAST_VIF:
00702          _multicast_on = TRUE;
00703          break;
00704
00705     case IP_RECVOPTS:
00706     case IP_RECVRETOPTS:
00707     case IP_RECVDSTADDR:
00708     case IP_RETOPTS:
00709     case IP_RSVP_ON:
00710     case IP_RSVP_OFF:
00711     case IP_RSVP_VIF_ON:
00712     case IP_RSVP_VIF_OFF:
00713     case IP_PORTRANGE:
00714     case IP_RECVIF:
00715          break;
00716
00717     default:
00718          SOCK_ERRNO (ENOPROTOOPT);
00719          return (-1);
00720   }
00721   return (0);
00722 }
00723
00724 static int get_raw_opt (Socket *s, int opt, void *val, int *len)
00725 {
00726   switch (opt)
00727   {
00728     case IP_OPTIONS:
00729          if (s->ip_opt)
00730          {
00731            *len = (int)s->ip_opt_len;
00732            memcpy (val, &s->ip_opt->IP_opts[0], *len);
00733          }
00734          else
00735          {
00736            memset (val, 0, *len);
00737            *len = 0;
00738          }
00739          break;
00740
00741     case IP_HDRINCL:
00742          *(int*)val = (s->inp_flags & INP_HDRINCL);
00743          *len = sizeof(int);
00744          break;
00745
00746     case IP_TOS:
00747          *(int*)val = s->ip_tos;
00748          *len = sizeof(int);
00749          break;
00750
00751     case IP_TTL:
00752     case IP_MULTICAST_TTL:
00753          *(BYTE*)val = s->ip_ttl;
00754          *len = 1;
00755          break;
00756
00757     case IP_RECVOPTS:
00758     case IP_RECVRETOPTS:
00759     case IP_RECVDSTADDR:
00760     case IP_RETOPTS:
00761     case IP_RSVP_ON:
00762     case IP_RSVP_OFF:
00763     case IP_RSVP_VIF_ON:
00764     case IP_RSVP_VIF_OFF:
00765     case IP_PORTRANGE:
00766     case IP_RECVIF:
00767          break;
00768
00769     case IP_ADD_MEMBERSHIP:
00770     case IP_DROP_MEMBERSHIP:
00771     case IP_MULTICAST_IF:
00772          _multicast_on = TRUE;
00773          break;
00774
00775     case IP_MULTICAST_LOOP:
00776          _multicast_on = TRUE;
00777          *(BYTE*)val = 0;
00778          *len = 1;
00779          break;
00780
00781     case IP_MULTICAST_VIF:
00782          _multicast_on = TRUE;
00783          break;
00784
00785     default:
00786          SOCK_ERRNO (ENOPROTOOPT);
00787          return (-1);
00788   }
00789   return (0);
00790 }
00791
00792 /*
00793  * Set receive buffer size for UDP/TCP. Since sock_setbuf() handles
00794  * maxiumum 64kB, we do the same here.
00795  * Maximum size accepted for TCP is '64k * (2 << TCP_MAX_WINSHIFT)' = 1MByte.
00796  * Minimum size is 1 byte.
00797  */
00798 static int set_recv_buf (sock_type *s, DWORD size, BOOL is_tcp)
00799 {
00800   BYTE  *buf;
00801   DWORD  len;
00802   DWORD  max = is_tcp ? MAX_TCP_RECV_BUF : MAX_UDP_RECV_BUF;
00803
00804   if (s->tcp.rx_data == &s->tcp.rx_buf[0])
00805        buf = NULL;
00806   else buf = s->tcp.rx_data-4;
00807
00808   size = min (size, max);  /* 64kB/1MB */
00809   buf  = (BYTE*) realloc (buf, size+8);
00810   if (!buf)
00811   {
00812     SOCK_ERRNO (ENOMEM);
00813     return (-1);
00814   }
00815
00816   /* Copy the data to new buffer. Data might be overlapping
00817    * hence using memmove(). Add front/back markers.
00818    */
00819   if (s->tcp.rx_datalen > 0)
00820   {
00821     len = min ((long)size-8, s->tcp.rx_datalen);
00822     memmove (buf+4, s->tcp.rx_data, len);
00823   }
00824   *(DWORD*)buf          = SAFETY_TCP;
00825   *(DWORD*)(buf+4+size) = SAFETY_TCP;
00826   s->tcp.rx_data     = buf + 4;
00827   s->tcp.max_rx_data = size - 1;
00828
00829   if (is_tcp && size > USHRT_MAX)
00830      s->tcp.tx_wscale = (BYTE) (size >> 16);  /* not yet */
00831
00832   SOCK_DEBUGF ((" %lu", size));
00833   return (0);
00834 }
00835
00836 /*
00837  * Set transmit buffer size for UDP/TCP.
00838  * Max size accepted is 'max'.
00839  * size == 0 is legal, but how should we handle that?
00840  */
00841 static int set_xmit_buf (sock_type *s, DWORD size, BOOL is_tcp)
00842 {
00843 #if 0 /* not yet */
00844   BYTE  *buf;
00845   DWORD  max = is_tcp ? MAX_TCP_SEND_BUF : MAX_UDP_SEND_BUF;
00846   size_t len;
00847
00848   size = min (size, max);
00849   buf  = realloc (s->tcp.tx_data, size);
00850   if (!buf)
00851   {
00852     SOCK_ERRNO (ENOMEM);
00853     return (-1);
00854   }
00855
00856   /* Copy current data to new buffer. Data might be overlapping
00857    * hence using memmove(). Add front/back markers.
00858    */
00859   if (s->tcp.tx_datalen > 0)
00860   {
00861     len = min ((long)size-8, s->tcp.tx_datalen);
00862     memmove (buf+4, s->tcp.tx_data, len);
00863   }
00864   *(DWORD*)buf          = SAFETY_TCP;
00865   *(DWORD*)(buf+size-4) = SAFETY_TCP;
00866   s->tcp.tx_data    = buf + 4;
00867   s->tcp.maxdatalen = size - (4+4+1);
00868   SOCK_DEBUGF ((" %lu", size));
00869 #else
00870   ARGSUSED (s);
00871   ARGSUSED (size);
00872   ARGSUSED (is_tcp);
00873 #endif
00874   return (0);
00875 }
00876
00877 /*
00878  * Set receive buffer size for RAW socket
00879  */
00880 static int raw_rx_buf (_raw_Socket *raw, DWORD size)
00881 {
00883   SOCK_DEBUGF ((" %lu unsupported", size));
00884   ARGSUSED (raw);
00885   ARGSUSED (size);
00886   return (0);
00887 }
00888
00889 static int raw6_rx_buf (_raw6_Socket *raw, DWORD size)
00890 {
00892   SOCK_DEBUGF ((" %lu unsupported", size));
00893   ARGSUSED (raw);
00894   ARGSUSED (size);
00895   return (0);
00896 }
00897
00898 static int raw_tx_buf (_raw_Socket *raw, DWORD size)
00899 {
00901   SOCK_DEBUGF ((" %lu unsupported", size));
00902   ARGSUSED (raw);
00903   ARGSUSED (size);
00904   return (0);
00905 }
00906
00907 static int raw6_tx_buf (_raw6_Socket *raw, DWORD size)
00908 {
00910   SOCK_DEBUGF ((" %lu unsupported", size));
00911   ARGSUSED (raw);
00912   ARGSUSED (size);
00913   return (0);
00914 }
00915
00916
00917 /*
00918  * Set send buffer "low water marks"; x >= 0, x < send-size.
00919  */
00920 static int set_tx_lowat (Socket *sock, unsigned size)
00921 {
00922   switch (sock->so_type)
00923   {
00924     case SOCK_STREAM:
00925          sock->send_lowat = min (size, MAX_TCP_SEND_BUF-1);
00926          break;
00927     case SOCK_DGRAM:
00928          sock->send_lowat = min (size, MAX_UDP_SEND_BUF-1);
00929          break;
00930     case SOCK_RAW:
00931          sock->send_lowat = min (size, _mtu);
00932          break;
00933     default:
00934          SOCK_ERRNO (ENOPROTOOPT);
00935          return (-1);
00936   }
00937   return (0);
00938 }
00939
00940 /*
00941  * Set receive buffer "low water marks"; x >= 0, x < recv-size.
00942  */
00943 static int set_rx_lowat (Socket *sock, unsigned size)
00944 {
00945   switch (sock->so_type)
00946   {
00947     case SOCK_STREAM:
00948          if (sock->tcp_sock)
00949             sock->recv_lowat = min (size, sock->tcp_sock->max_rx_data-1);
00950          break;
00951     case SOCK_DGRAM:
00952          if (sock->udp_sock)
00953             sock->recv_lowat = min (size, sock->udp_sock->max_rx_data-1);
00954          break;
00955     case SOCK_RAW:
00956          sock->recv_lowat = min (size, sizeof(sock->raw_sock->rx_data)-1);
00957          break;
00958     default:
00959          SOCK_ERRNO (ENOPROTOOPT);
00960          return (-1);
00961   }
00962   return (0);
00963 }
00964
00965 /*
00966  * Get receive/transmit buffer "low water marks"
00967  */
00968 static int get_tx_lowat (const Socket *sock, unsigned *size)
00969 {
00970   if (sock->so_type == SOCK_STREAM ||
00971       sock->so_type == SOCK_DGRAM  ||
00972       sock->so_type == SOCK_RAW)
00973   {
00974     *size = sock->send_lowat;
00975     return (0);
00976   }
00977   SOCK_ERRNO (ENOPROTOOPT);
00978   return (-1);
00979 }
00980
00981 static int get_rx_lowat (const Socket *sock, unsigned *size)
00982 {
00983   if (sock->so_type == SOCK_STREAM ||
00984       sock->so_type == SOCK_DGRAM  ||
00985       sock->so_type == SOCK_RAW)
00986   {
00987     *size = sock->recv_lowat;
00988     return (0);
00989   }
00990   SOCK_ERRNO (ENOPROTOOPT);
00991   return (-1);
00992 }
00993
00994 #if defined(USE_DEBUG)
00995 /*
00996  * Handle printing of option names
00997  */
00998 static const struct search_list sol_options[] = {
00999                   { SO_DEBUG,       "SO_DEBUG"       },
01000                   { SO_ACCEPTCONN,  "SO_ACCEPTCONN"  },
01001                   { SO_REUSEADDR,   "SO_REUSEADDR"   },
01002                   { SO_KEEPALIVE,   "SO_KEEPALIVE"   },
01003                   { SO_DONTROUTE,   "SO_DONTROUTE"   },
01004                   { SO_BROADCAST,   "SO_BROADCAST"   },
01005                   { SO_USELOOPBACK, "SO_USELOOPBACK" },
01006                   { SO_LINGER,      "SO_LINGER"      },
01007                   { SO_OOBINLINE,   "SO_OOBINLINE"   },
01008                   { SO_SNDBUF,      "SO_SNDBUF"      },
01009                   { SO_RCVBUF,      "SO_RCVBUF"      },
01010                   { SO_SNDLOWAT,    "SO_SNDLOWAT"    },
01011                   { SO_RCVLOWAT,    "SO_RCVLOWAT"    },
01012                   { SO_SNDTIMEO,    "SO_SNDTIMEO"    },
01013                   { SO_RCVTIMEO,    "SO_RCVTIMEO"    },
01014                   { SO_ERROR,       "SO_ERROR"       },
01015                   { SO_TYPE,        "SO_TYPE"        }
01016                 };
01017
01018 static const struct search_list tcp_options[] = {
01019                   { TCP_NODELAY, "TCP_NODELAY" },
01020                   { TCP_MAXSEG,  "TCP_MAXSEG"  },
01021                   { TCP_NOPUSH,  "TCP_NOPUSH"  },
01022                   { TCP_NOOPT,   "TCP_NOOPT"   }
01023                 };
01024
01025 static const struct search_list ip_options[] = {
01026                   { IP_OPTIONS,        "IP_OPTIONS"         },
01027                   { IP_HDRINCL,        "IP_HDRINCL"         },
01028                   { IP_TOS,            "IP_TOS"             },
01029                   { IP_TTL,            "IP_TTL"             },
01030                   { IP_RECVOPTS,       "IP_RECVOPTS"        },
01031                   { IP_RECVRETOPTS,    "IP_RECVRETOPTS"     },
01032                   { IP_RECVDSTADDR,    "IP_RECVDSTADDR"     },
01033                   { IP_RETOPTS,        "IP_RETOPTS"         },
01034                   { IP_MULTICAST_IF,   "IP_MULTICAST_IF"    },
01035                   { IP_MULTICAST_TTL,  "IP_MULTICAST_TTL"   },
01036                   { IP_MULTICAST_LOOP, "IP_MULTICAST_LOOP"  },
01037                   { IP_ADD_MEMBERSHIP, "IP_ADD_MEMBERSHIP"  },
01038                   { IP_DROP_MEMBERSHIP,"IP_DROP_MEMBERSHIP" },
01039                   { IP_MULTICAST_VIF,  "IP_MULTICAST_VIF"   },
01040                   { IP_RSVP_ON,        "IP_RSVP_ON"         },
01041                   { IP_RSVP_OFF,       "IP_RSVP_OFF"        },
01042                   { IP_RSVP_VIF_ON,    "IP_RSVP_VIF_ON"     },
01043                   { IP_RSVP_VIF_OFF,   "IP_RSVP_VIF_OFF"    },
01044                   { IP_PORTRANGE,      "IP_PORTRANGE"       },
01045                   { IP_RECVIF,         "IP_RECVIF"          },
01046                   { IP_FW_ADD,         "IP_FW_ADD"          },
01047                   { IP_FW_DEL,         "IP_FW_DEL"          },
01048                   { IP_FW_FLUSH,       "IP_FW_FLUSH"        },
01049                   { IP_FW_ZERO,        "IP_FW_ZERO"         },
01050                   { IP_FW_GET,         "IP_FW_GET"          },
01051                   { IP_NAT,            "IP_NAT"             }
01052                 };
01053
01054
01055 static const char *sockopt_name (int level, int option)
01056 {
01057   switch ((DWORD)level)
01058   {
01059     case SOL_SOCKET:
01060          return list_lookup (option, sol_options, DIM(sol_options));
01061
01062     case IPPROTO_UDP:
01063          return ("udp option!?");
01064
01065     case IPPROTO_TCP:
01066          return list_lookup (option, tcp_options, DIM(tcp_options));
01067
01068     case IPPROTO_IP:
01069     case IPPROTO_ICMP:
01070          return list_lookup (option, ip_options, DIM(ip_options));
01071
01072     default:
01073          return ("invalid level?");
01074   }
01075 }
01076 #endif  /* USE_DEBUG    */
01077 #endif  /* USE_BSD_API */
Generated on Wed Jan 25 15:42:39 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/SPLIT.C Source File

SRC/SPLIT.C

Go to the documentation of this file.
00001
00006 /*  Copyright (c) 1997-2002 Gisle Vanem <giva@bgnett.no>
00007  *
00008  *  Redistribution and use in source and binary forms, with or without
00009  *  modification, are permitted provided that the following conditions
00010  *  are met:
00011  *  1. Redistributions of source code must retain the above copyright
00012  *     notice, this list of conditions and the following disclaimer.
00013  *  2. Redistributions in binary form must reproduce the above copyright
00014  *     notice, this list of conditions and the following disclaimer in the
00015  *     documentation and/or other materials provided with the distribution.
00016  *  3. All advertising materials mentioning features or use of this software
00017  *     must display the following acknowledgement:
00018  *       This product includes software developed by Gisle Vanem
00019  *       Bergen, Norway.
00020  *
00021  *  THIS SOFTWARE IS PROVIDED BY ME (Gisle Vanem) AND CONTRIBUTORS ``AS IS''
00022  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00023  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00024  *  ARE DISCLAIMED.  IN NO EVENT SHALL I OR CONTRIBUTORS BE LIABLE FOR ANY
00025  *  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00026  *  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00027  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00028  *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00029  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00030  *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00031  *
00032  *  G. Vanem <giva@bgnett.no> 2002
00033  */
00034
00035 #include <stdio.h>
00036 #include <stdlib.h>
00037
00038 #include "wattcp.h"
00039 #include "pcsed.h"
00040 #include "pcpkt.h"
00041 #include "pppoe.h"
00042 #include "ppp.h"
00043 #include "misc.h"
00044 #include "strings.h"
00045 #include "bsddbug.h"
00046 #include "ip6_in.h"
00047 #include "split.h"
00048
00049 #if defined(NEED_PKT_SPLIT)
00050
00051 #define MARKER     0xDEAFABBA
00052 #define MAX_SPLITS 10
00053
00054 static struct pkt_split split_list_in [MAX_SPLITS];
00055 static struct pkt_split split_list_out[MAX_SPLITS];
00056
00057 static void split_mac (struct pkt_split *, const void *);
00058 static void split_ip4 (struct pkt_split *, const in_Header *);
00059 static void split_ip6 (struct pkt_split *, const in6_Header *);
00060
00061 const struct pkt_split *pkt_get_split_in (void)
00062 {
00063   WATT_ASSERT (*(DWORD*)&split_list_in[MAX_SPLITS-1] == MARKER);
00064   return (&split_list_in[0]);
00065 }
00066
00067 const struct pkt_split *pkt_get_split_out (void)
00068 {
00069   WATT_ASSERT (*(DWORD*)&split_list_out[MAX_SPLITS-1] == MARKER);
00070   return (&split_list_out[0]);
00071 }
00072
00073 const struct pkt_split *pkt_get_type_in (enum Components type)
00074 {
00075   const struct pkt_split *ps;
00076
00077   for (ps = pkt_get_split_in(); ps->data; ps++)
00078       if (type == ps->type)
00079          return (ps);
00080   return (NULL);
00081 }
00082
00083 const struct pkt_split *pkt_get_type_out (enum Components type)
00084 {
00085   const struct pkt_split *ps;
00086
00087   for (ps = pkt_get_split_out(); ps->data; ps++)
00088       if (type == ps->type)
00089          return (ps);
00090   return (NULL);
00091 }
00092
00093 const struct pkt_split *pkt_split_mac_in (const void *ptr)
00094 {
00095   *(DWORD*) &split_list_in[MAX_SPLITS-1] = MARKER;
00096   split_mac (&split_list_in[0], ptr);
00097   return (&split_list_in[0]);
00098 }
00099
00100 const struct pkt_split *pkt_split_mac_out (const void *ptr)
00101 {
00102   *(DWORD*) &split_list_out[MAX_SPLITS-1] = MARKER;
00103   split_mac (&split_list_out[0], ptr);
00104   return (&split_list_out[0]);
00105 }
00106
00107 static void split_mac (struct pkt_split *ps, const void *ptr)
00108 {
00109   const link_Packet *pkt = (const link_Packet*) ptr;
00110   const in_Header   *ip  = NULL;
00111   WORD  type = 0;
00112
00113   if (_pktserial)    /* SLIP/PPP/AX25 doesn't have MAC header */
00114   {
00115     ip = &pkt->ip.head;
00116     if (ip->ver == 6)
00117          split_ip6 (ps, (const in6_Header*)ip);
00118     else split_ip4 (ps, ip);
00119     return;
00120   }
00121
00122   if (_pktdevclass == PDCLASS_TOKEN)
00123   {
00124     const tok_Packet *tr = &pkt->tok;
00125
00126     ps->type = TYPE_TOKEN_HEAD;
00127     ps->data = pkt;
00128     ps->len  = sizeof(tok_Header);
00129
00130     ip   = (const in_Header*) &tr->data[0];
00131     type = tr->head.type;
00132   }
00133   else if (_pktdevclass == PDCLASS_FDDI)
00134   {
00135     const fddi_Packet *fddi = &pkt->fddi;
00136
00137     ps->type = TYPE_FDDI_HEAD;
00138     ps->data = pkt;
00139     ps->len  = sizeof(fddi_Header);
00140
00141     ip   = (const in_Header*) &fddi->data[0];
00142     type = fddi->head.type;
00143   }
00144   else if (_pktdevclass == PDCLASS_ARCNET)
00145   {
00146     const arcnet_Packet *arc = &pkt->arc;
00147
00148     ps->type = TYPE_ARCNET_HEAD;
00149     ps->data = pkt;
00150     ps->len  = ARC_HDRLEN;
00151
00152     ip   = (const in_Header*) ((BYTE*)arc + ARC_HDRLEN);
00153     type = arc->head.type;
00154   }
00155   else if (_pktdevclass == PDCLASS_ETHER)
00156   {
00157     ps->type = TYPE_ETHER_HEAD;
00158     ps->data = pkt;
00159     ps->len  = sizeof(eth_Header);
00160
00161     ip   = (const in_Header*) &pkt->eth.data[0];
00162     type = pkt->eth.head.type;
00163   }
00164
00165   if (type == IP4_TYPE)
00166   {
00167     ps++;
00168     split_ip4 (ps, ip);
00169     return;
00170   }
00171
00172   if (type == IP6_TYPE)
00173   {
00174     ps++;
00175     split_ip6 (ps, (const in6_Header*)ip);
00176     return;
00177   }
00178
00179   if (type == ARP_TYPE)
00180   {
00181     ps++;
00182     ps->type = TYPE_ARP;
00183     ps->data = &pkt->eth.data[0];
00184     ps->len  = sizeof(arp_Header);
00185   }
00186   else if (type == RARP_TYPE)
00187   {
00188     ps++;
00189     ps->type = TYPE_RARP;
00190     ps->data = &pkt->eth.data[0];
00191     ps->len  = sizeof(rarp_Header);
00192   }
00193   else if (type == PPPOE_DISC_TYPE)
00194   {
00195     pppoe_Packet *pppoe = (pppoe_Packet*)&pkt->eth.data[0];
00196
00197     ps++;
00198     ps->type = TYPE_PPPOE_DISC;
00199     ps->data = pppoe;
00200     ps->len  = intel16 (pppoe->length);
00201   }
00202   else if (type == PPPOE_SESS_TYPE)
00203   {
00204     const pppoe_Packet *pppoe = (const pppoe_Packet*)&pkt->eth.data[0];
00205     WORD                proto = intel16 (*(WORD*)&pppoe->data[0]);
00206
00207     ps++;
00208     ps->type = TYPE_PPPOE_SESS;
00209     ps->data = pppoe;
00210     ps->len  = PPPOE_HDR_SIZE;
00211     if (proto == intel16(PPP_IP))
00212     {
00213       ip = (const in_Header*)&pppoe->data[2];
00214       split_ip4 (++ps, ip);
00215       return;
00216     }
00217     if (proto == PPP_LCP)
00218     {
00219       const char *bp = (const char*) &pppoe->data[2];
00220       ps++;
00221       ps->type = TYPE_PPP_LCP;
00222       ps->data = bp;
00223       ps->len  = intel16 (*(WORD*)(bp+2));
00224     }
00225     else if (proto == PPP_IPCP)
00226     {
00227       const char *bp = (const char*) &pppoe->data[2];
00228       ps++;
00229       ps->type = TYPE_PPP_IPCP;
00230       ps->data = bp;
00231       ps->len  = intel16 (*(WORD*)(bp+2));
00232     }
00233   }
00234   else if (intel16(type) < ETH_MAX_DATA)   /* LLC unsupported */
00235   {
00236     ps++;
00237     ps->type = TYPE_LLC_HEAD;
00238     ps->len  = intel16 (type);
00239     ps->data = &pkt->eth.data[0];
00240   }
00241
00242   ps++;
00243   ps->data = NULL;
00244 }
00245
00246 static void split_ip4 (struct pkt_split *ps, const in_Header *ip4)
00247 {
00248   unsigned ip_len, ip_ofs, head_len;
00249   int      opt_len;
00250
00251   head_len = in_GetHdrLen (ip4);
00252   opt_len  = head_len - sizeof(*ip4);
00253   ip_ofs   = intel16 (ip4->frag_ofs);
00254   ip_ofs   = (ip_ofs & IP_OFFMASK) << 3;  /* 0 <= ip_ofs <= 65536-8 */
00255
00256   if (head_len < sizeof(*ip4))
00257      goto quit;
00258
00259   ps->type = TYPE_IP4;
00260   ps->len  = head_len;
00261   ps->data = ip4;
00262
00263   if (opt_len > 0)
00264   {
00265     ps++;
00266     ps->type = TYPE_IP4_OPTIONS;
00267     ps->data = (ip4 + 1);
00268     ps->len  = opt_len;
00269   }
00270
00271   if (ip_ofs)
00272   {
00273     ps++;
00274     ps->type = TYPE_IP4_FRAG;
00275     ps->data = (BYTE*)ip4 + head_len;
00276     ps->len  = intel16 (ip4->length) - head_len;
00277     goto quit;
00278   }
00279
00280   if (ip4->proto == ICMP_PROTO)
00281   {
00282     ps++;
00283     ps->type = TYPE_ICMP;
00284     ps->data = (BYTE*)ip4 + head_len;
00285     ps->len  = intel16 (ip4->length) - head_len;
00286   }
00287
00288   else if (ip4->proto == IGMP_PROTO)
00289   {
00290     ps++;
00291     ps->type = TYPE_IGMP;
00292     ps->data = (BYTE*)ip4 + head_len;
00293     ps->len  = intel16 (ip4->length) - head_len;
00294   }
00295
00296   else if (ip4->proto == UDP_PROTO)
00297   {
00298     const udp_Header *udp = (const udp_Header*) ((BYTE*)ip4 + head_len);
00299     unsigned          len = intel16 (udp->length) - sizeof(*udp);
00300
00301     ps++;
00302     ps->type = TYPE_UDP_HEAD;
00303     ps->data = (BYTE*)ip4 + head_len;
00304     ps->len  = sizeof (*udp);
00305     ps++;
00306     ps->type = TYPE_UDP_DATA;
00307     ps->data = (BYTE*)ip4 + head_len + sizeof(*udp);
00308     ps->len  = min (len, intel16(ip4->length) - head_len - sizeof(*udp));
00309   }
00310
00311   else if (ip4->proto == TCP_PROTO)
00312   {
00313     const tcp_Header *tcp = (const tcp_Header*) ((BYTE*)ip4 + head_len);
00314     unsigned          ofs = tcp->offset << 2;
00315     unsigned          dlen;
00316
00317     ip_len = intel16 (ip4->length) - sizeof(*ip4);
00318     ps++;
00319     ps->type = TYPE_TCP_HEAD;
00320     ps->data = tcp;
00321     ps->len  = sizeof (*tcp);
00322     if (ofs - sizeof(*tcp) > 0)
00323     {
00324       ps++;
00325       ps->type = TYPE_TCP_OPTIONS;
00326       ps->data = tcp + 1;
00327       ps->len  = ofs - sizeof(*tcp);
00328     }
00329     dlen = intel16 (ip4->length) - head_len - ofs;
00330     dlen = min (dlen, ip_len);
00331     ps++;
00332     ps->type = TYPE_TCP_DATA;
00333     ps->data = (const char*)tcp + ofs;
00334     ps->len  = dlen;   /* may be 0 */
00335   }
00336
00337 quit:
00338   ps++;
00339   ps->data = NULL;
00340 }
00341
00342 static void split_ip6 (struct pkt_split *ps, const in6_Header *ip6)
00343 {
00344 #if defined(USE_IPV6)
00345   const tcp_Header   *tcp;
00346   const ip6_RouteHdr *rh;
00347   const BYTE         *bp = (const BYTE*)ip6;
00348   WORD  ip_len = intel16 (ip6->len);
00349   BYTE  nxt_hd = ip6->next_hdr;
00350   int   ofs, len;
00351
00352   ps->type = TYPE_IP6;
00353   ps->len  = sizeof(*ip6);
00354   ps->data = ip6;
00355   ps++;
00356
00357   while (nxt_hd && (bp < (const BYTE*)ip6 + ip_len))
00358   {
00359     switch (nxt_hd)
00360     {
00361       case IP6_NEXT_TCP:
00362            tcp = (const tcp_Header*) (ip6 + 1);
00363            ofs = tcp->offset << 2;
00364            ps->type = TYPE_TCP_HEAD;
00365            ps->data = tcp;
00366            ps->len  = sizeof (*tcp);
00367            if (ofs - sizeof(*tcp) > 0)
00368            {
00369              ps++;
00370              ps->type = TYPE_TCP_OPTIONS;
00371              ps->data = tcp + 1;
00372              ps->len  = ofs - sizeof(*tcp);
00373            }
00374            nxt_hd = 0;   /* no next headers allowed */
00375            break;
00376
00377       case IP6_NEXT_UDP:
00378            ps->type = TYPE_UDP_HEAD;
00379            ps->data = ip6 + 1;
00380            ps->len  = sizeof (udp_Header);
00381            nxt_hd   = 0;
00382            break;
00383
00384       case IP6_NEXT_HOP:
00385            rh  = (struct ip6_RouteHdr*) (ip6 + 1);
00386            len = (rh->hdrlen + 1) << 3;
00387            ps->type = TYPE_IP6_HOP;
00388            ps->data = rh;
00389            ps->len  = len;
00390            bp      += len;
00391            nxt_hd   = *bp;
00392            break;
00393
00394       case IP6_NEXT_ROUTING:
00395            rh  = (struct ip6_RouteHdr*) (ip6 + 1);
00396            len = (rh->hdrlen + 1) << 3;
00397            ps->type = TYPE_IP6_ROUTING;
00398            ps->data = rh;
00399            ps->len  = len;
00400            bp      += len;
00401            nxt_hd   = *bp;
00402            break;
00403
00404       case IP6_NEXT_DEST:
00405            rh  = (struct ip6_RouteHdr*) (ip6 + 1);
00406            len = (rh->hdrlen + 1) << 3;
00407            ps->type = TYPE_IP6_DEST;
00408            ps->data = rh;
00409            ps->len  = len;
00410            bp      += len;
00411            nxt_hd   = *bp;
00412            break;
00413
00414       case IP6_NEXT_ICMP:
00415            rh  = (struct ip6_RouteHdr*) (ip6 + 1);
00416            len = (rh->hdrlen + 1) << 3;
00417            ps->type = TYPE_IP6_ICMP;
00418            ps->data = rh;
00419            ps->len  = len;
00420            bp      += len;
00421            nxt_hd   = 0;
00422            break;
00423
00424       case IP6_NEXT_NONE:
00425            ps->type = TYPE_IP6_NONE;
00426            ps->data = NULL;
00427            ps->len  = 0;
00428            nxt_hd   = 0;
00429
00431       case IP6_NEXT_FRAGMENT:
00432       case IP6_NEXT_ESP:
00433       case IP6_NEXT_AUTH:
00434       case IP6_NEXT_IPV6:
00435            rh  = (struct ip6_RouteHdr*) (ip6 + 1);
00436            len = (rh->hdrlen + 1) << 3;
00437            ps->type = TYPE_IP6_UNSUPP;
00438            ps->data = NULL;
00439            ps->len  = 0;
00440            bp      += len;
00441            nxt_hd   = *bp;
00442            break;
00443
00444       case IP6_NEXT_COMP:
00445       default:
00446            ps->type = TYPE_IP6_UNSUPP;
00447            ps->data = NULL;
00448            ps->len  = 0;
00449            nxt_hd   = 0;
00450     }
00451     ps++;
00452   }
00453 #else
00454   ARGSUSED (ip6);
00455 #endif        /* USE_IPV6 */
00456
00457   ps->data = NULL;
00458 }
00459
00460 #if defined(USE_DEBUG)
00461 #if defined(USE_BSD_API)
00462
00463 static const struct search_list names[] = {
00464      { TYPE_TOKEN_HEAD,  "token"      },
00465      { TYPE_FDDI_HEAD,   "fddi"       },
00466      { TYPE_ETHER_HEAD,  "ether"      },
00467      { TYPE_ARP,         "arp"        },
00468      { TYPE_RARP,        "rarp"       },
00469      { TYPE_PPPOE_DISC,  "pppoe-disc" },
00470      { TYPE_PPPOE_SESS,  "pppoe-sess" },
00471      { TYPE_PPP_LCP,     "lcp"        },
00472      { TYPE_PPP_IPCP,    "ipcp"       },
00473      { TYPE_LLC_HEAD,    "llc"        },
00474      { TYPE_IP4,         "ip4"        },
00475      { TYPE_IP4_OPTIONS, "ip4-opt"    },
00476      { TYPE_IP4_FRAG,    "ip4-frag"   },
00477      { TYPE_ICMP,        "icmp"       },
00478      { TYPE_IGMP,        "igmp"       },
00479      { TYPE_UDP_HEAD,    "udp"        },
00480      { TYPE_UDP_DATA,    "udp-data"   },
00481      { TYPE_TCP_HEAD,    "tcp"        },
00482      { TYPE_TCP_OPTIONS, "tcp-opt"    },
00483      { TYPE_TCP_DATA,    "tcp-data"   },
00484      { TYPE_IP6,         "ip6"        },
00485      { TYPE_IP6_HOP,     "ip6-hop"    },
00486      { TYPE_IP6_IPV6,    "ip6-ip6"    },
00487      { TYPE_IP6_ROUTING, "ip6-route"  },
00488      { TYPE_IP6_FRAGMENT,"ip6-frag"   },
00489      { TYPE_IP6_ESP,     "ip6-esp"    },
00490      { TYPE_IP6_AUTH,    "ip6-auth"   },
00491      { TYPE_IP6_ICMP,    "icmp6"      },
00492      { TYPE_IP6_DEST,    "ip6-dest"   },
00493      { TYPE_IP6_NONE,    "ip6-none"   },
00494      { TYPE_IP6_UNSUPP,  "ip6-unsupp" }
00495    };
00496 #endif
00497
00498 void pkt_print_split_in (void)
00499 {
00500   const struct pkt_split *ps;
00501
00502   SOCK_DEBUGF (("\nRx:\n"));
00503   for (ps = pkt_get_split_in(); ps->data; ps++)
00504       SOCK_DEBUGF (("%10s: %5u bytes\n",
00505                     list_lookup(ps->type, names, DIM(names)), ps->len));
00506 }
00507
00508 void pkt_print_split_out (void)
00509 {
00510   const struct pkt_split *ps;
00511
00512   SOCK_DEBUGF (("\nTx:\n"));
00513   for (ps = pkt_get_split_out(); ps->data; ps++)
00514       SOCK_DEBUGF (("%10s: %5u bytes\n",
00515                     list_lookup(ps->type, names, DIM(names)), ps->len));
00516 }
00517 #endif /* USE_DEBUG */
00518 #endif /* NEED_PKT_SPLIT */
Generated on Wed Jan 25 15:42:39 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/SPLIT.H Source File

SRC/SPLIT.H

Go to the documentation of this file.
00001
00003 #ifndef _w32_SPLIT_H
00004 #define _w32_SPLIT_H
00005
00006 #if (defined(USE_STATISTICS) || defined(USE_DEBUG) || defined(USE_IPV6)) && !defined(USE_UDP_ONLY)
00007 #define NEED_PKT_SPLIT
00008 #endif
00009
00010 enum Components {
00011      TYPE_TOKEN_HEAD = 1,
00012      TYPE_FDDI_HEAD,
00013      TYPE_ETHER_HEAD,
00014      TYPE_ARCNET_HEAD,
00015      TYPE_ARP,
00016      TYPE_RARP,
00017      TYPE_PPPOE_DISC,
00018      TYPE_PPPOE_SESS,
00019      TYPE_PPP_LCP,
00020      TYPE_PPP_IPCP,
00021      TYPE_LLC_HEAD,
00022      TYPE_IP4,
00023      TYPE_IP4_OPTIONS,
00024      TYPE_IP4_FRAG,
00025      TYPE_ICMP,
00026      TYPE_IGMP,
00027      TYPE_UDP_HEAD,
00028      TYPE_UDP_DATA,
00029      TYPE_TCP_HEAD,
00030      TYPE_TCP_OPTIONS,
00031      TYPE_TCP_DATA,
00032      TYPE_IP6,
00033      TYPE_IP6_HOP,
00034      TYPE_IP6_IPV6,
00035      TYPE_IP6_ROUTING,
00036      TYPE_IP6_FRAGMENT,
00037      TYPE_IP6_ESP,
00038      TYPE_IP6_AUTH,
00039      TYPE_IP6_ICMP,
00040      TYPE_IP6_DEST,
00041      TYPE_IP6_NONE,
00042      TYPE_IP6_UNSUPP,
00043      TYPE_MAX
00044    };
00045
00046 struct pkt_split {
00047        enum Components type;
00048        const void     *data;
00049        unsigned        len;
00050      };
00051
00052 extern const struct pkt_split *pkt_split_mac_in   (const void *link_pkt);
00053 extern const struct pkt_split *pkt_split_mac_out  (const void *link_pkt);
00054 extern const struct pkt_split *pkt_get_split_in   (void);
00055 extern const struct pkt_split *pkt_get_split_out  (void);
00056 extern const struct pkt_split *pkt_get_type_in    (enum Components type);
00057 extern const struct pkt_split *pkt_get_type_out   (enum Components type);
00058
00059 extern void pkt_print_split_in  (void);
00060 extern void pkt_print_split_out (void);
00061
00062 #endif
Generated on Wed Jan 25 15:42:39 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/STREAM.C Source File

SRC/STREAM.C

Go to the documentation of this file.
00001
00037 #include "socket.h"
00038
00039 #if defined(USE_BSD_API)
00040
00041 /*
00042  * How does this fit in with djgpp's FSextensions ?
00043  * Does it support fdopen() ?
00044  */
00045
00046 int sock_fgets (char *buf, int max, FILE *stream)
00047 {
00048   int        rc, s = fileno (stream);
00049   Socket    *sock  = _socklist_find (s);
00050   sock_type *sk    = NULL;
00051
00052   SOCK_PROLOGUE (sock, "\nsock_fgets:%d", s);
00053
00054   if (sock->tcp_sock)
00055      sk = (sock_type*) sock->tcp_sock;
00056   else if (sock->udp_sock)
00057      sk = (sock_type*) sock->udp_sock;
00058
00059   rc = sk ? sock_gets (sk, (BYTE*)buf, max) : -1;
00060
00061   SOCK_DEBUGF ((", rc %d", rc));
00062   return (rc);
00063 }
00064
00065 int sock_fputs (const char *text, FILE *stream)
00066 {
00067   int     s    = fileno (stream);
00068   Socket *sock = _socklist_find (s);
00069
00070   SOCK_PROLOGUE (sock, "\nsock_fputs:%d", s);
00071   return write_s (s, text, strlen(text));
00072 }
00073
00074 #endif  /* USE_BSD_API */
Generated on Wed Jan 25 15:42:39 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/STRINGS.C Source File

SRC/STRINGS.C

Go to the documentation of this file.
00001
00005 #include <stdio.h>
00006 #include <stdlib.h>
00007 #include <string.h>
00008 #include <ctype.h>
00009
00010 #include "wattcp.h"
00011 #include "misc.h"
00012 #include "strings.h"
00013
00014 /*
00015  * This file contains some gross hacks. Take great care !
00016  */
00017 #include "nochkstk.h"
00018
00019 #ifdef __WATCOMC__
00020   extern void _outchar (char c);
00021   #pragma aux _outchar = \
00022           "mov ah, 2"    \
00023           "int 21h"      \
00024           parm [dl]      \
00025           modify [ax];
00026 #endif
00027
00028 /*
00029  * Print a single character to stdout.
00030  */
00031 static void outch (char chr)
00032 {
00033   if (chr == (char)0x1A)     /* EOF (^Z) causes trouble to stdout */
00034      return;
00035
00036 #if defined(WIN32)
00037   {
00038     HANDLE hnd = GetStdHandle (STD_OUTPUT_HANDLE);
00039
00040     if (hnd != INVALID_HANDLE_VALUE)
00041        WriteConsoleA (hnd, &chr, 1, NULL, NULL);
00042   }
00043 #elif !(DOSX)
00044   /* Qemm doesn't like INT 21 without a valid ES reg. intdos() sets up that.
00045    */
00046   {
00047     union REGS r;
00048     r.h.ah = 2;
00049     r.h.dl = chr;
00050     intdos (&r, &r);
00051   }
00052
00053 #elif (DOSX & POWERPAK)
00054   {
00055     union REGS r;
00056     r.h.ah = 2;
00057     r.h.dl = chr;
00058     int386 (0x21, &r, &r);
00059   }
00060
00061 #elif defined(__BORLANDC__)  /* avoid spawning tasm.exe */
00062   _ES = _DS;
00063   _DL = chr;
00064   _AL = 2;
00065   geninterrupt (0x21);
00066
00067 #elif defined(_MSC_VER) || defined(__DMC__)
00068   asm mov dl, chr
00069   asm mov ah, 2
00070   asm int 21h
00071
00072 #elif defined(__CCDL__)
00073   asm mov dl, [chr]
00074   asm mov ah, 2
00075   asm int 0x21
00076
00077 #elif defined(__WATCOMC__)
00078   _outchar (chr);
00079
00080 #elif defined(__HIGHC__)     /* outch() must not be optimised! */
00081   _inline (0x8A,0x55,0x08);  /* mov dl,[ebp+8] */
00082   _inline (0xB4,0x02);       /* mov ah,2       */
00083   _inline (0xCD,0x21);       /* int 21h        */
00084
00085 #elif defined(__GNUC__)
00086   __asm__ __volatile__
00087           ("movb %b0, %%dl\n\t"
00088            "movb $2, %%ah\n\t"
00089            "int $0x21\n\t"
00090            :
00091            : "r" (chr)
00092            : "%eax", "%edx" );
00093
00094 #else
00095   #error Tell me how to do this
00096 #endif
00097 }
00098
00099 void (*_outch)(char c) = outch;
00100
00101 /*---------------------------------------------------*/
00102
00103 #if defined(USE_DEBUG)
00104   #if defined(WATT32_DOS_DLL)   /* cannot use 'import_export.printf' here */
00105     int (MS_CDECL *_printf) (const char*, ...) = NULL;
00106   #else
00107     int (MS_CDECL *_printf) (const char*, ...) = printf;
00108   #endif
00109 #else
00110   static int MS_CDECL EmptyPrint (const char *fmt, ...)
00111   {
00112     outsnl ("`(*_printf)()' called outside `USE_DEBUG'");
00113     ARGSUSED (fmt);
00114     return (0);
00115   }
00116   int (MS_CDECL *_printf) (const char*, ...) = EmptyPrint;
00117 #endif
00118
00119 /*---------------------------------------------------*/
00120
00121 void outs (const char *s)
00122 {
00123   while (s && *s)
00124   {
00125     if (*s == '\n')
00126        (*_outch) ('\r');
00127     (*_outch) (*s++);
00128   }
00129 }
00130
00131 void outsnl (const char *s)
00132 {
00133   outs (s);
00134   (*_outch) ('\r');
00135   (*_outch) ('\n');
00136 }
00137
00138 void outsn (const char *s, int n)
00139 {
00140   while (*s != '\0' && n-- >= 0)
00141   {
00142     if (*s == '\n')
00143        (*_outch) ('\r');
00144     (*_outch) (*s++);
00145   }
00146 }
00147
00148 void outhex (char c)
00149 {
00150   char hi = (c & 0xF0) >> 4;
00151   char lo = c & 15;
00152
00153   if (hi > 9)
00154        (*_outch) ((char)(hi-10+'A'));
00155   else (*_outch) ((char)(hi+'0'));
00156
00157   if (lo > 9)
00158        (*_outch) ((char)(lo-10+'A'));
00159   else (*_outch) ((char)(lo+'0'));
00160 }
00161
00162 void outhexes (const char *s, int n)
00163 {
00164   while (n-- > 0)
00165   {
00166     outhex (*s++);
00167     (*_outch) (' ');
00168   }
00169 }
00170
00176 char *rip (char *s)
00177 {
00178   char *p;
00179
00180   if ((p = strrchr(s,'\n')) != NULL) *p = '\0';
00181   if ((p = strrchr(s,'\r')) != NULL) *p = '\0';
00182   return (s);
00183 }
00184
00190 BYTE atox (const char *hex)
00191 {
00192   unsigned hi = toupper (hex[2]);
00193   unsigned lo = toupper (hex[3]);
00194
00195   hi -= isdigit (hi) ? '0' : 'A'-10;
00196   lo -= isdigit (lo) ? '0' : 'A'-10;
00197   return (BYTE) ((hi << 4) + lo);
00198 }
00199
00203 char *strreplace (int ch1, int ch2, char *str)
00204 {
00205   char *s = str;
00206
00207   WATT_ASSERT (str != NULL);
00208   while (*s)
00209   {
00210     if (*s == ch1)
00211         *s = ch2;
00212     s++;
00213   }
00214   return (str);
00215 }
00216
00217
00224 char *StrLcpy (char *dst, const char *src, size_t len)
00225 {
00226   WATT_ASSERT (src != NULL);
00227   WATT_ASSERT (dst != NULL);
00228   WATT_ASSERT (len > 0);
00229
00230   if (strlen(src) < len)
00231      return strcpy (dst, src);
00232
00233   memcpy (dst, src, len);
00234   dst [len-1] = '\0';
00235   return (dst);
00236 }
00237
00241 char *strltrim (const char *s)
00242 {
00243   const char *p = s;
00244
00245   WATT_ASSERT (s != NULL);
00246
00247   while (p[0] && p[1] && isspace(*p))
00248        p++;
00249   return (char*)p;
00250 }
00251
00255 char *strrtrim (char *s)
00256 {
00257   size_t n;
00258
00259   WATT_ASSERT (s != NULL);
00260
00261   n = strlen (s);
00262   while (n)
00263   {
00264     if (!isspace(s[--n]))
00265        break;
00266     s[n] = '\0';
00267   }
00268   return (s);
00269 }
00270
00277 size_t strntrimcpy (char *dst, const char *src, size_t n)
00278 {
00279   size_t      len;
00280   const char *s;
00281
00282   WATT_ASSERT (src != NULL);
00283   WATT_ASSERT (dst != NULL);
00284
00285   len = 0;
00286   s   = src;
00287
00288   if (n && s[0])
00289   {
00290     while (isspace(*s))
00291           ++s;
00292     len = strlen (s);
00293     if (len)
00294     {
00295       const char *e = &s[len-1];
00296       while (isspace(*e))
00297       {
00298         --e;
00299         --len;
00300       }
00301       if (len > n)
00302           len = n;
00303       strncpy (dst, s, len);
00304     }
00305   }
00306   if (len < n)
00307      dst[len] = '\0';
00308   return (len);
00309 }
00310
00311 #ifdef NOT_USED
00312 int isstring (const char *str, size_t len)
00313 {
00314   if (strlen(str) > len-1)
00315      return (0);
00316
00317   while (*str)
00318   {
00319     if (!isprint(*str++))
00320     {
00321       str--;
00322       if (!isspace(*str++))
00323          return (0);
00324     }
00325   }
00326   return (1);
00327 }
00328 #endif
Generated on Wed Jan 25 15:42:39 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/STRINGS.H Source File

SRC/STRINGS.H

Go to the documentation of this file.
00001
00003 #ifndef _w32_STRINGS_H
00004 #define _w32_STRINGS_H
00005
00006 #define _printf      NAMESPACE (_printf)
00007 #define _outch       NAMESPACE (_outch)
00008 #define outs         NAMESPACE (outs)
00009 #define outsnl       NAMESPACE (outsnl)
00010 #define outsn        NAMESPACE (outsn)
00011 #define outhexes     NAMESPACE (outhexes)
00012 #define outhex       NAMESPACE (outhex)
00013 #define rip          NAMESPACE (rip)
00014 #define StrLcpy      NAMESPACE (StrLcpy)
00015 #define strntrimcpy  NAMESPACE (strntrimcpy)
00016 #define strrtrim     NAMESPACE (strrtrim)
00017 #define strltrim     NAMESPACE (strltrim)
00018 #define strreplace   NAMESPACE (strreplace)
00019 #define atox         NAMESPACE (atox)
00020
00021 /* Points to current var-arg print routine.
00022  * Need gcc 3.x for printf-check on func-pointers.
00023  */
00024 W32_DATA int (MS_CDECL *_printf) (const char *fmt, ...) ATTR_PRINTF(1,2);
00025
00026 /* Points to current character output handler.
00027  */
00028 W32_DATA void (*_outch) (char c);
00029
00030 W32_FUNC void  outs    (const char *s);         /* print a ASCIIZ string to stdio  */
00031 W32_FUNC void  outsnl  (const char *s);         /* print a ASCIIZ string w/newline */
00032 W32_FUNC void  outsn   (const char *s, int n);  /* print a string with len max n   */
00033 W32_FUNC void  outhexes(const char *s, int n);  /* print a hex-string with len n   */
00034 W32_FUNC void  outhex  (char ch);               /* print a hex-char to stdio       */
00035 W32_FUNC char *rip     (char *s);               /* strip off '\r' and '\n' from s  */
00036
00037 extern  char  *strreplace  (int ch1, int ch2, char *str);
00038 extern  char  *StrLcpy     (char *dst, const char *src, size_t len);
00039 extern  size_t strntrimcpy (char *dst, const char *src, size_t len);
00040 extern  char  *strrtrim    (char *src);
00041 extern  char  *strltrim    (const char *src);
00042 extern  BYTE   atox        (const char *src);
00043
00044 #endif
00045
Generated on Wed Jan 25 15:42:39 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/SYSLOG.C Source File

SRC/SYSLOG.C

Go to the documentation of this file.
00001
00019 #include <stdio.h>
00020 #include <stdlib.h>
00021 #include <stdarg.h>
00022 #include <sys/syslog.h>
00023 #include <sys/socket.h>
00024 #include <fcntl.h>
00025 #include <string.h>
00026 #include <time.h>
00027 #include <netdb.h>
00028
00029 #include "wattcp.h"
00030 #include "misc.h"
00031 #include "printk.h"
00032 #include "pctcp.h"
00033 #include "pcsed.h"
00034 #include "pcstat.h"
00035 #include "pcbuf.h"
00036 #include "pcdbug.h"
00037 #include "pcconfig.h"
00038 #include "netaddr.h"
00039 #include "sock_ini.h"
00040 #include "strings.h"
00041 #include "syslog2.h"
00042
00043 #if defined(USE_BSD_API)
00044
00045 #if defined(__CCDL__) && !defined(getpid)
00046 #define getpid()  0
00047 #endif
00048
00049 #if defined(__LCCDL__)
00050 #define getpid()  _getpid()
00051 #endif
00052
00053 #define INTERNALLOG  (LOG_ERR|LOG_CONS|LOG_PERROR|LOG_PID)
00054
00055 static sock_type *logSock   = NULL;     /* UDP socket for log */
00056 static FILE      *logFile   = NULL;     /* FILE* for log */
00057 static DWORD      logHost   = 0UL;      /* IP-address of host (host order) */
00058 static BOOL       logOpened = FALSE;    /* have done openlog() (error or not) */
00059 static int        logStat   = 0;        /* status bits, set by openlog() */
00060 static char      *logTag    = NULL;     /* string to tag the entry with */
00061 static int        logMask   = LOG_INFO; /* default is LOG_EMERG - LOGINFO */
00062 static DWORD      logFacil  = LOG_USER; /* default facility */
00063
00064 /* These arrays used to be pulled in from <sys/syslog.h> when SYSLOG_NAMES
00065  * was defined, but caused "multiple defined" problems.
00066  */
00067 CODE prioritynames[] = {
00068         { LOG_ALERT,      "alert"    },
00069         { LOG_CRIT,       "crit"     },
00070         { LOG_DEBUG,      "debug"    },
00071         { LOG_EMERG,      "emerg"    },
00072         { LOG_ERR,        "err"      },
00073         { LOG_ERR,        "error"    },      /* DEPRECATED */
00074         { LOG_INFO,       "info"     },
00075         { INTERNAL_NOPRI, "none"     },      /* INTERNAL */
00076         { LOG_NOTICE,     "notice"   },
00077         { LOG_EMERG,      "panic"    },      /* DEPRECATED */
00078         { LOG_WARNING,    "warn"     },      /* DEPRECATED */
00079         { LOG_WARNING,    "warning"  },
00080         { -1,             NULL       }
00081       };
00082
00083 CODE facilitynames[] = {
00084         { LOG_AUTH,      "auth"      },
00085         { LOG_AUTHPRIV,  "authpriv"  },
00086         { LOG_CRON,      "cron"      },
00087         { LOG_DAEMON,    "daemon"    },
00088         { LOG_FTP,       "ftp"       },
00089         { LOG_KERN,      "kern"      },
00090         { LOG_LPR,       "lpr"       },
00091         { LOG_MAIL,      "mail"      },
00092         { INTERNAL_MARK, "mark"      },      /* INTERNAL */
00093         { LOG_NEWS,      "news"      },
00094         { LOG_NTP,       "ntp"       },
00095         { LOG_AUTH,      "security"  },      /* DEPRECATED */
00096         { LOG_SYSLOG,    "syslog"    },
00097         { LOG_USER,      "user"      },
00098         { LOG_UUCP,      "uucp"      },
00099         { LOG_LOCAL0,    "local0"    },
00100         { LOG_LOCAL1,    "local1"    },
00101         { LOG_LOCAL2,    "local2"    },
00102         { LOG_LOCAL3,    "local3"    },
00103         { LOG_LOCAL4,    "local4"    },
00104         { LOG_LOCAL5,    "local5"    },
00105         { LOG_LOCAL6,    "local6"    },
00106         { LOG_LOCAL7,    "local7"    },
00107         { -1,            NULL        }
00108       };
00109
00110 /*
00111  * syslog, vsyslog --
00112  *   print message on log file; output is intended for syslogd(8).
00113  */
00114 void MS_CDECL syslog (int pri, const char *fmt, ...)
00115 {
00116   va_list args;
00117   va_start (args, fmt);
00118   vsyslog (pri, fmt, args);
00119   va_end (args);
00120 }
00121
00122 void vsyslog (int pri, const char *fmt, va_list ap)
00123 {
00124   const char *pri_name = "?";
00125   const char *fac_name = "?";
00126   const char *pri_end;
00127   char  *p;
00128   char   tbuffer [2048];
00129   int    left = sizeof(tbuffer);
00130   int    saved_errno = errno;
00131   time_t t;
00132
00133 #if 0
00134   /* Check for invalid bits
00135    */
00136   if (pri & ~(LOG_PRIMASK|LOG_FACMASK))
00137   {
00138     syslog (INTERNALLOG, "syslog: unknown priority: %d", pri);
00139     pri &= (LOG_PRIMASK | LOG_FACMASK);
00140   }
00141 #endif
00142
00143   /* Set default facility if none specified
00144    */
00145   if (!(pri & LOG_FACMASK))
00146      pri |= logFacil;
00147
00148 #if defined(USE_DEBUG)
00149   pri_name = list_lookup (LOG_PRI(pri),
00150                           (const struct search_list*)prioritynames,
00151                           DIM(prioritynames)-1);
00152
00153   fac_name = list_lookup (LOG_FACMASK & pri,
00154                           (const struct search_list*)facilitynames,
00155                           DIM(facilitynames)-1);
00156 #endif
00157
00158   /* Check priority against setlogmask() values.
00159    * Note: higher priorities are lower values !!
00160    */
00161   if (LOG_PRI(pri) > LOG_PRI(logMask))
00162   {
00163     if (debug_on >= 2)
00164        (*_printf) ("syslog: Dropping %s (%d) priority message, "
00165                    "facility %s (%d), pri 0x%04X\n",
00166                    pri_name, LOG_PRI(pri),
00167                    fac_name, LOG_FAC(pri), pri);
00168     return;
00169   }
00170
00171 #if 1
00172   if (debug_on >= 2)
00173      (*_printf) ("syslog: Accepting %s (%d) priority message, "
00174                  "facility %s (%d), pri 0x%04X\n",
00175                  pri_name, LOG_PRI(pri),
00176                  fac_name, LOG_FAC(pri), pri);
00177 #endif
00178
00179   /* Build the message
00180    */
00181   time (&t);
00182   p  = tbuffer;
00183   p += _snprintk (p, left, "<%3d>%.15s ", pri, ctime(&t)+4);
00184   left -= p - tbuffer;
00185   pri_end = 1 + strchr (tbuffer, '>');
00186
00187   if (logTag)
00188   {
00189     p += _snprintk (p, left, logTag);
00190     left -= p - tbuffer;
00191   }
00192   if (logStat & LOG_PID)
00193   {
00194     p += _snprintk (p, left, "[%d]", getpid());
00195     left -= p - tbuffer;
00196   }
00197   if (logTag)
00198   {
00199     p += _snprintk (p, left, ": ");
00200     left -= p - tbuffer;
00201   }
00202
00203   SOCK_ERRNO (saved_errno);
00204   p += _vsnprintk (p, left, fmt, ap);
00205   if (*(p-1) != '\n')
00206   {
00207     *p++ = '\n';
00208     *p = '\0';
00209   }
00210
00211   if (!logOpened)
00212      openlog (logTag, logStat | LOG_NDELAY, logFacil);
00213
00214   if (logFile)
00215      _fputsk (pri_end, logFile);
00216
00217   if ((logStat & LOG_PERROR) ||
00218       ((pri & LOG_PRIMASK) == LOG_ERR && (logStat & LOG_CONS)))
00219      _fputsk (pri_end, stdout);
00220
00221   if (logSock)
00222   {
00223     int   len = strlen (tbuffer);
00224     char *err;
00225
00226     len = sock_write (logSock, (const BYTE*)tbuffer, len);
00227     err = (char*) sockerr (logSock);
00228
00229     if (len <= 0 || err)
00230     {
00231       err = strdup (err);
00232       sock_close (logSock);
00233       free (logSock);
00234       logSock = NULL;
00235       syslog (logStat | LOG_ERR, "UDP write failed: %s\n", err);
00236       if (err)
00237          free (err);
00238     }
00239   }
00240 }
00241
00242
00243 static const char *getlogname (void)
00244 {
00245   const char *name = get_argv0();
00246   char       *dot;
00247   static char buf [MAX_PATHLEN];
00248
00249   if (name && name[0])
00250   {
00251     name = StrLcpy (buf, name, sizeof(buf));
00252     dot = strrchr (name, '.');
00253     if (dot && (!strnicmp(dot,".exe",4) || !strnicmp(dot,".exp",4)))
00254     {
00255       strcpy (dot, ".log");
00256       return (name);
00257     }
00258   }
00259   return ("$unknown.log");
00260 }
00261
00262
00263 static int openloghost (char **errbuf)
00264 {
00265   struct servent *sp;
00266   struct hostent *hp;
00267   static char buf [80];
00268
00269   *errbuf = NULL;
00270
00271   if (logSock)    /* reopen UDP connection */
00272   {
00273     sock_close (logSock);
00274     logSock = NULL;
00275   }
00276
00277   sp = getservbyname ("syslog", "udp");
00278   if (sp)
00279      syslog_port = htons (sp->s_port);
00280
00281   logHost = _inet_addr (syslog_hostName);
00282   if (!logHost)
00283   {
00284     hp = gethostbyname (syslog_hostName);
00285     if (!hp)
00286     {
00287       sprintf (buf, "unknown host `%s'", syslog_hostName);
00288       *errbuf = buf;
00289       return (0);
00290     }
00291     logHost = ntohl (*(DWORD*)hp->h_addr);
00292   }
00293
00294   if (!logSock)
00295   {
00296     logSock = (sock_type*) malloc (sizeof(_udp_Socket));
00297     if (!logSock)
00298     {
00299       StrLcpy (buf, strerror(errno), sizeof(buf));
00300       *errbuf = buf;
00301       return (0);
00302     }
00303   }
00304
00305   if (!udp_open(&logSock->udp, 0, logHost, syslog_port, NULL))
00306   {
00307     StrLcpy (buf, sockerr(logSock), sizeof(buf));
00308     *errbuf = buf;
00309     sock_close (logSock);
00310     free (logSock);
00311     logSock = NULL;
00312     return (0);
00313   }
00314   return (1);
00315 }
00316
00317 void openlog (const char *ident, int logstat, int logfac)
00318 {
00319   static BOOL done = FALSE;
00320   BOOL   fail  = FALSE;
00321   char  *error = NULL;
00322
00323   if (ident)
00324      logTag = (char*)ident;
00325   logStat = logstat;
00326
00327   if (logfac && !(logfac & ~LOG_FACMASK))  /* legal facility */
00328      logFacil = logfac;
00329
00330   if (!syslog_fileName[0])          /* not set in wattcp.cfg */
00331      StrLcpy (syslog_fileName, getlogname(), sizeof(syslog_fileName));
00332
00333   if (syslog_mask)
00334   {
00335     TCP_CONSOLE_MSG (2, ("setlogmask(0x%04X)\n", syslog_mask));
00336     setlogmask (syslog_mask);
00337   }
00338
00339   /* Open immediately
00340    * !! fix-me: the LOG_NDELAY flag is really for the network connection
00341    */
00342   if (syslog_fileName[0] && (logStat & LOG_NDELAY))
00343   {
00344     if (logFile)                  /* reopen */
00345        fclose (logFile);
00346
00347     logOpened = TRUE;
00348     logFile = fopen (syslog_fileName, "at");
00349     if (!logFile || fputs("\n",logFile) == EOF)
00350     {
00351       logFile = NULL;
00352       error = strerror (errno);
00353       fail  = TRUE;
00354     }
00355 #if !defined(__BORLANDC__)  /* buggy output with this */
00356     else
00357     {
00358       static char fbuf [256];
00359       setvbuf (logFile, fbuf, _IOLBF, sizeof(fbuf));  /* line-buffered */
00360     }
00361 #endif
00362   }
00363
00364   if (syslog_hostName[0] && !openloghost(&error))
00365      fail = TRUE;
00366
00367   _printk_file = logFile;
00368
00369   if (!done)
00370   {
00371     RUNDOWN_ADD (closelog, 110);
00372     _printk_init (2000, NULL);
00373     done = TRUE;
00374     if (logSock)
00375     {
00376       syslog (LOG_INFO, "syslog client at %I started", htonl(my_ip_addr));
00377       if (_inet_addr(syslog_hostName))
00378            syslog (LOG_INFO, "Logging to host %s", syslog_hostName);
00379       else syslog (LOG_INFO, "Logging to host %s (%I)",
00380                    syslog_hostName, htonl(logHost));
00381     }
00382   }
00383
00384   if (fail && (logStat & LOG_CONS))
00385      fprintf (stdout, "syslog: %s\n", error);
00386 }
00387
00388
00389 int setlogmask (int mask)
00390 {
00391   int old = logMask;
00392   if (mask)
00393      logMask = mask;
00394   return (old);
00395 }
00396
00397
00398 char *setlogtag (char *newTag)
00399 {
00400   char *old = logTag;
00401   logTag = newTag;
00402   return (old);
00403 }
00404
00405 #include "nochkstk.h"
00406
00407 void closelog (void)
00408 {
00409   if (!_watt_fatal_error)
00410   {
00411     if (logFile)
00412        fclose (logFile);
00413
00414     if (logSock)
00415     {
00416       sock_close (logSock);
00417       free (logSock);
00418     }
00419   }
00420   logSock   = NULL;
00421   logFile   = NULL;
00422   logOpened = FALSE;
00423 }
00424 #endif /* USE_BSD_API */
00425
00426
00427 #if defined(TEST_PROG)
00428
00429 #include "sock_ini.h"
00430 #include "pcdbug.h"
00431
00432 int main (void)
00433 {
00434   dbug_init();
00435   sock_init();
00436   debug_on = 2;
00437
00438   openlog ("test", LOG_PID, LOG_LOCAL2);
00439
00440   syslog (LOG_NOTICE, "NOTICE:  time now %t. file %s at line %d\n",
00441           __FILE__, __LINE__);
00442
00443   SOCK_ERRNO (ENOMEM);
00444   syslog (LOG_ERR | LOG_LOCAL0, "ERR:     Allocation failed; %m");
00445
00446   syslog (LOG_DEBUG, "DEBUG:   my_ip_addr = %I", htonl(my_ip_addr));
00447
00448   SOCK_ERRNO (ENETDOWN);
00449   syslog (LOG_ALERT, "ALERT:   Connection failed; %m");
00450
00451   syslog (LOG_EMERG, "EMERG:   Coffee mug empty");
00452
00453   syslog (LOG_CRIT|LOG_KERN, "CRIT:    Kernel message: General error reading disk.");
00454
00455   SOCK_ERRNO (EILSEQ);
00456   syslog (LOG_WARNING, "WARNING: Multibyte error; %m");
00457
00458   syslog (LOG_INFO, "INFO:    Leaving main()");
00459
00460   printf ("Done. ");
00461   if (logFile)
00462      printf ("Look at `%s'", syslog_fileName);
00463
00464   closelog();
00465   return (0);
00466 }
00467 #endif /* TEST_PROG */
Generated on Wed Jan 25 15:42:39 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/SYSLOG2.C Source File

SRC/SYSLOG2.C

Go to the documentation of this file.
00001
00035 #include <stdio.h>
00036 #include <stdlib.h>
00037 #include <stdarg.h>
00038 #include <sys/syslog.h>
00039 #include <errno.h>
00040 #include <fcntl.h>
00041 #include <string.h>
00042 #include <time.h>
00043
00044 #include "wattcp.h"
00045 #include "printk.h"
00046 #include "pcconfig.h"
00047 #include "strings.h"
00048 #include "syslog2.h"
00049
00050 #if defined(USE_BSD_API)
00051
00052 static void (*prev_hook) (const char*, const char*) = NULL;
00053
00054 char syslog_fileName [MAX_NAMELEN] = "";   /* name of logfile */
00055 char syslog_hostName [MAX_HOSTLEN] = "";   /* name of loghost */
00056 WORD syslog_port = 514;                    /* udp port to use */
00057 int  syslog_mask = LOG_UPTO(-1);           /* log everything */
00058
00059 static int getlogmask (const char *value)
00060 {
00061   int mask = 0;
00062
00063   if (!strcmp(value, "all"))
00064      return (LOG_PRIMASK); /* LOG_UPTO (LOG_EMERG); */
00065
00066   if (strstr(value, "emerg"))  mask |= LOG_EMERG;
00067   if (strstr(value, "alert"))  mask |= LOG_ALERT;
00068   if (strstr(value, "crit"))   mask |= LOG_CRIT;
00069   if (strstr(value, "error"))  mask |= LOG_ERR;
00070   if (strstr(value, "warn"))   mask |= LOG_WARNING;
00071   if (strstr(value, "notice")) mask |= LOG_NOTICE;
00072   if (strstr(value, "info"))   mask |= LOG_INFO;
00073   if (strstr(value, "debug"))  mask |= LOG_DEBUG;
00074   return (mask);
00075 }
00076
00077 static void set_syslog_mask (const char *value)
00078 {
00079   char val[100];
00080
00081   StrLcpy (val, value, sizeof(val));
00082   strlwr (val);
00083   syslog_mask = getlogmask (val);
00084 }
00085
00086 static void ourinit (const char *name, const char *value)
00087 {
00088   static const struct config_table syslog_cfg[] = {
00089             { "FILE",  ARG_STRCPY, (void*)&syslog_fileName },
00090             { "HOST",  ARG_STRCPY, (void*)&syslog_hostName },
00091             { "PORT",  ARG_ATOI,   (void*)&syslog_port     },
00092             { "LEVEL", ARG_FUNC,   (void*)set_syslog_mask  },
00093             { NULL,    0,          NULL                    }
00094           };
00095   if (!parse_config_table(&syslog_cfg[0], "SYSLOG.", name, value) && prev_hook)
00096      (*prev_hook) (name, value);
00097 }
00098
00099 void syslog_init (void)
00100 {
00101   prev_hook = usr_init;
00102   usr_init  = ourinit;
00103 }
00104 #endif /* USE_BSD_API */
Generated on Wed Jan 25 15:42:39 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/SYSLOG2.H Source File

SRC/SYSLOG2.H

Go to the documentation of this file.
00001
00003 #ifndef _w32_SYSLOG2_H
00004 #define _w32_SYSLOG2_H
00005
00006 extern char syslog_fileName [MAX_NAMELEN];
00007 extern char syslog_hostName [MAX_HOSTLEN];
00008 extern WORD syslog_port;
00009 extern int  syslog_mask;
00010
00011 extern void syslog_init (void);
00012
00013 #endif
Generated on Wed Jan 25 15:42:39 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/TARGET.H Source File

SRC/TARGET.H

Go to the documentation of this file.
00001 #ifndef _w32_TARGET_H
00002 #define _w32_TARGET_H
00003
00011 #ifndef _w32_WATTCP_H
00012 #error TARGET.H must be included inside or after WATTCP.H
00013 #endif
00014
00015 #define DOS4GW       1
00016 #define DJGPP        2
00017 #define PHARLAP      4
00018 #define PHAR286      8
00019 #define POWERPAK     16
00020 #define X32VM        32
00021 #define WINWATT      64
00022 #define PHARLAP_DLL (0x80|PHARLAP)
00023 #define DOS4GW_DLL  (0x80|DOS4GW)
00024 #define DJGPP_DXE   (0x80|DJGPP)
00026 /*
00027  * Notes:
00028  *
00029  * (1) Most 32-bit DOS compilers (Borland/Watcom/Microsoft/HighC/DMC)
00030  *     will work with this DOS extender. Some compilers support far
00031  *     pointers (48-bits), some don't. And even worse, some of those who
00032  *     do, have bugs in their segment register handling!
00033  *     Add `-DBUGGY_FARPTR=1' to your makefile's CFLAGS if you experience
00034  *     this or crashes in weird places (generate .asm listing to find out).
00035  *
00036  *     The problem is present in:
00037  *       - Metaware's HighC v3.1 at -O3 or above (for sure).
00038  *       - BCC32 v4, Some rumours say far-ptrs in combination with FPU-ops.
00039  *
00040  * (2) Several DOS-extenders supports Watcom-386. DOS4GW (from Tenberry)
00041  *     is a DPMI 0.9 host with limited API. Other compatible DOS-extenders
00042  *     can also be used without modifying Watt-32. These are:
00043  *     DOS4GW Pro, DOS4G, Pmode/W, CauseWay, DOS32A, EDOS, WDOSX and
00044  *     Zurenava. Watcom with FlashTek's X-32 hasn't been tested.
00045  *
00046  */
00047
00048 #ifndef BUGGY_FARPTR
00049 #define BUGGY_FARPTR 0      /* Assume no compilers have fp-bugs, duh! */
00050 #endif
00051
00052 #if defined(_MSC_VER) && defined(M_I86SM)   /* Microsoft doesn't have */
00053   #define __SMALL__                         /* __SMALL__,  __LARGE__  */
00054 #endif
00055
00056 #if defined(_MSC_VER) && defined(M_I86LM)
00057   #define __LARGE__
00058 #endif
00059
00060 #if defined(__TINY__) || defined(__COMPACT__) || defined(__MEDIUM__) || defined(__HUGE__)
00061   #error Unsupported memory model (tiny/compact/medium/huge)
00062 #endif
00063
00064 #if defined(M_I86TM) || defined(M_I86CM) || defined(M_I86MM) || defined(M_I86HM)
00065   #error Unsupported memory model (tiny/compact/medium/huge)
00066 #endif
00067
00068 #if defined(_M_I86MM) || defined(_M_I86MH)
00069   #error Unsupported memory model (medium/huge)
00070 #endif
00071
00072 #if defined(__SMALL__) || defined(__LARGE__)
00073   #undef  DOSX
00074   #define DOSX 0
00075 #endif
00076
00077 /*
00078  * djgpp 2.x with GNU C 2.7 or later.
00079  */
00080 #if defined(__DJGPP__) && defined(__GNUC__)
00081   #undef  DOSX
00082   #define DOSX      DJGPP
00083 #endif
00084
00085 /*
00086  * Watcom 11.x or OpenWatcom 1.x.
00087  */
00088 #if defined(__WATCOMC__) && defined(__386__)
00089   #undef  DOSX
00090   #define DOSX      DOS4GW    /* may be DOS4GW/X32VM/PHARLAP */
00091   #define WATCOM386
00092 #endif
00093
00094 /*
00095  * Digital Mars Compiler 8.30+
00096  */
00097 #if defined(__DMC__) && (__INTSIZE==4)
00098   #undef  DOSX
00099   #define DOSX      X32VM     /* may also be DOS4GW/PHARLAP */
00100   #define DMC386
00101 #endif
00102
00103 /*
00104  * PellesC works with WIN32 only.
00105  * Note: "pocc -Ze" sets _MSC_VER.
00106  */
00107 #if defined(__POCC__)
00108   #if !defined(__POCC__OLDNAMES)
00109   #error Use the "pocc -Go" option.
00110   #endif
00111   #undef  DOSX
00112   #define DOSX      WINWATT
00113   #undef _MSC_VER
00114 #endif
00115
00116 /*
00117  * Microsoft Visual-C 32-bit. Really not supported with PharLap,
00118  * but works with WIN32 as target.
00119  */
00120 #if defined(_MSC_VER) && (_M_IX86 >= 300)
00121   #undef  DOSX
00122   #define DOSX      WINWATT  /* VC 2.0 can use PHARLAP too */
00123   #define MSC386
00124 #endif
00125
00126 /*
00127  * Metaware's High-C 3.x
00128  */
00129 #if defined(__HIGHC__)
00130   #undef  DOSX
00131   #define DOSX      PHARLAP   /* Is DOS4GW possible? */
00132 #endif
00133
00134 /*
00135  * Borland 32-bit PowerPak compiler (v4.x, v5.x untested)
00136  */
00137 #if defined(__BORLANDC__) && defined(__FLAT__) && defined(__DPMI32__)
00138   #define BORLAND386
00139   #undef  DOSX
00140   #define DOSX      POWERPAK  /* may also be DOS4GW (for WDOSX targets) */
00141                               /* or PHARLAP (not yet) */
00142 #endif
00143
00144 #if defined(__BORLANDC__) && defined(WIN32)
00145   #define BORLAND_WIN32
00146   #undef  DOSX
00147   #define DOSX      WINWATT  /* experimental ATM */
00148 #endif
00149
00150 /*
00151  * LadSoft (cc386 is rather buggy, so not really supported)
00152  */
00153 #if defined(__CCDL__) && defined(__386__)
00154   #undef  DOSX
00155   #define DOSX      DOS4GW
00156 #endif
00157
00158 /*
00159  * Build a Windows DLL. Uses WinPcap as packet-driver replacement.
00160  */
00161 #if defined(WIN32) || defined(_WIN32)
00162   #undef  DOSX
00163   #define DOSX      WINWATT
00164 #endif
00165
00166
00167 #ifndef DOSX
00168   #error DOSX target not defined
00169 #endif
00170
00171 /* 32-bit Digital Mars Compiler defines __SMALL__. So make a
00172  * define for 16-bit __SMALL__ models.
00173  */
00174 #if (DOSX == 0) && defined(__SMALL__)
00175   #define __SMALL16__
00176 #endif
00177
00178 /*
00179  * Macros and hacks depending on target (DOS-extender).
00180  */
00181
00182 #if (DOSX & PHARLAP)
00183   #include <stdio.h>
00184   #include <pharlap.h>
00185   #undef FP_OFF
00186   #include <dos.h>
00187
00188   #ifdef WATCOM386
00189   #include <i86.h>
00190   #endif
00191
00192   extern REALPTR _watt_dosTbr;
00193   extern DWORD   _watt_dosTbSize;
00194
00195   #if (!BUGGY_FARPTR) &&         /* Trust the compiler to handle far-ptr ? */ \
00196       (__CMPLR_FEATURES__ & __FEATURE_FARPTR__) /* compilers with far-ptrs */
00197     #define HAS_FP                              /* i.e. HighC, Watcom386   */
00198     extern FARPTR _watt_dosFp;
00199
00200     #define DOSMEM(s,o,t) *(t _far*)(_watt_dosFp + (DWORD)((o)|(s)<<4))
00201     #define PEEKB(s,o)    DOSMEM(s,o,BYTE)
00202     #define PEEKW(s,o)    DOSMEM(s,o,WORD)
00203     #define PEEKL(s,o)    DOSMEM(s,o,DWORD)
00204     #define POKEB(s,o,x)  DOSMEM(s,o,BYTE)  = (BYTE)(x)
00205     #define POKEW(s,o,x)  DOSMEM(s,o,WORD)  = (WORD)(x)
00206     #define POKEL(s,o,x)  DOSMEM(s,o,DWORD) = (DWORD)(x)
00207   #else
00208     #define PEEKB(s,o)    PeekRealByte (((s) << 16) + (o))
00209     #define PEEKW(s,o)    PeekRealWord (((s) << 16) + (o))
00210     #define PEEKL(s,o)    PeekRealDWord(((s) << 16) + (o))
00211     #define POKEB(s,o,x)  PokeRealByte (((s) << 16) + (o), (x))
00212     #define POKEW(s,o,x)  PokeRealWord (((s) << 16) + (o), (x))
00213     #define POKEL(s,o,x)  PokeRealDWord(((s) << 16) + (o), (x))
00214   #endif
00215
00216 #elif (DOSX & PHAR286)   /* 16-bit protected mode */
00217   #include <stdio.h>
00218   #include <phapi.h>
00219
00220   #error Pharlap Lite not supported yet
00221
00222 #elif (DOSX & DJGPP)
00223   #include <dos.h>
00224   #include <dpmi.h>
00225   #include <go32.h>
00226   #include <sys/farptr.h>
00227
00228   #define PEEKB(s,o)      _farpeekb (_dos_ds, (o)+((s)<<4))
00229   #define PEEKW(s,o)      _farpeekw (_dos_ds, (o)+((s)<<4))
00230   #define PEEKL(s,o)      _farpeekl (_dos_ds, (o)+((s)<<4))
00231   #define POKEB(s,o,x)    _farpokeb (_dos_ds, (o)+((s)<<4), x)
00232   #define POKEW(s,o,x)    _farpokew (_dos_ds, (o)+((s)<<4), x)
00233   #define POKEL(s,o,x)    _farpokel (_dos_ds, (o)+((s)<<4), x)
00234   #define BOOL            int
00235
00236 #elif (DOSX & DOS4GW)
00237   #if defined(__DJGPP__)
00238     #include <dpmi.h>
00239     #include <go32.h>
00240
00241   #elif defined(__CCDL__)
00242     #include <dpmi.h>
00243     #include <i86.h>
00244   #endif
00245
00246   #include <dos.h>
00247
00248   extern WORD  _watt_dosTbSeg;
00249   extern DWORD _watt_dosTbSize;
00250
00251   #define DOSMEM(s,o,t)   *(volatile t *) (((s) << 4) | (o))
00252   #define PEEKB(s,o)      DOSMEM(s,o,BYTE)
00253   #define PEEKW(s,o)      DOSMEM(s,o,WORD)
00254   #define PEEKL(s,o)      DOSMEM(s,o,DWORD)
00255   #define POKEB(s,o,x)    DOSMEM(s,o,BYTE)  = (BYTE)(x)
00256   #define POKEW(s,o,x)    DOSMEM(s,o,WORD)  = (WORD)(x)
00257   #define POKEL(s,o,x)    DOSMEM(s,o,DWORD) = (DWORD)(x)
00258   #undef  BOOL
00259   #define BOOL int
00260
00261 #elif (DOSX & X32VM)
00262   #include <x32.h>
00263
00264   #if defined(DMC386) || defined(WATCOM386)
00265     #define HAS_FP
00266     typedef BYTE _far *FARPTR;
00267     extern FARPTR _watt_dosFp;
00268   #endif
00269
00270   extern DWORD _watt_dosTbr, _watt_dosTbSize;
00271
00272   #ifdef DMC386
00273     #define DOSMEM(s,o,t) (t*)((DWORD)_x386_zero_base_ptr + (DWORD)((o)|(s)<<4))
00274     #define PEEKB(s,o)    *DOSMEM(s,o,BYTE)
00275     #define PEEKW(s,o)    *DOSMEM(s,o,WORD)
00276     #define PEEKL(s,o)    *DOSMEM(s,o,DWORD)
00277     #define POKEB(s,o,x)  *DOSMEM(s,o,BYTE)  = (BYTE)(x)
00278     #define POKEW(s,o,x)  *DOSMEM(s,o,WORD)  = (WORD)(x)
00279     #define POKEL(s,o,x)  *DOSMEM(s,o,DWORD) = (DWORD)(x)
00280   #else
00281     #define PEEKB(s,o)    PeekRealByte (((s) << 16) + (o))
00282     #define PEEKW(s,o)    PeekRealWord (((s) << 16) + (o))
00283     #define PEEKL(s,o)    PeekRealDWord(((s) << 16) + (o))
00284     #define POKEB(s,o,x)  PokeRealByte (((s) << 16) + (o), x)
00285     #define POKEW(s,o,x)  PokeRealWord (((s) << 16) + (o), x)
00286     #define POKEL(s,o,x)  PokeRealDWord(((s) << 16) + (o), x)
00287   #endif
00288
00289   #undef  BOOL
00290   #define BOOL int
00291
00292 #elif (DOSX & POWERPAK)
00293   #include <dos.h>
00294
00295   extern WORD  _watt_dosTbSeg, _watt_dos_ds;
00296   extern DWORD _watt_dosTbr, _watt_dosTbSize;
00297
00298   #define PEEKB(s,o)      _farpeekb (_watt_dos_ds, (o)+((s)<<4))
00299   #define PEEKW(s,o)      _farpeekw (_watt_dos_ds, (o)+((s)<<4))
00300   #define PEEKL(s,o)      _farpeekl (_watt_dos_ds, (o)+((s)<<4))
00301   #define POKEB(s,o,x)    _farpokeb (_watt_dos_ds, (o)+((s)<<4), x)
00302   #define POKEW(s,o,x)    _farpokew (_watt_dos_ds, (o)+((s)<<4), x)
00303   #define POKEL(s,o,x)    _farpokel (_watt_dos_ds, (o)+((s)<<4), x)
00304   #undef  BOOL
00305   #define BOOL int
00306
00307 #elif !(DOSX & WINWATT)   /* All real-mode and non-WIN32 targets */
00308   #include <dos.h>
00309   #define  BOOL           int
00310
00311   #if defined(__WATCOMC__) || defined(_MSC_VER)
00312     #define PEEKB(s,o)    (*((BYTE  __far*) MK_FP(s,o)))
00313     #define PEEKW(s,o)    (*((WORD  __far*) MK_FP(s,o)))
00314     #define PEEKL(s,o)    (*((DWORD __far*) MK_FP(s,o)))
00315     #define POKEB(s,o,x)  (*((BYTE  __far*) MK_FP(s,o)) = (BYTE)(x))
00316     #define POKEW(s,o,x)  (*((WORD  __far*) MK_FP(s,o)) = (WORD)(x))
00317     #define POKEL(s,o,x)  (*((DWORD __far*) MK_FP(s,o)) = (DWORD)(x))
00318   #else
00319     #define PEEKB(s,o)    peekb(s,o)
00320     #define PEEKW(s,o)    (WORD) peek(s,o)
00321     #define PEEKL(s,o)    (*((DWORD far*) MK_FP(s,o)))
00322     #define POKEB(s,o,x)  pokeb (s,o,x)
00323     #define POKEW(s,o,x)  poke (s,o,x)
00324     #define POKEL(s,o,x)  (*((DWORD far*) MK_FP(s,o)) = (DWORD)(x))
00325   #endif
00326 #endif
00327
00328
00329 /* Use Pharlap's definition of a DOS-memory address;
00330  *   segment in upper 16-bits, offset in lower 16-bits.
00331  */
00332 #if !(DOSX & PHARLAP) && !defined(REALPTR) && !defined(WIN32)
00333   #define REALPTR  DWORD
00334 #endif
00335
00336 #if (DOSX)
00337   #define FARCODE
00338   #define FARDATA
00339 #else
00340   #define FARCODE  far
00341   #define FARDATA  far
00342 #endif
00343
00344 /*
00345  * Macros and hacks depending on vendor (compiler).
00346  */
00347
00348 #if defined(__TURBOC__) && (__TURBOC__ <= 0x301)
00349   #include <mem.h>
00350   #include <alloc.h>
00351
00352   #define OLD_TURBOC  /* TCC <= 2.01 doesn't have <malloc.h> and <memory.h> */
00353   #define __cdecl _Cdecl
00354   #define _far    far
00355 #elif defined(__POCC__)
00356   #include <string.h>
00357   #include <stdlib.h>
00358 #else
00359   #include <stdlib.h>
00360   #include <memory.h>
00361   #include <malloc.h>
00362 #endif
00363
00364 #if defined(__HIGHC__)
00365   #include <string.h>
00366
00367   #define max(a,b)        _max (a,b)          /* intrinsic functions */
00368   #define min(a,b)        _min (a,b)
00369   #define ENABLE()        _inline (0xFB)      /* sti */
00370   #define DISABLE()       _inline (0xFA)      /* cli */
00371 #endif
00372
00373 #if defined(_MSC_VER) && !defined(__POCC__)   /* "cl" and not "pocc -Ze" */
00374   #if (DOSX) && (DOSX != WINWATT) && (DOSX != PHARLAP)
00375     #error MSC and non-Win32 or non-Pharlap targets not supported
00376   #endif
00377
00378   #undef cdecl
00379
00380   #if (_MSC_VER <= 600)   /* A few exceptions for Quick-C <= 6.0 */
00381     #define NO_INLINE_ASM /* doesn't have built-in assembler */
00382     #define ENABLE()      _enable()
00383     #define DISABLE()     _disable()
00384     #define cdecl         _cdecl
00385   #else
00386  /* #pragma warning (disable:4103 4113 4229) */
00387  /* #pragma warning (disable:4024 4047 4761 4791) */
00388     #define ENABLE()      __asm sti
00389     #define DISABLE()     __asm cli
00390     #define asm           __asm
00391     #define cdecl         __cdecl
00392   #endif
00393
00394   #if (_MSC_VER >= 800)
00395     #pragma intrinsic (abs, memcmp, memcpy, memset)
00396     #pragma intrinsic (strcat, strcmp, strcpy, strlen)
00397     #if (DOSX == 0)
00398       #pragma intrinsic (_fmemcpy)
00399     #endif
00400   #endif
00401
00402   #if (DOSX == 0)
00403     #define interrupt     _interrupt far
00404     #define getvect(a)    _dos_getvect (a)
00405     #define setvect(a,b)  _dos_setvect (a, b)
00406     #undef  MK_FP
00407     #define MK_FP(s,o)    (void _far*) (((DWORD)(s) << 16) + (DWORD)(o))
00408   #endif
00409 #endif
00410
00411 #if defined(__TURBOC__) || defined(__BORLANDC__)
00412   #if defined(__DPMI16__)
00413     #error 16-bit DPMI version not supported
00414   #endif
00415
00416   #include <string.h>
00417
00418   #define ENABLE()        __emit__(0xFB)
00419   #define DISABLE()       __emit__(0xFA)
00420
00421   #pragma warn -bbf-     /* "Bitfields must be signed or unsigned int" warning */
00422   #pragma warn -sig-     /* "Conversion may loose significant digits" warning */
00423   #pragma warn -cln-     /* "Constant is long" warning */
00424
00425   #if defined(__DPMI32__)
00426     #pragma warn -stu-   /* structure undefined */
00427     #pragma warn -aus-   /* assigned a value that is never used */
00428   #endif
00429
00430   /* make string/memory functions inline */
00431   #if defined(__BORLANDC__) && !defined(__DPMI32__)
00432     #define strlen        __strlen__
00433     #define strncpy       __strncpy__
00434     #define strrchr       __strrchr__
00435     #define strncmp       __strncmp__
00436     #define memset        __memset__
00437     #define memcpy        __memcpy__
00438     #define memcmp        __memcmp__
00439     #define memchr        __memchr__
00440   #endif
00441 #endif
00442
00443 #if defined(__GNUC__)
00444   #if (__GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7))
00445     #error I need GCC 2.7 or later
00446   #endif
00447   #include <string.h>
00448
00449   #define __fastcall      __attribute__((__fastcall__)) /* unsupported in gcc/djgpp */
00450   #define _fastcall       __attribute__((__fastcall__))
00451
00452   #if !(DOSX & WINWATT)
00453     #define ENABLE()      __asm__ __volatile__ ("sti")
00454     #define DISABLE()     __asm__ __volatile__ ("cli")
00455   #endif
00456 #endif
00457
00458 #if defined(__WATCOMC__)
00459   #include <dos.h>
00460   #include <string.h>
00461
00462   #if !defined (_M_IX86)
00463   #error Only Watcom x86 supported
00464   #endif
00465
00466   #pragma intrinsic (strcmp, memset)
00467   #pragma warning (disable:120)
00468   #if (__WATCOMC__ >= 1220)  /* OW 1.2+ */
00469   /* #pragma warning (disable:H3006 H3007) */
00470   #endif
00471
00472   #if !(DOSX & WINWATT)
00473     #define getvect(a)      _dos_getvect (a)
00474     #define setvect(a,b)    _dos_setvect (a, b)
00475     #define BOOL            int
00476
00477     extern void ENABLE  (void);
00478     extern void DISABLE (void);
00479     #pragma aux ENABLE  = 0xFB;
00480     #pragma aux DISABLE = 0xFA;
00481   #endif
00482 #endif
00483
00484 #if defined(__DMC__) && !(DOSX & WINWATT)
00485   #include <dos.h>
00486   #include <dpmi.h>
00487   #include <string.h>
00488
00489   #define ENABLE()        enable()
00490   #define DISABLE()       disable()
00491 #endif
00492
00493 #if defined(__CCDL__) && !(DOSX & WINWATT)
00494   #include <string.h>
00495   #include <dos.h>
00496
00497   #define cdecl           _cdecl
00498   #define BOOL            int
00499   #define ENABLE()        asm sti
00500   #define DISABLE()       asm cli
00501 #endif
00502
00503 #if (DOSX & WINWATT)
00504   extern CRITICAL_SECTION _watt_crit_sect;
00505
00506   #if defined(__LCC__)
00507     #define ENTER_CRIT()    EnterCriticalSection ((struct _CRITICAL_SECTION*)&_watt_crit_sect)
00508     #define LEAVE_CRIT()    LeaveCriticalSection ((struct _CRITICAL_SECTION*)&_watt_crit_sect)
00509   #else
00510     #define ENTER_CRIT()    EnterCriticalSection (&_watt_crit_sect)
00511     #define LEAVE_CRIT()    LeaveCriticalSection (&_watt_crit_sect)
00512   #endif
00513
00514   #undef  DISABLE
00515   #define DISABLE()       ENTER_CRIT()
00516   #undef  ENABLE
00517   #define ENABLE()        LEAVE_CRIT()
00518 #else
00519   #define ENTER_CRIT()    ((void)0)
00520   #define LEAVE_CRIT()    ((void)0)
00521 #endif
00522
00523
00524 #if !defined(cdecl) && defined(__GNUC__) && defined(__MINGW32__)
00525 #define cdecl __attribute__((__cdecl__))
00526 #endif
00527
00528 #ifndef cdecl
00529 #define cdecl
00530 #endif
00531
00532 #if (DOSX & (DOS4GW|X32VM))
00533 #define HAVE_DOS_NEAR_PTR
00534 #endif
00535
00536 #ifndef max
00537 #define max(a,b)   (((a) > (b)) ? (a) : (b))
00538 #endif
00539
00540 #ifndef min
00541 #define min(a,b)   (((a) < (b)) ? (a) : (b))
00542 #endif
00543
00544 /*
00545  * Macros to hide GNU-C features.
00546  */
00547 #if defined(__GNUC__) && (__GNUC__ >= 3) && \
00548    !defined(WATT32_DOS_DLL)  /* not djgpp for DXE */
00549   #define ATTR_PRINTF(_1,_2) __attribute__((format(printf,_1,_2)))
00550   #define ATTR_SCANF(_1,_2)  __attribute__((format(scanf,_1,_2)))
00551 #else
00552   #define ATTR_PRINTF(_1,_2)
00553   #define ATTR_SCANF(_1,_2)
00554 #endif
00555
00556 #if defined(__GNUC__)
00557   #define ATTR_REGPARM(_n)   __attribute__((regparm(_n)))
00558   #define ATTR_NORETURN()    __attribute__((noreturn))
00559 #else
00560   #define ATTR_REGPARM(n)
00561   #define ATTR_NORETURN()
00562 #endif
00563
00564 #if defined(__LCC__) || defined(__POCC__)
00565   #define __FUNCTION__  __func__
00566 #elif defined(_MSC_VER) && (_MSC_VER >= 1300)
00567   /* __FUNCTION__ is built-in */
00568 #elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)
00569   #define __FUNCTION__  __func__
00570 #elif !defined(__GNUC__) && !defined(__WATCOMC__) && !defined(__DMC__)
00571   #define __FUNCTION__  "func?"
00572 #endif
00573
00574
00575 /*
00576  * Hack for Microsoft C.
00577  *
00578  * Quick-C/Visual-C insists that signal-handlers, atexit() and var-arg
00579  * functions must be defined cdecl. But e.g. Watcom's register call
00580  * doesn't need this. This becomes a problem if using _fastcall or
00581  * "cl /Gr" globally.
00582  */
00583 #if defined(_MSC_VER) && !defined(__POCC__) && !defined(WIN32)
00584   #undef  MS_CDECL
00585   #define MS_CDECL  cdecl
00586 #else
00587   #define MS_CDECL
00588 #endif
00589
00590
00591 /*
00592  * Because kbhit() will pull in more conio function that we
00593  * really need, use the simple kbhit() variant (without ungetch
00594  * option). This also prevents multiple definition trouble when
00595  * linking e.g. PD-curses and Watt-32 library.
00596  */
00597
00598 #if defined (__DJGPP__)
00599   #ifdef __dj_include_conio_h_
00600     #error "Don't include <conio.h>"
00601   #endif
00602   #include <pc.h>     /* simple kbhit() */
00603
00604 #elif defined (__HIGHC__) || defined(__WATCOMC__) || defined(__DMC__)
00605   #if defined(__portable_conio_h_) || defined(__metaware_conio_h_)
00606     #error "Don't include <mw/conio.h>"
00607   #endif
00608   #include <conio.h>  /* simple kbhit() */
00609
00610 #elif defined(_MSC_VER) && defined(__386__)
00611   /*
00612    * Problems including <conio.h> from Visual C 4.0
00613    */
00614   int __cdecl kbhit (void);
00615
00616 #else                 /* no other option */
00617   #include <conio.h>
00618 #endif
00619
00620 #endif  /* _w32_TARGET_H */
00621
Generated on Wed Jan 25 15:42:39 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/TCP_FSM.C Source File

SRC/TCP_FSM.C

Go to the documentation of this file.
00001
00007 #include <stdio.h>
00008 #include <stdlib.h>
00009 #include <string.h>
00010 #include <limits.h>
00011
00012 #include "copyrigh.h"
00013 #include "wattcp.h"
00014 #include "chksum.h"
00015 #include "strings.h"
00016 #include "misc.h"
00017 #include "timer.h"
00018 #include "sock_ini.h"
00019 #include "language.h"
00020 #include "rs232.h"
00021 #include "pcconfig.h"
00022 #include "pcqueue.h"
00023 #include "pcsed.h"
00024 #include "pcpkt.h"
00025 #include "ip4_out.h"
00026 #include "ip6_out.h"
00027 #include "ip6_in.h"
00028 #include "split.h"
00029 #include "pcdbug.h"
00030 #include "pcstat.h"
00031 #include "pctcp.h"
00032
00033 #if !defined(USE_UDP_ONLY)
00034
00035 #define flag_SYN_ACK  (tcp_FlagSYN | tcp_FlagACK)
00036 #define flag_FIN_ACK  (tcp_FlagFIN | tcp_FlagACK)
00037
00038 #if 1
00039   #define TCP_TRACE  TCP_TRACE_MSG
00040 #else
00041   #define TCP_TRACE  ((void)0)
00042 #endif
00043
00044 typedef int (*tcp_StateProc)  (_tcp_Socket**, const in_Header*, tcp_Header*, int);
00045
00046 static int  tcp_listen_state  (_tcp_Socket**, const in_Header*, tcp_Header*, int);
00047 static int  tcp_resolve_state (_tcp_Socket**, const in_Header*, tcp_Header*, int);
00048 static int  tcp_synsent_state (_tcp_Socket**, const in_Header*, tcp_Header*, int);
00049 static int  tcp_synrec_state  (_tcp_Socket**, const in_Header*, tcp_Header*, int);
00050 static int  tcp_estab_state   (_tcp_Socket**, const in_Header*, tcp_Header*, int);
00051 static int  tcp_estcl_state   (_tcp_Socket**, const in_Header*, tcp_Header*, int);
00052 static int  tcp_finwt1_state  (_tcp_Socket**, const in_Header*, tcp_Header*, int);
00053 static int  tcp_finwt2_state  (_tcp_Socket**, const in_Header*, tcp_Header*, int);
00054 static int  tcp_closewt_state (_tcp_Socket**, const in_Header*, tcp_Header*, int);
00055 static int  tcp_closing_state (_tcp_Socket**, const in_Header*, tcp_Header*, int);
00056 static int  tcp_lastack_state (_tcp_Socket**, const in_Header*, tcp_Header*, int);
00057 static int  tcp_timewt_state  (_tcp_Socket**, const in_Header*, tcp_Header*, int);
00058
00059 static int  tcp_process_data (_tcp_Socket *s, const tcp_Header *tcp, int len, int *flags);
00060 static void tcp_set_window   (_tcp_Socket *s, const tcp_Header *tcp);
00061 static int  tcp_process_ACK  (_tcp_Socket *s, long *unack);
00062
00063 static tcp_StateProc tcp_state_tab [] = {
00064   tcp_listen_state,   /* tcp_StateLISTEN  : listening for connection */
00065   tcp_resolve_state,  /* tcp_StateRESOLVE : resolving IP, waiting on ARP reply */
00066   tcp_synsent_state,  /* tcp_StateSYNSENT : SYN sent, active open */
00067   tcp_synrec_state,   /* tcp_StateSYNREC  : SYN received, SYN+ACK sent (listen TCB) */
00068   tcp_estab_state,    /* tcp_StateESTAB   : established */
00069   tcp_estcl_state,    /* tcp_StateESTCL   : established, but will FIN */
00070   tcp_finwt1_state,   /* tcp_StateFINWT1  : sent FIN */
00071   tcp_finwt2_state,   /* tcp_StateFINWT2  : sent FIN, received FIN+ACK */
00072   tcp_closewt_state,  /* tcp_StateCLOSWT  : received FIN waiting for close */
00073   tcp_closing_state,  /* tcp_StateCLOSING : sent FIN, received FIN (waiting for FIN+ACK) */
00074   tcp_lastack_state,  /* tcp_StateLASTACK : FIN received, ACK+FIN sent */
00075   tcp_timewt_state,   /* tcp_StateTIMEWT  : dally after sending final FIN+ACK */
00076 };
00077
00078 static BOOL  is_ip4;         /* TRUE: input packet is IPv4, else IPv6 */
00079 static DWORD acknum, seqnum; /* ACK/SEQ of current segment */
00080
00081 #if defined(USE_NEW_TCP_REASM)  /* not yet */
00082
00083 #define MAX_REASM_SEG 10
00084
00085 static int tcp_reassemble (_tcp_Socket *s, const tcp_Header *tcp,
00086                            UINT len, int flags);
00087
00088 struct tcp_reasm {
00089        struct {
00090          DWORD left;
00091          DWORD right;
00092        } edge [MAX_REASM_SEG];
00093        int idx;
00094      };
00095 #endif
00096
00097
00098 /*
00099  * _tcp_fsm - Our TCP-input state-machine.
00100  *
00101  *   Returns 1 to tcp_handler() if a retransmission is required
00102  *   immediately or when RTO expires.
00103  */
00104 int _tcp_fsm (_tcp_Socket **sp, const in_Header *ip)
00105 {
00106   tcp_Header  *tcp;
00107   _tcp_Socket *s = *sp;
00108   BYTE         flags;
00109   int          rc;
00110   int          in_state = s->state;
00111
00112   if (s->state >= tcp_StateCLOSED)
00113      return (0);
00114
00115   is_ip4 = (ip->ver == 4);
00116
00117 #if defined(NEED_SPLIT)
00118   tcp = (tcp_Header*) pkt_get_type_in (TYPE_TCP_HEAD)->data;
00119 #else
00120   tcp = (tcp_Header*) ((BYTE*)ip + in_GetHdrLen (ip));
00121   is_ip4 = TRUE;  /* assume IPv4 */
00122 #endif
00123
00124   acknum = intel (tcp->acknum);
00125   seqnum = intel (tcp->seqnum);
00126
00127   flags = tcp->flags & tcp_FlagMASK;
00128   rc = (*tcp_state_tab[s->state]) (sp, ip, tcp, flags);
00129   s  = *sp;
00130
00131 #if defined(USE_DEBUG)
00132   if (debug_on >= 3)
00133   {
00134     const char *st_in  = tcpStateName (in_state);
00135     const char *st_out = tcpStateName (s->state);
00136
00137     SIO_TRACE (("tcp-state: %s -> %s", st_in, st_out));
00138     TCP_CONSOLE_MSG (3, ("tcp-state: %s -> %s", st_in, st_out));
00139   }
00140 #endif
00141
00142 #if defined(USE_BSD_API)
00143   if (_bsd_socket_hook)
00144     (*_bsd_socket_hook) (BSO_DEBUG, s, in_state, s->state);
00145 #endif
00146
00147   ARGSUSED (in_state);
00148   return (rc);
00149 }
00150
00151 /*
00152  * LISTEN state
00153  */
00154 static int tcp_listen_state (_tcp_Socket **sp, const in_Header *ip,
00155                              tcp_Header *tcp, int flags)
00156 {
00157   _tcp_Socket *s = *sp;
00158
00159   SET_PEER_MAC_ADDR (s, ip);  /* save his ethernet address */
00160
00161   if ((flags & tcp_FlagSYN) == tcp_FlagSYN)
00162   {
00163 #if defined(USE_BSD_API)
00164     /*
00165      * Append the TCB `s' to the listen-queue. The new TCB on output
00166      * from `_bsd_socket_hook' is the clone of `s' on input unless the
00167      * listen-queue is full.
00168      */
00169     if (_bsd_socket_hook && !(*_bsd_socket_hook)(BSO_SYN_CALLBACK,&s))
00170     {
00171       /* Append failed due to queue full or (temporary) memory shortage.
00172        * Silently discard SYN. TCB `s' is unchanged.
00173        */
00174       CLR_PEER_MAC_ADDR (s);
00175       return (0);
00176     }
00177 #endif
00178
00179     if (is_ip4 && ip->tos > s->tos)
00180        s->tos = ip->tos;
00181
00182     s->recv_next = seqnum + 1;
00183     s->flags     = flag_SYN_ACK;
00184     s->state     = tcp_StateSYNREC;
00185     s->unhappy   = TRUE;
00186     TCP_SEND (s);            /* respond immediately */
00187
00188     s->timeout = set_timeout (tcp_TIMEOUT);
00189     STAT (tcpstats.tcps_accepts++);
00190   }
00191   else
00192   {
00193     TCP_SEND_RESET (s, ip, tcp);
00194     STAT (tcpstats.tcps_conndrops++);
00195     CLR_PEER_MAC_ADDR (s);
00196   }
00197   return (0);
00198 }
00199
00200 /*
00201  * RESOLVE state, GvB 2002-09 'inserted'
00202  * Nothing done here, the action is in pctcp.c / tcp_Retransmitter()
00203  */
00204 static int tcp_resolve_state (_tcp_Socket **sp, const in_Header *ip,
00205                               tcp_Header *tcp, int flags)
00206 {
00207   ARGSUSED (sp);
00208   ARGSUSED (ip);
00209   ARGSUSED (tcp);
00210   ARGSUSED (flags);
00211   return (1);
00212 }
00213
00214 /*
00215  * SYNSENT state
00216  */
00217 static int tcp_synsent_state (_tcp_Socket **sp, const in_Header *ip,
00218                               tcp_Header *tcp, int flags)
00219 {
00220   _tcp_Socket *s = *sp;
00221
00222   if (flags & tcp_FlagSYN)
00223   {
00224     if (is_ip4 && ip->tos > s->tos)
00225        s->tos = ip->tos;
00226
00227     s->flags   = tcp_FlagACK;
00228     s->timeout = set_timeout (tcp_TIMEOUT);
00229
00230     /* SYN+ACK means connection established, else SYNREC
00231      */
00232     if (flags & tcp_FlagACK)
00233     {
00234       /* Check the ACK value
00235        */
00236       if (acknum == s->send_next + 1)
00237       {
00238         const in6_Header *ip6 = (const in6_Header*) ip;
00239         int   len;
00240
00241         if (is_ip4)
00242              len = intel16 (ip->length) - in_GetHdrLen (ip);
00243         else len = intel16 (ip6->len);
00244
00245         s->state = tcp_StateESTAB;
00246         s->send_next++;
00247         s->recv_next = seqnum + 1;
00248
00249         /* Should be no data in SYN+ACK, but..
00250          */
00251         tcp_process_data (s, tcp, len, &flags);
00252
00253         /* Prevent retrans on no tx-data
00254          */
00255         s->unhappy = s->tx_datalen > 0 ? TRUE : FALSE;
00256
00257        /* !! Maybe use TCP_SENDSOON() to merge application data into ACK
00258         */
00259         TCP_SEND (s);
00260       }
00261       else
00262       {
00263         /* Wrong ACK, force a RST and resend SYN now
00264          */
00265         s->flags   = tcp_FlagRST;
00266         s->unhappy = TRUE;
00267         TCP_SEND (s);
00268
00269         s->send_next = INIT_SEQ();  /* !! should we set a new seq-num? */
00270         s->flags     = tcp_FlagSYN;
00271
00272 #if defined(USE_DEBUG)
00273         s->last_seqnum[0] = 0UL;
00274         s->last_seqnum[1] = 0UL;
00275 #endif
00276         TCP_SENDSOON (s);
00277       }
00278
00281     }
00282     else
00283     {
00284       s->recv_next++;
00285       s->state = tcp_StateSYNREC;  /* resend SYN in tcp_Retransmitter() */
00286       return (1);
00287     }
00288   }
00289   else
00290   {
00291     TCP_SEND_RESET (s, ip, tcp);
00292     return (0);
00293   }
00294   return (1);
00295 }
00296
00297 /*
00298  * SYNREC state (intermediate state for LISTEN to ESTABLISHED state).
00299  */
00300 static int tcp_synrec_state (_tcp_Socket **sp, const in_Header *ip,
00301                              tcp_Header *tcp, int flags)
00302 {
00303   _tcp_Socket *s = *sp;
00304
00305   if (flags & tcp_FlagSYN)  /* retransmitted SYN */
00306   {
00307     s->flags   = flag_SYN_ACK;
00308     s->unhappy = TRUE;
00309     TCP_SEND (s);
00310     s->timeout = set_timeout (tcp_TIMEOUT);
00311     return (0);
00312   }
00313
00314   if ((flags & tcp_FlagACK) && acknum == (s->send_next + 1))
00315   {
00316     tcp_set_window (s, tcp);      /* Allocate Tx-buffer based on peer's window */
00317     STAT (tcpstats.tcps_connects++);
00318     s->send_next++;
00319     s->flags   = tcp_FlagACK;
00320     s->state   = tcp_StateESTAB;
00321     s->timeout = 0UL;            /* never timeout now */
00322     s->unhappy = FALSE;
00323     return (0);
00324   }
00325   ARGSUSED (ip);
00326   return (1);
00327 }
00328
00329 /*
00330  * ESTABLISHED state
00331  */
00332 static int tcp_estab_state (_tcp_Socket **sp, const in_Header *ip,
00333                             tcp_Header *tcp, int flags)
00334 {
00335   const in6_Header *ip6 = (const in6_Header*) ip;
00336   _tcp_Socket      *s   = *sp;
00337   int   len;
00338   long  ldiff;      /* how much still ACK'ed */
00339   BOOL  did_tx;
00340
00341   /* handle lost SYN
00342    */
00343   if ((flags & tcp_FlagSYN) && (flags & tcp_FlagACK))
00344   {
00345     /* !! should check if data and process it */
00346     TCP_SEND (s);
00347     return (0);
00348   }
00349
00350   if (!(flags & tcp_FlagACK))   /* must ACK something */
00351      return (0);
00352
00353   s->timeout = 0UL;             /* we do not timeout at this point */
00354
00355   if (!tcp_process_ACK(s,&ldiff))
00356   {
00357     TCP_CONSOLE_MSG (2, ("_tcp_fsm() confused so set unacked "
00358                      "back to 0 from %ld\n", s->send_una));
00359     STAT (tcpstats.tcps_persistdrop++); /* !! a better counter? */
00360     s->send_una = 0;
00361   }
00362
00363   if (s->send_una < 0)
00364       s->send_una = 0;
00365
00366   s->flags = tcp_FlagACK;
00367
00368   if (is_ip4)
00369        len = intel16 (ip->length) - in_GetHdrLen (ip);
00370   else len = intel16 (ip6->len);
00371
00372   if (tcp_process_data (s, tcp, len, &flags) < 0)
00373   {
00374     TCP_SEND (s);  /* An out-of-order or missing segment; do fast ACK */
00375     return (1);
00376   }
00377
00378   did_tx = FALSE;
00379
00380   if (s->state != tcp_StateCLOSWT  &&
00381       (flags & tcp_FlagFIN)        &&
00382       SEQ_GEQ(s->recv_next,seqnum) &&
00383       SEQ_LT(s->recv_next,seqnum+s->adv_win))
00384   {
00385     if (s->missed_seq[0] == s->missed_seq[1])
00386     {
00387       s->recv_next++;
00388       SET_ERR_MSG (s, _LANG("Connection closed by peer"));
00389
00390       /* Implied CLOSE-WAIT -> LAST-ACK transition here
00391        */
00392       TCP_SEND (s);
00393       did_tx = TRUE;
00394
00395       TCP_CONSOLE_MSG (2, ("tcp_estab_state(): got FIN\n"));
00396
00397       s->locflags |= LF_GOT_FIN;
00398       s->flags    |= tcp_FlagFIN;    /* for tcp_Retransmitter() */
00399       s->unhappy   = TRUE;
00400       s->timeout   = set_timeout (tcp_LASTACK_TIME); /* Added AGW 6 Jan 2001 */
00401       s->state     = tcp_StateLASTACK;
00402     }
00403     else
00404     {
00405       s->unhappy = TRUE;
00406       TCP_SEND (s);  /* force a retransmit, no state change */
00407       did_tx = TRUE;
00408     }
00409   }
00410
00411   /*
00412    * Eliminate the spurious ACK messages bug.
00413    * For the window update, the length should be the
00414    * data length only, so exclude the TCP header size
00415    *  -- Joe <jdhagen@itis.com>
00416    */
00417   len -= (tcp->offset << 2);
00418   if ((ldiff > 0 && s->tx_datalen > 0) || len > 0)
00419   {
00420     /* Need to ACK and update window, but how urgent ??
00421      * We need a better criteria for doing Fast-ACK.
00422      */
00423     if (ldiff > 0 || s->adv_win < s->max_seg)
00424     {
00425       TCP_TRACE (("tcp_estab_state (%u): FastACK: ldiff %ld, "
00426                   "UNA %ld, MS-right %ld\n",
00427                   __LINE__, ldiff, s->send_una,
00428                   s->missed_seq[0] != s->missed_seq[1] ?
00429                   s->missed_seq[0] - s->recv_next : 0));
00430       s->karn_count = 0;
00431       s->flags |= tcp_FlagPUSH;
00432       TCP_SEND (s);
00433       did_tx = TRUE;
00434
00435       if (s->adv_win == 0)  /* need to open closed window in retransmitter */
00436       {
00437         s->locflags |= LF_WINUPDATE;
00438         s->unhappy = TRUE;
00439       }
00440     }
00441     else
00442     {
00443       TCP_SENDSOON (s);          /* delayed ACK */
00444       did_tx = TRUE;
00445     }
00446   }
00447
00448   /* Check if we need to reply to keep-alive segment
00449    */
00450   if (!did_tx && (len == 0) && (seqnum == s->recv_next-1) &&
00451       ((flags & tcp_FlagACK) == tcp_FlagACK) &&  /* ACK only */
00452       (s->state == tcp_StateESTAB))
00453   {
00454     s->locflags |= LF_KEEPALIVE;
00455     TCP_TRACE (("tcp_process_ACK(): Got keepalive ACK\n"));
00456     TCP_SEND (s);
00457   }
00458   return (0);
00459 }
00460
00461 /*
00462  * ESTAB_CLOSE state
00463  */
00464 static int tcp_estcl_state (_tcp_Socket **sp, const in_Header *ip,
00465                             tcp_Header *tcp, int flags)
00466 {
00467   tcp_estab_state (sp, ip, tcp, flags);
00468   _tcp_close (*sp);
00469   return (0);
00470 }
00471
00472 /*
00473  * CLOSE_WAIT state
00474  */
00475 static int tcp_closewt_state (_tcp_Socket **sp, const in_Header *ip,
00476                               tcp_Header *tcp, int flags)
00477 {
00478   return tcp_estab_state (sp, ip, tcp, flags);
00479 }
00480
00481 /*
00482  * FIN_WAIT1 state
00483  */
00484 static int tcp_finwt1_state (_tcp_Socket **sp, const in_Header *ip,
00485                              tcp_Header *tcp, int flags)
00486 {
00487   const in6_Header *ip6 = (const in6_Header*) ip;
00488   _tcp_Socket      *s   = *sp;
00489   long  ldiff;
00490   int   len;
00491
00492   if (is_ip4)
00493        len = intel16 (ip->length) - in_GetHdrLen (ip);
00494   else len = intel16 (ip6->len);
00495
00496  /* Peer may not have read all the data yet, we
00497   * must still supply it as requested
00498   */
00499   if (tcp_process_ACK(s,&ldiff))
00500   {
00501     if (ldiff == 0 || s->send_una < 0)
00502        s->send_una = 0;
00503   }
00504
00505   /* They may still be transmitting data, we must read it
00506    */
00507   tcp_process_data (s, tcp, len, &flags);
00508
00509   /* Check if peer TCP has ACK'ed all sent data and
00510    * is ready to change states. No missing segment and got FIN+ACK.
00511    */
00512   if (s->missed_seq[0] == s->missed_seq[1] &&
00513       (flags & flag_FIN_ACK) == flag_FIN_ACK)
00514   {
00515     if (seqnum == s->recv_next)
00516     {
00517       s->recv_next++;               /* we must ACK their FIN! */
00518
00519       if (SEQ_GEQ(acknum, s->send_next+1))
00520       {
00521         /* Not simultaneous close (they've ACKed our FIN)
00522          * We need to ACK their FIN and move to TIME_WAIT
00523          */
00524         s->send_next++;
00525         s->timeout = set_timeout (tcp_TIMEWT_TO);
00526         s->state   = tcp_StateTIMEWT;
00527       }
00528       else
00529       {
00530         /* Simultaneous close (haven't ACKed our FIN yet)
00531          * We need to ACK their FIN and move to CLOSING
00532          */
00533         s->timeout = set_timeout (tcp_TIMEOUT); /* !! S. Lawson, added 12.Nov 1999 */
00534         s->state   = tcp_StateCLOSING;
00535       }
00536       s->flags   = tcp_FlagACK;
00537       s->unhappy = FALSE;
00538       TCP_SEND (s);
00539     }
00540   }
00541   else if (flags & tcp_FlagACK)
00542   {
00543     /* other side is legitimately ACKing our FIN
00544      */
00545     if ((acknum == s->send_next + 1) &&
00546         (seqnum == s->recv_next)  &&
00547         (s->tx_datalen == 0))
00548     {
00549       if (!(s->locflags & LF_LINGER))
00550       {
00551         _tcp_unthread (s, TRUE);  /* enters tcp_StateCLOSED */
00552         return (0);
00553       }
00554       s->send_next++;
00555       s->state   = tcp_StateFINWT2;
00556       s->unhappy = FALSE;             /* we don't send anything */
00557       s->timeout = set_timeout (tcp_TIMEOUT);
00558     }
00559     else if ((acknum == s->send_next + 1) && (seqnum == s->recv_next + 1))
00560     {
00561      /* !! added 30-Aug 1999 GV
00562       * Try to stop that annoying retransmission bug/feature(?)
00563       * from FreeBSD 4.x which increments both SEQ and ACK.
00564       */
00565       s->send_next++;
00566       s->recv_next++;
00567       s->flags      = tcp_FlagRST;
00568       s->unhappy    = FALSE;
00569       s->karn_count = 0;
00570       s->tx_datalen = 0;
00571       TCP_SEND (s);
00572       _tcp_unthread (s, TRUE);
00573       return (0);
00574     }
00575   }
00576   return (1);
00577 }
00578
00579 /*
00580  * FIN_WAIT2 state
00581  */
00582 static int tcp_finwt2_state (_tcp_Socket **sp, const in_Header *ip,
00583                              tcp_Header *tcp, int flags)
00584 {
00585   const in6_Header *ip6 = (const in6_Header*) ip;
00586   _tcp_Socket      *s   = *sp;
00587   int   len;
00588
00589   if (is_ip4)
00590        len = intel16 (ip->length) - in_GetHdrLen (ip);
00591   else len = intel16 (ip6->len);
00592
00593   /* They may still be transmitting data, we must read it
00594    */
00595   tcp_process_data (s, tcp, len, &flags);
00596
00597   if (s->missed_seq[0] != s->missed_seq[1])
00598   {
00599     /* peer must retransmit to get all data */
00600     return (1);
00601   }
00602
00603   if (flags & tcp_FlagFIN)
00604   {
00605     TCP_CONSOLE_MSG (2, ("tcp_finwt2_state(): got FIN\n"));
00606     s->locflags |= LF_GOT_FIN;
00607   }
00608
00609   if ((flags & tcp_FlagACK)  &&
00610       acknum == s->send_next &&
00611       seqnum == s->recv_next)
00612   {
00613     s->recv_next++;
00614     s->flags   = tcp_FlagACK;
00615     s->unhappy = FALSE;
00616     s->state   = tcp_StateTIMEWT;
00617     s->timeout = set_timeout (tcp_TIMEWT_TO);
00618     TCP_SEND (s);
00619     return (0);
00620   }
00621   return (1);
00622 }
00623
00624
00625 /*
00626  * CLOSING state
00627  */
00628 static int tcp_closing_state (_tcp_Socket **sp, const in_Header *ip,
00629                               tcp_Header *tcp, int flags)
00630 {
00631   _tcp_Socket *s = *sp;
00632
00633   if ((flags & (tcp_FlagACK|tcp_FlagFIN)) == tcp_FlagACK)  /* ACK, no FIN */
00634   {
00635     /* Per FINWT1 above, acknum should be 's->send_next+1',
00636      * which should cause us to bump 's->send_next' to match.
00637      */
00638     if (SEQ_GT(acknum,s->send_next) && /* AGW - 6th Jan 2001 */
00639         seqnum == s->recv_next)
00640     {
00641       s->send_next++;
00642       s->state   = tcp_StateTIMEWT;
00643       s->unhappy = FALSE;
00644       s->timeout = set_timeout (tcp_TIMEWT_TO);
00645     }
00646   }
00647   ARGSUSED (ip);
00648   ARGSUSED (tcp);
00649   return (1);
00650 }
00651
00652 /*
00653  * LASTACK state
00654  */
00655 static int tcp_lastack_state (_tcp_Socket **sp, const in_Header *ip,
00656                               tcp_Header *tcp, int flags)
00657 {
00658   _tcp_Socket *s = *sp;
00659
00660   if (flags & tcp_FlagFIN)
00661   {
00662     /* they lost our two packets, back up
00663      */
00664     TCP_CONSOLE_MSG (2, ("tcp_lastack_state(): got FIN\n"));
00665
00666     s->locflags |= LF_GOT_FIN;
00667     s->flags     = flag_FIN_ACK;
00668     TCP_SEND (s);
00669     s->unhappy = TRUE;
00670     return (0);
00671   }
00672
00673   if (SEQ_GT(acknum,s->send_next) && /* AGW allow for any later acks 6th Jan 2001 */
00674       seqnum == s->recv_next)
00675   {
00676     s->state   = tcp_StateCLOSED;   /* no 2*MSL necessary */
00677     s->unhappy = FALSE;             /* we're done         */
00678     return (0);
00679   }
00680   ARGSUSED (ip);
00681   ARGSUSED (tcp);
00682   return (1);
00683 }
00684
00685 /*
00686  * TIMEWAIT state
00687  */
00688 static int tcp_timewt_state (_tcp_Socket **sp, const in_Header *ip,
00689                              tcp_Header *tcp, int flags)
00690 {
00691   _tcp_Socket *s = *sp;
00692
00693   if (flags & tcp_FlagACK)
00694   {
00695     /* our peer needs an FIN-ACK which is sent by tcp_Retransmitter().
00696      */
00697     s->flags   = tcp_FlagACK;
00698     s->unhappy = FALSE;
00699     s->state   = tcp_StateCLOSED;  /* support 2 MSL in RST code */
00700     TCP_SEND (s);
00701   }
00702   ARGSUSED (ip);
00703   ARGSUSED (tcp);
00704   return (1);
00705 }
00706
00707
00711 static void tcp_process_options (_tcp_Socket *s, const tcp_Header *tcp,
00712                                  const BYTE *tcp_data, int flags)
00713 {
00714   const BYTE *opt = (const BYTE*)(tcp+1);
00715   WORD  max_seg;
00716   int   num = 0;
00717
00718   /* Default to not sending timestamp
00719    */
00720   s->locflags &= ~LF_USE_TSTAMP;
00721
00722   /* Clamp # of options to prevent DoS-attack from 0-sized
00723    * unknown options.
00724    */
00725   while (opt < tcp_data && num++ < 10)
00726   {
00727     switch (*opt)
00728     {
00729       case TCPOPT_EOL:
00730            return;
00731
00732       case TCPOPT_NOP:
00733            opt++;
00734            break;
00735
00736       case TCPOPT_MAXSEG:   /* we are very liberal on MSS stuff */
00737            if (flags & tcp_FlagSYN)
00738            {
00739              max_seg = intel16 (*(WORD*)(opt+2));
00740              if (!s->max_seg || max_seg < s->max_seg)
00741              {
00742                TCP_CONSOLE_MSG (2, ("Setting MSS %u\n", max_seg));
00743                s->max_seg = max_seg;
00744              }
00745            }
00746            opt += 4;
00747            break;
00748
00749       case TCPOPT_TIMESTAMP:
00750            /* Use TS values only if SEQ is for new data.
00751             */
00752            if ((flags & tcp_FlagSYN) ||
00753                ((flags & tcp_FlagACK) &&
00754                (long)(seqnum - s->recv_next)))
00755            {
00756              s->ts_recent = intel (*(DWORD*)(opt+2));  /* echo this back */
00757              s->ts_echo   = intel (*(DWORD*)(opt+6));  /* use in RTT calc */
00758              s->locflags |= LF_USE_TSTAMP;             /* peer has this */
00759            }
00760            opt += 10;
00761            break;
00762
00763       case TCPOPT_WINDOW:
00764            if (flags & tcp_FlagSYN)
00765            {
00766              s->rx_wscale = min (TCP_MAX_WINSHIFT, *(opt+2));
00767              s->locflags |= LF_RCVD_SCALE;
00768            }
00769            opt += 3;
00770            break;
00771
00772       case TCPOPT_SACK_PERM:
00773            if (flags & tcp_FlagSYN)
00774               s->locflags |= LF_SACK_PERMIT;  /* no effect yet */
00775            opt += 2;
00776            break;
00777
00778       case TCPOPT_CHKSUM_REQ:
00779            opt += 3;
00780            break;
00781
00782       case TCPOPT_CHKSUM_DAT:
00783            opt += *(opt+1);
00784            break;
00785
00786       default:              /* unknown options; type,length,... */
00787            opt += *(opt+1);
00788            break;
00789     }
00790   }
00791 }
00792
00793
00794 /*
00795  * TCP segment processsing:
00796  *
00797  * In the tcp_Socket structure:
00798  *
00799  *   - rx_datalen is the index in the receive buffer where the next
00800  *     in-order data should be written.
00801  *   - recv_next is the TCP sequence number of the start of the next
00802  *     in-order data.
00803  *   - missed_seq[0] is the TCP sequence number of the first octet of
00804  *     the buffered out-of-order data.
00805  *   - missed_seq[1] is the TCP sequence number of the first octet
00806  *     following the buffered out-of-order data.  If missed_seq[0] and
00807  *     missed_seq[1] are equal, there is no buffered out-of-order data.
00808  *
00809  * ldiff is the difference between the received sequence number and
00810  * the expected sequence number.  If ldiff is zero or positive, and
00811  * ldiff is less than the length of the packet, data can be appended
00812  * to the receive buffer.  If ldiff is negative, data may be prepended
00813  * and/or appended to the buffered out-of-order data.
00814  *
00815  * Packets are discarded without processing if the _end_ of the packet
00816  * is before recv_next, in which case we've already processed the
00817  * data, or after the advertised receive window.
00818  *
00819  * For ldiff >= 0, there are four cases to handle:
00820  *  1) No out-of-order buffer: append the packet data and add the
00821  *     length to recv_next.
00822  *  2) No overlap with out-of-order buffer: same as (1).
00823  *  3) New data reaches but doesn't extend out-of-order buffer:
00824  *     copy up to buffer, set recv_next to missed_seq[1], and
00825  *     clear missed_seq[0] and missed_seq[1].
00826  *  4) New data extends past out-of-order buffer: same as (1),
00827  *     also clearing missed_seq[0] and missed_seq[1].
00828  *
00829  * For ldiff < 0, there are four further cases to handle:
00830  *  5) No out-of-order buffer: copy the packet data and set
00831  *     missed_seq[0] and missed_seq[1].
00832  *  6) Data starts at missed_seq[1]: append to out-of-order buffer
00833  *     and update missed_seq[1].
00834  *  7) Data extends start: copy new data and update missed_seq[0].
00835  *  8) Data extends end: copy new data and updated missed_seq[1].
00836  * Case 7 and case 8 are not exclusive.
00837  *
00838  * When an out-of-order packet is received, -1 is returned so that a
00839  * duplicate acknowledgement will be sent immediately, signalling the
00840  * peer to use fast retransmit to resend the missing data.
00841  */
00842
00843 /*
00844  * Add data at rx_datalen, updating rx_datalen and recv_next.
00845  */
00846 static void
00847 copy_in_order (_tcp_Socket *s, const BYTE *data, unsigned len)
00848 {
00849   TCP_TRACE (("copy_in_order (%u): Append %u bytes at %u-%u\n",
00850               __LINE__, len, s->rx_datalen, s->rx_datalen + len));
00851   memcpy (s->rx_data + s->rx_datalen, data, len);
00852   s->recv_next += len;
00853   s->rx_datalen += len;
00854 }
00855
00856 /*
00857  * Handle any new data that increments the 'recv_next' index.
00858  * 'ldiff >= 0'.
00859  */
00860 static void
00861 data_in_order (_tcp_Socket *s, const BYTE *data, unsigned len, unsigned diff)
00862 {
00863   /* Skip data before recv_next. We must be left with some data or
00864    * we wouldn't have been called.
00865    */
00866   data += diff;
00867   len  -= diff;
00868
00869   if (s->protoHandler)
00870   {
00871     s->recv_next += (*s->protoHandler) (s, data, len, NULL, NULL);
00872   }
00873   else if (s->missed_seq[0] == s->missed_seq[1] ||
00874            s->recv_next + len < s->missed_seq[0])
00875   {
00876     /* (1) Normal case: just copy all the data to the buffer.
00877      * (2) Received in-order doesn't catch up to buffered out-of-order.
00878      */
00879     copy_in_order (s, data, len);
00880   }
00881   else
00882   {
00883     /* (3) Received data catches up to saved out-of-order data.
00884      * (4) Received data extends beyond saved out-of-order data.
00885      */
00886     unsigned ms_end = s->missed_seq[1] - s->recv_next;
00887
00888     copy_in_order (s, data, s->missed_seq[0] - s->recv_next);
00889
00890     /* Update offset and length to incorporate out-of-order data.
00891      */
00892     TCP_TRACE (("data_in_order (%u): Use %lu out-of-order bytes\n",
00893                 __LINE__, s->missed_seq[1] - s->missed_seq[0]));
00894     s->rx_datalen += (s->missed_seq[1] - s->missed_seq[0]);
00895     s->recv_next = s->missed_seq[1];
00896     s->missed_seq[0] = s->missed_seq[1] = 0;
00897
00898     if (len > ms_end)
00899     {
00900       /* (4) Extend out-of-order data, if received past end. */
00901       copy_in_order (s, data + ms_end, len - ms_end);
00902     }
00903   }
00904
00905   TCP_TRACE (("data_in_order (%u): edges %lu/%lu, recv.next %lu\n",
00906               __LINE__, s->missed_seq[0], s->missed_seq[1],
00907               s->recv_next));
00908
00909   TCP_TRACE (("data_in_order (%u): new data now ends at %u\n",
00910               __LINE__, s->rx_datalen));
00911 }
00912
00913 /*
00914  * Add data before missed_seq[0], updating its value.
00915  */
00916 static void
00917 prepend_out_of_order (_tcp_Socket *s, const BYTE *data, unsigned len)
00918 {
00919   unsigned start = s->missed_seq[0] - s->recv_next + s->rx_datalen - len;
00920
00921   TCP_TRACE (("prepend_out_of_order (%u): Prepend %u bytes at %u-%u\n",
00922               __LINE__, len, start, start + len));
00923   memcpy (s->rx_data + start, data, len);
00924   s->missed_seq[0] -= len;
00925 }
00926
00927 /*
00928  * Add data after missed_seq[1], updating its value.
00929  */
00930 static void
00931 append_out_of_order (_tcp_Socket *s, const BYTE *data, unsigned len)
00932 {
00933   unsigned start = s->missed_seq[1] - s->recv_next + s->rx_datalen;
00934
00935   TCP_TRACE (("append_out_of_order (%u): Append %u bytes at %u-%u\n",
00936               __LINE__, len, start, start + len));
00937   memcpy (s->rx_data + start, data, len);
00938   s->missed_seq[1] += len;
00939 }
00940
00941 /*
00942  * Handle one out-of-segment packet (ldiff < 0)
00943  */
00944 static void
00945 data_out_of_order (_tcp_Socket *s, const BYTE *data, unsigned len, unsigned diff)
00946 {
00947   if (s->missed_seq[0] == s->missed_seq[1])
00948   {
00949     /* (5) First out-of-order data. */
00950     s->missed_seq[0] = s->missed_seq[1] = seqnum;
00951     append_out_of_order (s, data, len);
00952   }
00953   else if (seqnum == s->missed_seq[1])
00954   {
00955     /* (6) Common case: immediately following last out-of-order packet. */
00956     append_out_of_order (s, data, len);
00957   }
00958   else
00959   {
00960     /* Offsets from recv_next:
00961      *  - diff is offset to start of received data;
00962      *  - diff + len is offset to after received data;
00963      *  - left is offset to start of saved out-of-order data;
00964      *  - right is offset to after saved out-of-order data.
00965      */
00966     unsigned left  = s->missed_seq[0] - s->recv_next;
00967     unsigned right = s->missed_seq[1] - s->recv_next;
00968
00969     if (diff < left && left <= diff + len)
00970     {
00971       /* (7) Data extending start. */
00972       prepend_out_of_order (s, data, left - diff);
00973     }
00974
00975     if (diff <= right && right < diff + len)
00976     {
00977       /* (8) Data extending end. */
00978       append_out_of_order (s, data - diff + right, diff + len - right);
00979     }
00980   }
00981
00982   TCP_TRACE (("data_out_of_order (%u): edges %lu/%lu, recv.next %lu\n",
00983               __LINE__, s->missed_seq[0], s->missed_seq[1], s->recv_next));
00984 }
00985
00991 static int tcp_process_data (_tcp_Socket *s, const tcp_Header *tcp,
00992                              int len, int *flags)
00993 {
00994   long  ldiff;
00995   int   data_ofs;
00996   const BYTE *data;
00997
00998   if (s->stress > 0)
00999       s->stress--;
01000
01001   tcp_set_window (s, tcp);  /* this one should be redundant */
01002
01003   ldiff = (long) (s->recv_next - seqnum);
01004
01005   if (*flags & tcp_FlagSYN)
01006      ldiff--;                         /* back up to 0 */
01007
01008   /* find the data portion
01009    */
01010   data_ofs = tcp->offset << 2;        /* dword to byte offset */
01011   data     = (const BYTE*)tcp + data_ofs;
01012
01013   if (data_ofs - sizeof(*tcp) > 0)
01014      tcp_process_options (s, tcp, data, *flags);
01015
01016   if (len - data_ofs < 0)
01017   {
01018     STAT (tcpstats.tcps_rcvbadoff++);
01019     len = 0;
01020   }
01021   else
01022     len -= data_ofs;    /* remove the header length */
01023
01024   TCP_TRACE (("tcp_process_data (%u): len %u, ldiff %ld\n",
01025               __LINE__, len, ldiff));
01026
01029 #if 0
01030   if ((*flags & tcp_FlagURG) && tcp->urgent && intel16(tcp->urgent) < len)
01031   {
01032     intel16 (tcp->urgent) + seq;
01033   }
01034 #endif
01035
01036   /*
01037    * SYN/RST segments shouldn't carry any data.
01038    * But SYN-ACK can (?)
01039    */
01040   if (*flags & (tcp_FlagSYN|tcp_FlagRST))
01041      return (0);
01042
01043   if (ldiff)   /* Out-of-Sequence data */
01044   {
01045     STAT (tcpstats.tcps_rcvoopack++);
01046     STAT (tcpstats.tcps_rcvoobyte += len);
01047   }
01048   else
01049   {
01050     STAT (tcpstats.tcps_rcvpack++);
01051     STAT (tcpstats.tcps_rcvbyte += len);
01052   }
01053
01054   /* No TCP data, so nothing more to do
01055    */
01056   if (len == 0)
01057      return (0);
01058
01059   /* Check that _end_ of packet is valid, i.e. will fit in advertised window.
01060    * If it's before recv_next, we've seen it all before; if it's after
01061    * then the peer (or someone else) sent more than we said we could take.
01062    */
01063   if ((unsigned)len - ldiff > s->adv_win)
01064   {
01065     TCP_TRACE (("tcp_ProcessData (%u): packet ends outside %lu/%lu\n",
01066                 __LINE__, s->recv_next, s->recv_next + s->adv_win));
01067     return (0);
01068   }
01069
01070   /* Handle any new data that increments the 'recv_next' index
01071    */
01072
01073   if (ldiff >= 0)
01074   {
01075     data_in_order (s, data, len, ldiff);
01076     s->unhappy = (s->tx_datalen > 0);
01077     return (0);
01078   }
01079
01080   STAT (tcpstats.tcps_rcvduppack++);      /* increment dup-ACK count */
01081   STAT (tcpstats.tcps_rcvdupbyte += len);
01082
01083   /* No out-of-sequence processing of FIN flag - S. Lawson
01084    */
01085   if (*flags & tcp_FlagFIN)
01086   {
01087     TCP_TRACE (("tcp_process_data (%u): clearing FIN\n", __LINE__));
01088     *flags &= ~tcp_FlagFIN;
01089   }
01090
01091   data_out_of_order (s, data, len, -ldiff);
01092   s->unhappy = TRUE;
01093   return (-1);
01094 }
01095
01096
01097 /*
01098  * Process the ACK value in received packet, but only if it falls within
01099  * current window. Discard queued Tx-data that has been acknowledged.
01100  */
01101 static int tcp_process_ACK (_tcp_Socket *s, long *unacked)
01102 {
01103   long ldiff = (long) (acknum - s->send_next);
01104   int  diff  = (int) ldiff;
01105
01106   if (unacked)
01107      *unacked = ldiff;
01108
01109 #if 0
01110   if (ldiff > s->window)  /* peer ACK'd data not sent yet */
01111   {
01112     TCP_SEND (s);
01113     STAT (tcpstats.tcps_rcvacktoomuch++);
01114     return (1);
01115   }
01116 #endif
01117
01118   if (ldiff >= 0 && (unsigned)diff <= s->tx_datalen)
01119   {
01120     if (s->tx_queuelen)
01121     {
01122       s->tx_queue    += diff;
01123       s->tx_queuelen -= diff;
01124     }
01125     else if ((unsigned)diff < s->tx_datalen && diff > 0)
01126     {
01127       memmove (s->tx_data, s->tx_data+diff, s->tx_datalen-diff);
01128     }
01129
01130     diff = min (diff, (long)s->tx_datalen); /* protect against "nastygrams" */
01131     s->tx_datalen -= diff;
01132     s->send_una   -= diff;
01133     s->send_next  += ldiff;
01134
01135     /* If peer ACK'ed everything and all queued data sent,
01136      * stop RTT-timer
01137      */
01138     if (s->send_una == 0 && s->tx_datalen == 0)
01139        s->rtt_time = 0UL;
01140
01141     STAT (tcpstats.tcps_rcvackpack++);
01142     STAT (tcpstats.tcps_rcvackbyte += ldiff);
01143     return (1);
01144   }
01145   return (0);
01146 }
01147
01153 static void tcp_set_window (_tcp_Socket *s, const tcp_Header *tcp)
01154 {
01155   s->window = intel16 (tcp->window);
01156   if (s->window > MAX_WINDOW)
01157       s->window = MAX_WINDOW;
01158
01159 #if 0
01160   if (s->send_ssthresh == 0)
01161      s->send_ssthresh = s->window;
01162 #endif
01163
01164   if (s->tx_data == &s->tx_buf[0] &&  /* Tx-data in _tcp_Socket */
01165       s->window > s->max_tx_data)     /* His window > our Tx-size */
01166   {
01167     WORD   window = s->window;
01168     size_t size;
01169     BYTE  *buf;
01170
01171     if (_eth_ndis3pkt)       /* limit NDIS3PKT's in-transit bytes */
01172        window = min (window, 6*_mss);
01173
01174     size = window + 8;       /* add size for markers */
01175     buf  = malloc (size);
01176
01177     TCP_TRACE (("tcp_set_window (%u): buf %p, size %lu, datalen %u\n",
01178                 __LINE__, buf, (DWORD)size, s->tx_datalen));
01179     if (!buf)
01180        return;
01181
01182     *(DWORD*)buf          = SAFETY_TCP;
01183     *(DWORD*)(buf+size-4) = SAFETY_TCP;
01184     if (s->tx_datalen)
01185        memcpy (buf+4, s->tx_data, s->tx_datalen);  /* copy to new buf */
01186     s->tx_data     = buf + 4;
01187     s->max_tx_data = window - 1;
01188   }
01189 }
01190
01195 #if defined(USE_NEW_TCP_REASM)
01196
01197 static int tcp_reassemble (_tcp_Socket *s, const tcp_Header *tcp,
01198                            const BYTE *data, UINT len, int *flags)
01199 {
01200   DWORD left_edge, right_edge;
01201   long  size, ofs;
01202
01203   if (len == 0)
01204      return (0);
01205
01206   if (SEQ_EQ(seqnum, s->recv_next))
01207   {
01208     /* normal enqueue */
01209     return (0);
01210   }
01211
01212   left_edge  = s->recv_next - s->rx_datalen;
01213   right_edge = s->recv_next + s->adv_win;
01214
01215   /* segment is left of expected recv-window
01216    */
01217   if(SEQ_LEQ(seqnum, left_edge) &&
01218      SEQ_LEQ(seqnum + len, left_edge))
01219   {
01220     return (0);
01221   }
01222
01223   /* Some of the segment is left of expected recv-window
01224    */
01225   if(SEQ_LEQ(seqnum, left_edge) &&
01226      SEQ_BETWEEN(seqnum + len, left_edge+1, right_edge))
01227   {
01228     size = seqnum + len - left_edge;
01229     ofs  = left_edge - seqnum;
01230     memcpy (s->rx_data + s->rx_datalen, data + ofs, size);
01231     return (0);
01232   }
01233
01234   /* The normal case
01235    */
01236   if (SEQ_BETWEEN(seqnum,left_edge,right_edge-1) &&
01237       SEQ_GT(seqnum+len,right_edge))
01238   {
01239     size = len;
01240     ofs  = seqnum - left_edge;
01241     memcpy (s->rx_data + s->rx_datalen + ofs, data, size);
01242     s->rx_datalen += len;
01243     s->recv_next = seqnum + len;
01244     return (0);
01245   }
01246
01247   if (SEQ_GT(seqnum,right_edge))
01248   {
01249     return (0);
01250   }
01251   return (-1);   /* unexpected case */
01252 }
01253 #endif /* USE_NEW_TCP_REASM */
01254
01255 #endif /* !USE_UDP_ONLY */
01256
Generated on Wed Jan 25 15:42:39 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/TCP_MD5.C Source File

SRC/TCP_MD5.C

Go to the documentation of this file.
00001
00038 #include <stdio.h>
00039 #include <stdarg.h>
00040 #include <stdlib.h>
00041 #include <string.h>
00042
00043 #include "wattcp.h"
00044 #include "chksum.h"
00045 #include "strings.h"
00046 #include "misc.h"
00047 #include "pctcp.h"
00048 #include "tcp_md5.h"
00049
00050 #if defined(USE_TCP_MD5)
00051
00052 /* MD5 context.
00053  */
00054 typedef struct {
00055         DWORD  state [4];    /* state (ABCD) */
00056         DWORD  count [2];    /* number of bits, modulo 2^64 (LSB first) */
00057         BYTE   buffer [64];  /* input buffer */
00058       } MD5_CTX;
00059
00060 static void MD5_Init   (MD5_CTX *context);
00061 static void MD5_Update (MD5_CTX *context, const void *buffer, size_t length);
00062 static void MD5_Final  (BYTE result[16], MD5_CTX *context);
00063
00064 const char *tcp_md5_secret (void *s, const char *secret)
00065 {
00066   _tcp_Socket *sock = (_tcp_Socket*)s;
00067   char *old = sock->secret;
00068
00069   if (old)
00070      free (old);
00071   sock->secret = secret ? strdup (secret) : NULL;
00072   return (old);
00073 }
00074
00075 /*
00076  * Used to insert the MD5 signature *after* we've built the complete
00077  * TCP packet.
00078  */
00079 void make_md5_signature (const in_Header *ip, const tcp_Header *tcp,
00080                          WORD datalen, const char *secret, BYTE *buf)
00081 {
00082   struct tcp_PseudoHeader ph;
00083   struct tcp_Header       tcp_copy;
00084   const BYTE *data = (const BYTE*)tcp + (tcp->offset << 2);
00085   MD5_CTX ctx;
00086
00087   MD5_Init (&ctx);
00088
00089   /* Step 1: Update MD5 hash with IP pseudo-header.
00090    */
00091   memset (&ph, 0, sizeof(ph));
00092   ph.src      = ip->source;
00093   ph.dst      = ip->destination;
00094   ph.protocol = ip->proto;
00095   ph.length   = intel16 (datalen);
00096
00097   MD5_Update (&ctx, &ph.src, sizeof(ph.src));
00098   MD5_Update (&ctx, &ph.dst, sizeof(ph.dst));
00099   MD5_Update (&ctx, &ph.mbz, sizeof(ph.mbz));
00100   MD5_Update (&ctx, &ph.protocol, sizeof(ph.protocol));
00101   MD5_Update (&ctx, &ph.length, sizeof(ph.length));
00102
00103   /* Step 2: Update MD5 hash with TCP header, excluding options.
00104    * The TCP checksum must be set to zero.
00105    */
00106   memcpy (&tcp_copy, tcp, sizeof(tcp_copy));
00107   tcp_copy.checksum = 0;
00108   MD5_Update (&ctx, &tcp_copy, sizeof(tcp_copy));
00109
00110   /* Step 3: Update MD5 hash with TCP segment data, if present.
00111    */
00112   if (datalen > 0)
00113      MD5_Update (&ctx, data, datalen);
00114
00115   /* Step 4: Update MD5 hash with shared secret.
00116    */
00117   MD5_Update (&ctx, secret, strlen(secret));
00118   MD5_Final (buf, &ctx);
00119 }
00120
00121 /*
00122  * Check incoming TCP segment for MD5 option.
00123  */
00124 BOOL check_md5_signature (const _tcp_Socket *s, const in_Header *ip)
00125 {
00126   const struct tcp_Header *tcp;
00127   const BYTE  *recv_sign, *data, *opt;
00128   struct tcp_PseudoHeader ph;
00129   struct tcp_Header       tcp_copy;
00130
00131   BYTE    signature [16];
00132   MD5_CTX ctx;
00133   WORD    len;
00134
00135   if (!s->secret)
00136      return (FALSE);
00137
00138   WATT_ASSERT (ip->ver == 4);
00139
00140   tcp = (tcp_Header*) ((BYTE*)ip + in_GetHdrLen (ip));
00141
00142   len = intel16 (ip->length) - in_GetHdrLen (ip);
00143   len -= (tcp->offset << 2);
00144   data = (const BYTE*)tcp + (tcp->offset << 2);
00145
00146   /* find the TCPOPT_SIGNATURE signature
00147    */
00148   recv_sign = NULL;
00149   for (opt = (const BYTE*)(tcp+1); opt < data; )
00150   {
00151     if (*opt == TCPOPT_SIGNATURE)
00152     {
00153       recv_sign = opt + 2;
00154       break;
00155     }
00156     if (*opt == TCPOPT_EOL)
00157        break;
00158
00159     if (*opt == TCPOPT_NOP)
00160          opt++;
00161     else opt += *(opt+1);
00162   }
00163
00164   if (!recv_sign || opt[1] != TCPOPT_SIGN_LEN)
00165      return (FALSE);
00166
00167   MD5_Init (&ctx);
00168
00169   /* Step 1: Update MD5 hash with IP pseudo-header.
00170    */
00171   memset (&ph, 0, sizeof(ph));
00172   ph.src      = ip->source;
00173   ph.dst      = ip->destination;
00174   ph.protocol = ip->proto;
00175   ph.length   = intel16 (len);
00176
00177   MD5_Update (&ctx, &ph.src, sizeof(ph.src));
00178   MD5_Update (&ctx, &ph.dst, sizeof(ph.dst));
00179   MD5_Update (&ctx, &ph.mbz, sizeof(ph.mbz));
00180   MD5_Update (&ctx, &ph.protocol, sizeof(ph.protocol));
00181   MD5_Update (&ctx, &ph.length, sizeof(ph.length));
00182
00183   /* Step 2: Update MD5 hash with TCP header, excluding options.
00184    * The TCP checksum must be set to zero.
00185    */
00186   memcpy (&tcp_copy, tcp, sizeof(tcp_copy));
00187   tcp_copy.checksum = 0;
00188   MD5_Update (&ctx, &tcp_copy, sizeof(tcp_copy));
00189
00190   /* Step 3: Update MD5 hash with TCP segment data, if present.
00191    */
00192   if (len > 0)
00193      MD5_Update (&ctx, data, len);
00194
00195   /* Step 4: Update MD5 hash with shared secret.
00196    */
00197   MD5_Update (&ctx, s->secret, strlen(s->secret));
00198   MD5_Final (signature, &ctx);
00199
00200   if (!memcmp(recv_sign, signature, sizeof(signature)))
00201      return (TRUE);
00202   return (FALSE);
00203 }
00204
00205 /*
00206  * taken from RFC-1321/Appendix A.3
00207  * MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
00208  */
00209
00210 /*
00211  * Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All rights
00212  * reserved.
00213  *
00214  * License to copy and use this software is granted provided that it is
00215  * identified as the "RSA Data Security, Inc. MD5 Message-Digest Algorithm"
00216  * in all material mentioning or referencing this software or this function.
00217  *
00218  * License is also granted to make and use derivative works provided that such
00219  * works are identified as "derived from the RSA Data Security, Inc. MD5
00220  * Message-Digest Algorithm" in all material mentioning or referencing the
00221  * derived work.
00222  *
00223  * RSA Data Security, Inc. makes no representations concerning either the
00224  * merchantability of this software or the suitability of this software for
00225  * any particular purpose. It is provided "as is" without express or implied
00226  * warranty of any kind.
00227  *
00228  * These notices must be retained in any copies of any part of this
00229  * documentation and/or software.
00230  */
00231
00232 /*
00233  * Constants for MD5Transform routine.
00234  */
00235 #define S11    7
00236 #define S12   12
00237 #define S13   17
00238 #define S14   22
00239 #define S21    5
00240 #define S22    9
00241 #define S23   14
00242 #define S24   20
00243 #define S31    4
00244 #define S32   11
00245 #define S33   16
00246 #define S34   23
00247 #define S41    6
00248 #define S42   10
00249 #define S43   15
00250 #define S44   21
00251
00252 static void Transform (DWORD[4], const BYTE *);
00253 static void Encode    (BYTE *, const DWORD *, size_t);
00254 static void Decode    (DWORD *, const BYTE *, size_t);
00255
00256 static BYTE padding[64] = {
00257        0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00258        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00259        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00260        0, 0
00261      };
00262
00263 /*
00264  * F, G, H and I are basic MD5 functions.
00265  */
00266 #define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
00267 #define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
00268 #define H(x, y, z) ((x) ^ (y) ^ (z))
00269 #define I(x, y, z) ((y) ^ ((x) | (~z)))
00270
00271 /*
00272  * ROTATE_LEFT rotates x left n bits.
00273  */
00274 #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
00275
00276 /*
00277  * FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4. Rotation is
00278  * separate from addition to prevent recomputation.
00279  */
00280 #define FF(a, b, c, d, x, s, ac) {                    \
00281         (a) += F ((b), (c), (d)) + (x) + (DWORD)(ac); \
00282         (a) = ROTATE_LEFT ((a), (s));                 \
00283         (a) += (b);                                   \
00284       }
00285 #define GG(a, b, c, d, x, s, ac) {                    \
00286         (a) += G ((b), (c), (d)) + (x) + (DWORD)(ac); \
00287         (a) = ROTATE_LEFT ((a), (s));                 \
00288         (a) += (b);                                   \
00289       }
00290 #define HH(a, b, c, d, x, s, ac) {                    \
00291         (a) += H ((b), (c), (d)) + (x) + (DWORD)(ac); \
00292         (a) = ROTATE_LEFT ((a), (s));                 \
00293         (a) += (b);                                   \
00294       }
00295 #define II(a, b, c, d, x, s, ac) {                    \
00296         (a) += I ((b), (c), (d)) + (x) + (DWORD)(ac); \
00297         (a) = ROTATE_LEFT ((a), (s));                 \
00298         (a) += (b);                                   \
00299       }
00300
00301 /*
00302  * MD5 initialization. Begins an MD5 operation, writing a new context.
00303  */
00304 static void MD5_Init (MD5_CTX *context)
00305 {
00306   context->count[0] = context->count[1] = 0;
00307
00308   /* Load magic initialization constants.
00309    */
00310   context->state[0] = 0x67452301;
00311   context->state[1] = 0xefcdab89;
00312   context->state[2] = 0x98badcfe;
00313   context->state[3] = 0x10325476;
00314 }
00315
00316 /*
00317  * MD5 block update operation. Continues an MD5 message-digest operation,
00318  * processing another message block, and updating the context.
00319  */
00320 static void MD5_Update (MD5_CTX    *context,    /* context */
00321                         const void *input,      /* input block */
00322                         size_t      inputLen)   /* length of input block */
00323 {
00324   DWORD i, index, partLen;
00325
00326   /* Compute number of bytes mod 64 */
00327   index = (DWORD) ((context->count[0] >> 3) & 0x3F);
00328
00329   /* Update number of bits */
00330   if ((context->count[0] += ((DWORD)inputLen << 3)) < ((DWORD)inputLen << 3))
00331        context->count[1]++;
00332   context->count[1] += ((DWORD)inputLen >> 29);
00333
00334   partLen = 64 - index;
00335
00336   /* Transform as many times as possible.
00337    */
00338   if (inputLen >= partLen)
00339   {
00340     memcpy (&context->buffer[index], input, partLen);
00341     Transform (context->state, context->buffer);
00342
00343     for (i = partLen; i + 63 < inputLen; i += 64)
00344         Transform (context->state, (const BYTE*)input+i);
00345     index = 0;
00346   }
00347   else
00348     i = 0;
00349
00350   /* Buffer remaining input */
00351   memcpy (&context->buffer[index], (const char*)input+i, inputLen-i);
00352 }
00353
00354 /*
00355  * MD5 finalization. Ends an MD5 message-digest operation, writing the
00356  * message digest and zeroizing the context.
00357  */
00358 static void MD5_Final (BYTE    digest[16],  /* message digest */
00359                        MD5_CTX *context)    /* context */
00360 {
00361   BYTE  bits[8];
00362   DWORD index, padLen;
00363
00364   /* Save number of bits */
00365   Encode (bits, context->count, 8);
00366
00367   /* Pad out to 56 mod 64. */
00368   index  = (DWORD) ((context->count[0] >> 3) & 0x3f);
00369   padLen = (index < 56) ? (56 - index) : (120 - index);
00370   MD5_Update (context, padding, padLen);
00371
00372   /* Append length (before padding) */
00373   MD5_Update (context, bits, 8);
00374
00375   /* Store state in digest */
00376   Encode (digest, context->state, 16);
00377
00378   /* Zeroize sensitive information. */
00379   memset (context, 0, sizeof(*context));
00380 }
00381
00382 /*
00383  * MD5 basic transformation. Transforms state based on block.
00384  */
00385 static void Transform (DWORD state[4], const BYTE *block)
00386 {
00387   DWORD a = state[0];
00388   DWORD b = state[1];
00389   DWORD c = state[2];
00390   DWORD d = state[3];
00391   DWORD x[16];
00392
00393   Decode (x, block, 64);
00394
00395   /* Round 1 */
00396   FF (a, b, c, d, x[0],  S11, 0xd76aa478); /* 1  */
00397   FF (d, a, b, c, x[1],  S12, 0xe8c7b756); /* 2  */
00398   FF (c, d, a, b, x[2],  S13, 0x242070db); /* 3  */
00399   FF (b, c, d, a, x[3],  S14, 0xc1bdceee); /* 4  */
00400   FF (a, b, c, d, x[4],  S11, 0xf57c0faf); /* 5  */
00401   FF (d, a, b, c, x[5],  S12, 0x4787c62a); /* 6  */
00402   FF (c, d, a, b, x[6],  S13, 0xa8304613); /* 7  */
00403   FF (b, c, d, a, x[7],  S14, 0xfd469501); /* 8  */
00404   FF (a, b, c, d, x[8],  S11, 0x698098d8); /* 9  */
00405   FF (d, a, b, c, x[9],  S12, 0x8b44f7af); /* 10 */
00406   FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
00407   FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
00408   FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
00409   FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
00410   FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
00411   FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
00412
00413   /* Round 2 */
00414   GG (a, b, c, d, x[1],  S21, 0xf61e2562); /* 17 */
00415   GG (d, a, b, c, x[6],  S22, 0xc040b340); /* 18 */
00416   GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
00417   GG (b, c, d, a, x[0],  S24, 0xe9b6c7aa); /* 20 */
00418   GG (a, b, c, d, x[5],  S21, 0xd62f105d); /* 21 */
00419   GG (d, a, b, c, x[10], S22, 0x2441453);  /* 22 */
00420   GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
00421   GG (b, c, d, a, x[4],  S24, 0xe7d3fbc8); /* 24 */
00422   GG (a, b, c, d, x[9],  S21, 0x21e1cde6); /* 25 */
00423   GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
00424   GG (c, d, a, b, x[3],  S23, 0xf4d50d87); /* 27 */
00425   GG (b, c, d, a, x[8],  S24, 0x455a14ed); /* 28 */
00426   GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
00427   GG (d, a, b, c, x[2],  S22, 0xfcefa3f8); /* 30 */
00428   GG (c, d, a, b, x[7],  S23, 0x676f02d9); /* 31 */
00429   GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
00430
00431   /* Round 3 */
00432   HH (a, b, c, d, x[5],  S31, 0xfffa3942); /* 33 */
00433   HH (d, a, b, c, x[8],  S32, 0x8771f681); /* 34 */
00434   HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
00435   HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
00436   HH (a, b, c, d, x[1],  S31, 0xa4beea44); /* 37 */
00437   HH (d, a, b, c, x[4],  S32, 0x4bdecfa9); /* 38 */
00438   HH (c, d, a, b, x[7],  S33, 0xf6bb4b60); /* 39 */
00439   HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
00440   HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
00441   HH (d, a, b, c, x[0],  S32, 0xeaa127fa); /* 42 */
00442   HH (c, d, a, b, x[3],  S33, 0xd4ef3085); /* 43 */
00443   HH (b, c, d, a, x[6],  S34, 0x4881d05);  /* 44 */
00444   HH (a, b, c, d, x[9],  S31, 0xd9d4d039); /* 45 */
00445   HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
00446   HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
00447   HH (b, c, d, a, x[2],  S34, 0xc4ac5665); /* 48 */
00448
00449   /* Round 4 */
00450   II (a, b, c, d, x[0],  S41, 0xf4292244); /* 49 */
00451   II (d, a, b, c, x[7],  S42, 0x432aff97); /* 50 */
00452   II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
00453   II (b, c, d, a, x[5],  S44, 0xfc93a039); /* 52 */
00454   II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
00455   II (d, a, b, c, x[3],  S42, 0x8f0ccc92); /* 54 */
00456   II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
00457   II (b, c, d, a, x[1],  S44, 0x85845dd1); /* 56 */
00458   II (a, b, c, d, x[8],  S41, 0x6fa87e4f); /* 57 */
00459   II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
00460   II (c, d, a, b, x[6],  S43, 0xa3014314); /* 59 */
00461   II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
00462   II (a, b, c, d, x[4],  S41, 0xf7537e82); /* 61 */
00463   II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
00464   II (c, d, a, b, x[2],  S43, 0x2ad7d2bb); /* 63 */
00465   II (b, c, d, a, x[9],  S44, 0xeb86d391); /* 64 */
00466
00467   state[0] += a;
00468   state[1] += b;
00469   state[2] += c;
00470   state[3] += d;
00471
00472   /* Zeroize sensitive information. */
00473   memset (&x, 0, sizeof(x));
00474 }
00475
00476 /*
00477  * Encodes input (DWORD) into output (BYTE). Assumes len is a
00478  * multiple of 4.
00479  */
00480 static void Encode (BYTE *output, const DWORD *input, size_t len)
00481 {
00482   size_t i, j;
00483
00484   for (i = 0, j = 0; j < len; i++, j += 4)
00485   {
00486 #if 0
00487     output[j]   = (BYTE) (input[i] & 0xff);
00488     output[j+1] = (BYTE) ((input[i] >> 8) & 0xff);
00489     output[j+2] = (BYTE) ((input[i] >> 16) & 0xff);
00490     output[j+3] = (BYTE) ((input[i] >> 24) & 0xff);
00491 #else
00492     *(DWORD*) (output+j) = intel (input[i]);
00493 #endif
00494   }
00495 }
00496
00497 /*
00498  * Decodes input (BYTE) into output (DWORD). Assumes len is a
00499  * multiple of 4.
00500  */
00501 static void Decode (DWORD *output, const BYTE *input, size_t len)
00502 {
00503   size_t i, j;
00504
00505   for (i = 0, j = 0; j < len; i++, j += 4)
00506 #if 0
00507       output[i] = ((DWORD)input[j]) |
00508                   (((DWORD)input[j+1]) << 8) |
00509                   (((DWORD)input[j+2]) << 16) |
00510                   (((DWORD)input[j+3]) << 24);
00511 #else
00512       output[i] = intel (*(DWORD*)(input+j));
00513 #endif
00514 }
00515
00516 #endif  /* USE_TCP_MD5 */
Generated on Wed Jan 25 15:42:39 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/TCP_MD5.H Source File

SRC/TCP_MD5.H

Go to the documentation of this file.
00001
00003 #ifndef _w32_TCP_MD5_H
00004 #define _w32_TCP_MD5_H
00005
00006 #define make_md5_signature   NAMESPACE (make_md5_signature)
00007 #define check_md5_signature  NAMESPACE (check_md5_signature)
00008
00009 /* At the momement, this is the only public interface.
00010  */
00011 extern const char *tcp_md5_secret (void *s, const char *secret);
00012
00013 extern void make_md5_signature (const in_Header  *ip,
00014                                 const tcp_Header *tcp,
00015                                 WORD datalen, const char *secret,
00016                                 BYTE *buf);
00017
00018 extern BOOL check_md5_signature (const _tcp_Socket *s,
00019                                  const in_Header *ip);
00020
00021 #endif
Generated on Wed Jan 25 15:42:39 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/TEREDO64.C Source File

SRC/TEREDO64.C

00001 /*
00002  * IPv6 tunneling over UDP/IPv4
00003  *
00004  * Refs:
00005  *  http://www.ietf.org/internet-drafts/draft-huitema-v6ops-teredo-00.txt
00006  *  http://www.microsoft.com/technet/treeview/default.asp?url=/technet/prodtechnol/winxppro/maintain/Teredo.asp
00007  */
00008 #include "teredo64.h"
00009
00010 /* 3FFE:831F::/32 */
00011 const struct in6_addr in6addr_teredo_pfx = {{ 0x3F, 0xFE, 0x83, 0x1F,
00012                                               0,0,0,0,0, 0,0,0,0,
00013                                               0,0,0,0,0 }};
00014
00015 /*
00016  * make_ipv6 teredo addr from
00017  *  dest_host, port, is_cone_nat:
00018  *
00019  *   prefix + ip4_host + (0x8000 * is_cone_nat) + (port ^0xFFFF)
00020  */
00021
Generated on Wed Jan 25 15:42:39 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/TEREDO64.H Source File

SRC/TEREDO64.H

Go to the documentation of this file.
00001
00003 #ifndef _w32_TEREDO64_H
00004 #define _w32_TEREDO64_H
00005
00006 #endif
Generated on Wed Jan 25 15:42:39 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/TFTP.C Source File

SRC/TFTP.C

Go to the documentation of this file.
00001
00037 #include "socket.h"
00038 #include "udp_dom.h"
00039 #include "tftp.h"
00040
00041 #if defined(USE_TFTP)
00042
00043 #if defined(USE_DEBUG)
00044   #define TRACE(x)  (*_printf) x
00045 #else
00046   #define TRACE(x)  ((void)0)
00047 #endif
00048
00049
00050 /*
00051  * Error codes private to this file:
00052  */
00053 #define ERR_INV       1       /* invalid packet size */
00054 #define ERR_ERR       2       /* error packet received */
00055 #define ERR_OP        3       /* invalid opcode */
00056 #define ERR_BLOCK     4       /* invalid block number */
00057 #define ERR_TIMEOUT   5       /* timeout while receiving */
00058 #define ERR_UNKNOWN   6       /* unknown error */
00059
00060 /*
00061  * Various definitions:
00062  */
00063 #define TFTP_RETRY      5          /* Maximum number of retries */
00064 #define TFTP_TIMEOUT    8          /* Default 8 seconds timeout */
00065 #define TFTP_HEADSIZE   4          /* th_opcode/th_block size */
00066 #define TFTP_PORT_LOW   1024       /* lowest legal local port */
00067 #define TFTP_PORT_HIGH  USHRT_MAX  /* higest legal local port */
00068 #define OCTET_STR       "octet"    /* name for 8-bit raw format */
00069 #define NETASCII_STR    "netascii" /* name for netascii format */
00070 #define MAIL_STR        "mail"     /* name for mail format */
00071
00072 /*
00073  * Public data
00074  */
00075 int (*tftp_writer) (const void*, size_t) = NULL;
00076 int (*tftp_terminator) (void)            = NULL;
00077
00078 /*
00079  * Local variables
00080  */
00081 static struct tftphdr *inbuf;    /* TFTP input buffer  */
00082 static struct tftphdr *outbuf;   /* TFTP output buffer */
00083 static sock_type      *sock;     /* Socket for UDP recv/xmit */
00084
00085 static DWORD currblock;          /* Current data block           */
00086 static int   blocksize;          /* Server's block size          */
00087 static int   ibuflen;            /* Size of data in input buffer */
00088 static int   isopen;             /* TRUE if connection is open   */
00089
00090 static int   tftp_errno   = 0;
00091 static DWORD tftp_server  = 0;
00092 static int   tftp_timeout = TFTP_TIMEOUT;
00093 static int   tftp_retry   = TFTP_RETRY;
00094 static int   tftp_lport   = 0;
00095
00096 static char  tftp_server_name[MAX_HOSTLEN]  = "";
00097 static char  tftp_xfer_mode  [MAX_VALUELEN] = OCTET_STR;
00098 static char *tftp_boot_remote_file = NULL;
00099 static char *tftp_boot_local_file  = NULL;
00100 static char *tftp_openmode         = NULL;
00101
00102 /*
00103  * Send a tftp request packet
00104  */
00105 static void send_req (char request, const char *fname)
00106 {
00107   char *cp, *mode;
00108   int   len;
00109   int   fnamlen = strlen (fname);
00110
00111   /* The output buffer is setup with the request code, the file name,
00112    * and the name of the data format.
00113    */
00114   memset (outbuf, 0, sizeof(*outbuf));
00115   outbuf->th_opcode = intel16 (request);
00116   len = SEGSIZE - sizeof(outbuf->th_opcode) - strlen(tftp_xfer_mode) - 1;
00117   cp  = (char*) &outbuf->th_stuff[0];
00118
00119   for ( ; *fname && len > 0 && fnamlen > 0; len--, fnamlen--)
00120       *cp++ = *fname++;
00121   *cp++ = '\0';
00122
00123   for (mode = tftp_xfer_mode; *mode; )
00124       *cp++ = *mode++;
00125   *cp++ = '\0';
00126
00127   /* Finally send the request
00128    */
00129   len = (int) (cp - (char*)outbuf);
00130   sock_fastwrite (sock, (BYTE*)outbuf, len);
00131 }
00132
00133
00134 /*
00135  * Send a tftp acknowledge packet
00136  */
00137 static void send_ack (WORD block)
00138 {
00139   struct tftphdr ack;
00140
00141   ack.th_opcode = intel16 (ACK);
00142   ack.th_block  = intel16 (block);
00143   sock_fastwrite (sock, (BYTE*)&ack, TFTP_HEADSIZE);
00144 }
00145
00146 #if defined(USE_DEBUG)
00147 /*
00148  * Return error string for 'th_code'
00149  */
00150 static const char *tftp_strerror (int code)
00151 {
00152   static const char *err_tab[] = {
00153                     "EUNDEF",
00154                     "ENOTFOUND",
00155                     "EACCESS",
00156                     "ENOSPACE",
00157                     "EBADOP",
00158                     "EBADID",
00159                     "EEXISTS",
00160                     "ENOUSER",
00161                     "EOPTNEG"
00162                   };
00163   if (code < 0 || code >= DIM(err_tab))
00164      return ("?");
00165   return (err_tab[code]);
00166 }
00167 #endif
00168
00169
00170 /*
00171  * Watch out for "ICMP port unreachable".
00172  */
00173 static void udp_callback (_udp_Socket *s, int icmp_type, int icmp_code)
00174 {
00175   if (s->ip_type == UDP_PROTO && s == (_udp_Socket*)sock &&
00176       (s->locflags & LF_GOT_ICMP) && icmp_type == ICMP_UNREACH)
00177   {
00178     /* In lack of a better way, pretend we got a FIN.
00179      * This causes sock_wait_input() below to break it's loop.
00180      */
00181     s->locflags |= LF_GOT_FIN;
00182     s->err_msg = icmp_type_str [ICMP_UNREACH];
00183   }
00184   ARGSUSED (icmp_code);
00185 }
00186
00187 /*
00188  * Receive a TFTP data packet
00189  */
00190 static int recv_packet (DWORD block)
00191 {
00192   int len, status = 0;
00193
00194   /* Use a callback since first block sent might cause a "ICMP
00195    * port unreachable" to be sent back. Note that the normal mechanism
00196    * of detecting ICMP errors (through _udp_cancel) doesn't work since
00197    * we did set 'sock->udp.hisaddr = 0'.
00198    *
00199    * Note: 'block' is 32-bit, but 16-bit in tftp-header.
00200    *       We allow the header block-counter to wrap (allowing > 32MB files).
00201    */
00202   if (block == 1UL)
00203        sock->udp.icmp_callb = (icmp_upcall) udp_callback;
00204   else sock->udp.icmp_callb = NULL;
00205
00206   /* Read packet with timeout
00207    */
00208   sock_wait_input (sock, tftp_timeout, NULL, &status);
00209
00210   len = sock_fastread (sock, (BYTE*)inbuf, TFTP_HEADSIZE+SEGSIZE);
00211
00212   /* Check that the packet has a correct length
00213    */
00214   len -= TFTP_HEADSIZE;
00215   if (len < 0 || len > SEGSIZE)
00216   {
00217     TRACE (("tftp: Invalid packet, len = %d\n", len));
00218     tftp_errno = ERR_INV;
00219     return (-1);
00220   }
00221
00222   /* Check if we got an error packet
00223    */
00224   if (intel16(inbuf->th_opcode) == ERROR)
00225   {
00226 #if defined(USE_DEBUG)
00227     int   code = intel16 (inbuf->th_code);
00228     const char *str = tftp_strerror (code);
00229
00230     TRACE (("tftp: Error: %s (%d): %.*s\n",
00231             str, code, SEGSIZE, inbuf->th_data));
00232 #endif
00233     tftp_errno = ERR_ERR;
00234     return (-1);
00235   }
00236
00237   /* Check if we got a valid data packet at all
00238    */
00239   if (intel16(inbuf->th_opcode) != DATA)
00240   {
00241     TRACE (("tftp: Invalid opcode %d\n", intel16(inbuf->th_opcode)));
00242     tftp_errno = ERR_OP;
00243     return (-1);
00244   }
00245
00246   /* Check if the block number of the data packet is correct
00247    */
00248   if (intel16(inbuf->th_block) != (WORD)block)
00249   {
00250     TRACE (("tftp: Block %u != %u\n", intel16(inbuf->th_block), (WORD)block));
00251     tftp_errno = ERR_BLOCK;
00252     return (-1);
00253   }
00254
00255   tftp_errno = 0;
00256   if (debug_on)
00257      (*_outch) ('#');  /* Write 1 hash-mark per block */
00258
00259   return (len);
00260
00261 sock_err:
00262   if (status == -1)
00263   {
00264     if (debug_on)
00265        (*_outch) ('T');
00266
00267     tftp_errno = ERR_TIMEOUT;
00268     return (-1);
00269   }
00270
00271   /* most likely "Port unreachable"
00272    */
00273   TRACE (("tftp: %s\n", sockerr(sock)));
00274   tftp_errno = ERR_UNKNOWN;
00275   return (-1);
00276 }
00277
00278
00279 /*
00280  * Open a TFTP connection on a random local port (our transaction ID).
00281  * Send the request, wait for first data block and send the first ACK.
00282  */
00283 static int tftp_open (DWORD server, const char *fname)
00284 {
00285   int  retry;
00286   WORD port = 69;
00287
00288 #if defined(USE_BSD_API)
00289   struct servent *sp = getservbyname ("tftp", "udp");
00290
00291   if (sp)
00292      port = intel16 ((WORD)sp->s_port);
00293 #endif
00294
00295   currblock = 0UL;
00296   blocksize = 0;
00297
00298   for (retry = 0; retry < tftp_retry; retry++)
00299   {
00300     WORD our_tid;  /* our transaction ID (local port) */
00301
00302     if (tftp_lport && tftp_lport < TFTP_PORT_LOW)
00303        outsnl (_LANG("tftp: Illegal local port."));
00304
00305     if (tftp_lport >= TFTP_PORT_LOW)
00306          our_tid = tftp_lport;
00307     else our_tid = Random (TFTP_PORT_LOW, TFTP_PORT_HIGH);
00308
00309     /* Try to open a TFTP connection to the server
00310      */
00311     if (!udp_open(&sock->udp, our_tid, server, port, NULL))
00312     {
00313       TRACE (("tftp: %s\n", sockerr(sock)));
00314       return (0);
00315     }
00316     sock->udp.locflags |= LF_NOCLOSE;  /* don't close socket on timeout */
00317
00318     /* Send the file request block, and then wait for the first data
00319      * block. If there is no response to the query, retry it with
00320      * another transaction ID (local port), so that all old packets get
00321      * discarded automatically.
00322      */
00323     send_req (RRQ, fname);
00324
00325     /* This hack makes it work because the response is sent back on
00326      * a source-port different from port 69; i.e. the server TID
00327      * uses a random port. Force the response packet to match a passive
00328      * socket in udp_handler().
00329      */
00330     sock->udp.hisaddr = 0;
00331
00332     ibuflen = recv_packet (1);
00333     if (ibuflen >= 0)
00334     {
00335       blocksize = ibuflen;
00336       isopen = TRUE;
00337       send_ack (1);
00338       return (1);
00339     }
00340
00341     /* If an error (except timeout) occurred, retries are useless
00342      */
00343     if (tftp_errno == ERR_ERR || tftp_errno == ERR_UNKNOWN)
00344        break;
00345   }
00346   return (0);
00347 }
00348
00349 /*
00350  * Close the TFTP connection
00351  */
00352 static void tftp_close (void)
00353 {
00354   if (tftp_terminator)
00355     (*tftp_terminator)();
00356
00357   if (debug_on)
00358      outs ("\n");
00359
00360   if (sock)
00361   {
00362     sock_close (sock);
00363     free (sock);
00364     sock = NULL;
00365   }
00366   DO_FREE (inbuf);
00367   DO_FREE (outbuf);
00368 }
00369
00370 /*
00371  * Set the name of TFTP server
00372  */
00373 char *tftp_set_server (const char *name, int len)
00374 {
00375   len = min (len+1, SIZEOF(tftp_server_name));
00376   return StrLcpy (tftp_server_name, name, len);
00377 }
00378
00379 /*
00380  * Set the name of remote/local file to load from TFTP server.
00381  * Format is "tftp.boot_file = remote [local].
00382  * Note: `remote' name cannot contain spaces.
00383  */
00384 char *tftp_set_boot_fname (const char *name, int len)
00385 {
00386   char *p, buf [MAX_PATHLEN];
00387
00388   len = min (len+1, SIZEOF(buf));
00389   StrLcpy (buf, name, len);
00390   tftp_boot_remote_file = strdup (buf);
00391   tftp_boot_local_file  = tftp_boot_remote_file;
00392
00393   if (tftp_boot_local_file)
00394   {
00395     p = strchr (tftp_boot_local_file, ' ');
00396     if (p)
00397     {
00398       *p++ = '\0';
00399       tftp_boot_local_file = p;
00400     }
00401   }
00402   return (tftp_boot_remote_file);
00403 }
00404
00405 /*
00406  * Set the mode used for transfer
00407  */
00408 static char *tftp_set_xfer_mode (const char *name)
00409 {
00410   return StrLcpy (tftp_xfer_mode, name, sizeof(tftp_xfer_mode));
00411 }
00412
00413 /*
00414  * Read the next data packet from a TFTP connection
00415  */
00416 static int tftp_get_block (const char **buf)
00417 {
00418   int retry;
00419
00420   /* Don't do anything if no TFTP connection is active.
00421    */
00422   if (!isopen)
00423      return (0);
00424
00425   /* If the block number is 0 then we are still dealing with the first
00426    * data block after opening a connection. If the data size is smaller
00427    * than 'blocksize' just close the connection again.
00428    */
00429   if (currblock == 0UL)
00430   {
00431     currblock++;
00432     if (ibuflen < blocksize)
00433        isopen = FALSE;
00434     *buf = (const char*) &inbuf->th_data[0];
00435     return (ibuflen);
00436   }
00437
00438   /* Wait for the next data packet. If no data packet is coming in,
00439    * resend the ACK for the last packet to restart the sender. Maybe
00440    * he didn't get our first ACK.
00441    */
00442   for (retry = 0; retry < tftp_retry; retry++)
00443   {
00444     ibuflen = recv_packet (currblock+1);
00445     if (ibuflen >= 0)
00446     {
00447       currblock++;
00448       send_ack ((WORD)currblock);
00449       if (ibuflen < blocksize)  /* last block received */
00450          isopen = FALSE;
00451       *buf = (const char*) &inbuf->th_data[0];
00452       return (ibuflen);
00453     }
00454     if (tftp_errno == ERR_ERR || tftp_errno == ERR_UNKNOWN)
00455        break;
00456
00457     send_ack ((WORD)currblock);
00458   }
00459   isopen = FALSE;
00460   return (-1);
00461 }
00462
00463 /*
00464  * Load the BOOT-file from TFTP server
00465  */
00466 int tftp_boot_load (void)
00467 {
00468   int rc = 0;
00469
00470   /* Allocate socket and buffers
00471    */
00472   sock   = (sock_type*) malloc (sizeof(sock->udp));
00473   inbuf  = (struct tftphdr*) malloc (TFTP_HEADSIZE+SEGSIZE);
00474   outbuf = (struct tftphdr*) malloc (TFTP_HEADSIZE+SEGSIZE);
00475
00476   if (!sock || !inbuf || !outbuf)
00477   {
00478     outsnl (_LANG("No memory for TFTP boot."));
00479     return (0);
00480   }
00481
00482   if (!tftp_boot_remote_file)
00483   {
00484     outsnl (_LANG("No remote TFTP boot filename defined."));
00485     return (0);
00486   }
00487
00488   if (tftp_server_name[0] && !tftp_server)
00489      tftp_server = resolve (tftp_server_name);
00490
00491   if (!tftp_server)
00492   {
00493     outsnl (_LANG("Cannot resolve TFTP-server "));
00494     return (0);
00495   }
00496
00497   if (debug_on)
00498      outs (_LANG("Doing TFTP boot load..."));
00499
00500   /* Open connection and request file
00501    */
00502   if (!tftp_open (tftp_server, tftp_boot_remote_file))
00503   {
00504     tftp_close();
00505     return (0);
00506   }
00507
00508   while (1)
00509   {
00510     const char *buf;
00511     int   size = tftp_get_block (&buf);
00512
00513     if (size < 0)  /* error in transfer */
00514     {
00515       rc = 0;
00516       break;
00517     }
00518     if (size > 0 && (*tftp_writer)(buf,size) < 0)
00519     {
00520       rc = -1;     /* writer failed, errno set */
00521       break;
00522     }
00523     if (size < blocksize)    /* got last block */
00524     {
00525       rc = 1;
00526       break;
00527     }
00528   }
00529   tftp_close();
00530   return (rc);
00531 }
00532
00533 /*
00534  * Config-file handler for TFTP-client
00535  */
00536 static void (*prev_hook) (const char*, const char*) = NULL;
00537
00538 static void tftp_cfg_hook (const char *name, const char *value)
00539 {
00540   static const struct config_table tftp_cfg[] = {
00541             { "BOOT_FILE", ARG_FUNC,    (void*)tftp_set_boot_fname },
00542             { "SERVER",    ARG_RESOLVE, (void*)&tftp_server        },
00543             { "TIMEOUT",   ARG_ATOI,    (void*)&tftp_timeout       },
00544             { "RETRY",     ARG_ATOI,    (void*)&tftp_retry         },
00545             { "MODE",      ARG_FUNC,    (void*)tftp_set_xfer_mode  },
00546             { "OPENMODE",  ARG_STRDUP,  (void*)&tftp_openmode      },
00547             { "PORT",      ARG_ATOI,    (void*)&tftp_lport         },
00548             { NULL,        0,           NULL                       }
00549           };
00550   if (!parse_config_table(tftp_cfg, "TFTP.", name, value) && prev_hook)
00551      (*prev_hook) (name, value);
00552 }
00553
00557 static void tftp_exit (void)
00558 {
00559   if (!_watt_fatal_error)
00560   {
00561     DO_FREE (tftp_boot_remote_file);
00562     DO_FREE (tftp_openmode);
00563   }
00564 }
00565
00569 int tftp_init (void)
00570 {
00571   prev_hook = usr_init;
00572   usr_init  = tftp_cfg_hook;
00573   RUNDOWN_ADD (tftp_exit, 261);
00574   return (TRUE);
00575 }
00576
00577 /*
00578  * A small test program, for djgpp/Watcom only
00579  */
00580 #if defined(TEST_PROG)
00581
00582 #include <unistd.h>
00583
00584 #include "getopt.h"
00585 #include "netaddr.h"
00586 #include "pcdbug.h"
00587 #include "pcarp.h"
00588
00589 static FILE  *file;
00590 static char  *fname;
00591 static DWORD  tot_size;
00592 static time_t start;
00593
00594 int close_func (void)
00595 {
00596   if (file && fname)
00597   {
00598     time_t now = time (NULL);
00599     double  speed;
00600
00601     if (now == start)
00602        now++;
00603     speed = (double)tot_size / (double)(now - start);
00604     fprintf (stderr, "closing `%s' (%.2f kB/s)\n", fname, speed/1024.0);
00605     fclose (file);
00606     file = NULL;
00607     return (1);
00608   }
00609   return (0);
00610 }
00611
00612 static int write_func (const void *buf, size_t length)
00613 {
00614   static DWORD block = 0;
00615
00616   if (debug_on < 2)
00617       debug_on = 2;
00618
00619   if (block == 0)
00620   {
00621     tot_size = 0UL;
00622     start = time (NULL);
00623     fname = tftp_boot_local_file;
00624     fprintf (stderr, "opening `%s'\n", fname);
00625     file = fopen (fname, tftp_openmode ? tftp_openmode : "wb");
00626   }
00627   if (!file)
00628   {
00629     perror (fname);
00630     return (-1);
00631   }
00632
00633 #if defined(__DJGPP__) && 0
00634   /*
00635    * Look for optional Watt-32 stubinfo in block 4.
00636    * If .exe file isn't newer, kill the connection
00637    */
00638   if (block == 4 && is_exe && check_timestamp(buf) < our_timestamp)
00639   {
00640     close_func();
00641     return (-1);
00642   }
00643 #endif
00644
00645   if (fwrite (buf, 1, length, file) < length)
00646      return (-1);
00647   tot_size += length;
00648   block++;
00649   return (0);
00650 }
00651
00652
00653 void usage (char *argv0)
00654 {
00655   printf ("Usage: %s [[-d] [-n] [-a] [-h host] [-f file]\n"
00656           "\t\t [-i ip] [-m mask]] [-t timeout] [-r retry]\n"
00657           "\t -d enable WATTCP.DBG file\n"
00658           "\t -n run with no config file\n"
00659           "\t -a add random MAC address for tftp host\n"
00660           "\t -h specify tftp host\n"
00661           "\t -f specify remote file to load\n"
00662           "\t -i specify ip-address      (default 192.168.0.1)\n"
00663           "\t -m specify network mask    (default 255.255.0.0)\n"
00664           "\t -t specify total timeout   (default %d)\n"
00665           "\t -r specify retry count     (default %d)\n",
00666           argv0, tftp_timeout, tftp_retry);
00667   exit (-1);
00668 }
00669
00670 int main (int argc, char **argv)
00671 {
00672   eth_address eth = { 1,2,3,4,5,6 };
00673   int a_flag = 0;
00674   int h_flag = 0;
00675   int i_flag = 0;
00676   int f_flag = 0;
00677   int n_flag = 0;
00678   int m_flag = 0;
00679   int d_flag = 0;
00680   int ch;
00681
00682   while ((ch = getopt(argc, argv, "adn?h:i:f:m:t:r:")) != EOF)
00683      switch (ch)
00684      {
00685        case 'a':
00686             a_flag = 1;
00687             break;
00688        case 'd':
00689             d_flag = 1;
00690             break;
00691        case 'n':
00692             n_flag = 1;
00693             break;
00694        case 'h':
00695             h_flag = 1;
00696             tftp_server = aton (optarg);
00697             break;
00698        case 'i':
00699             i_flag = 1;
00700             my_ip_addr = aton (optarg);
00701             break;
00702        case 'f':
00703             f_flag = 1;
00704             tftp_set_boot_fname (optarg, strlen(optarg));
00705             break;
00706        case 'm':
00707             m_flag = 1;
00708             sin_mask = aton (optarg);
00709             break;
00710        case 't':
00711             tftp_timeout = atoi (optarg);
00712             break;
00713        case 'r':
00714             tftp_retry = atoi (optarg);
00715             break;
00716        case '?':
00717        default:
00718             usage (argv[0]);
00719      }
00720
00721   if (n_flag)  /* Demonstrate running with no config file */
00722   {
00723     _watt_no_config = 1;
00724     dbg_mode_all    = 1;
00725     dbg_print_stat  = 1;
00726     debug_on = 3;
00727
00728     if (!m_flag)
00729        sin_mask = aton ("255.255.0.0");
00730     if (!i_flag)
00731        my_ip_addr = aton ("192.168.0.1");
00732     if (!h_flag)
00733        tftp_server = aton ("192.168.0.2");
00734     if (!f_flag)
00735        tftp_set_boot_fname ("test.fil", 8);
00736     if (a_flag)
00737        _arp_add_cache (tftp_server, (const eth_address*)&eth, FALSE);
00738   }
00739   else if (m_flag || i_flag || h_flag || f_flag || a_flag)
00740   {
00741     puts ("This option requires the `-n' flag");
00742     return (-1);
00743   }
00744
00745   if (d_flag)
00746      dbug_init();
00747
00748   if (n_flag)
00749      dbug_open();
00750
00751   /* Must set our hook first
00752    */
00753   tftp_writer     = write_func;
00754   tftp_terminator = close_func;
00755
00756   sock_init();
00757
00758   sleep (1);       /* drain network buffers */
00759   tcp_tick (NULL);
00760   return (0);
00761 }
00762 #endif /* TEST_PROG */
00763 #endif /* USE_TFTP */
Generated on Wed Jan 25 15:42:40 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/TFTP.H Source File

SRC/TFTP.H

Go to the documentation of this file.
00001
00024 #ifndef _w32_TFTP_H
00025 #define _w32_TFTP_H
00026
00027 extern int (*tftp_writer)     (const void *buf, size_t length);
00028 extern int (*tftp_terminator) (void);
00029
00030 extern int   tftp_init        (void);
00031 extern int   tftp_boot_load   (void);
00032
00033 extern char *tftp_set_server     (const char *name, int len);
00034 extern char *tftp_set_boot_fname (const char *name, int len);
00035
00036 #endif
Generated on Wed Jan 25 15:42:40 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/TIMER.C Source File

SRC/TIMER.C

Go to the documentation of this file.
00001
00018 #include <stdio.h>
00019 #include <stdlib.h>
00020 #include <limits.h>
00021 #include <signal.h>
00022 #include <time.h>
00023 #include <math.h>
00024 #include <errno.h>
00025 #include <sys/wtime.h>
00026
00027 #include "wattcp.h"
00028 #include "ioport.h"
00029 #include "strings.h"
00030 #include "gettod.h"
00031 #include "pcconfig.h"
00032 #include "pcqueue.h"
00033 #include "language.h"
00034 #include "cpumodel.h"
00035 #include "powerpak.h"
00036 #include "wdpmi.h"
00037 #include "x32vm.h"
00038 #include "rs232.h"
00039 #include "misc.h"
00040 #include "timer.h"
00041
00042 #if (DOSX & PHARLAP)
00043 #include <mw/exc.h>  /* _dx_alloc_rmode_wrapper_iret() */
00044 #endif
00045
00046 DWORD start_time = 0;
00047 DWORD start_day  = 0;
00049 BOOL  has_8254   = FALSE;
00050 BOOL  has_rdtsc  = FALSE;
00051 BOOL  use_rdtsc  = FALSE;
00052 BOOL  using_int8 = FALSE;
00053 DWORD clocks_per_usec;
00055 time_t user_tick_base   = 0UL;   /* time() when user-tick started */
00056 DWORD  user_tick_msec   = 0UL;   /* milli-sec user-tick counter */
00057 BOOL   user_tick_active = FALSE;
00058
00059 static DWORD date    = 0;
00060 static DWORD date_ms = 0;
00061
00062 #if defined(USE_PROFILER)
00063   /*
00064    * A simple execution profiler
00065    */
00066   BOOL profile_enable = FALSE;
00067   char profile_file [MAX_PATHLEN+1] = ".\\WATTCP.PRO";
00068
00069   static FILE  *prof_fout;
00070   static uint64 prof_start;
00071   static uint64 num_profs;
00072 #endif
00073
00074 /*
00075  * Things for the user installable timer ISR.
00076  */
00077 #if !(DOSX & DJGPP)
00078   #define TIMER_ISR_PERIOD  10UL  /* 10 msec between interrupts */
00079   #define TIMER_INTR        8
00080 #endif
00081
00082 #if (DOSX == 0) || (DOSX & DOS4GW)
00083   #define HAVE_TIMER_ISR
00084
00085   static W32_IntrHandler old_int_8 = NULL;
00086
00087 #elif (DOSX & (PHARLAP|X32VM))
00088   #define HAVE_TIMER_ISR
00089
00090   static REALPTR old_int_8, int8_cback;
00091   static FARPTR  old_int_8_pm;
00092   static RMC_BLK rmBlock_int8;
00093
00094 #elif (DOSX & DJGPP)
00095   #define HAVE_TIMER_ISR
00096
00097   static DWORD            itimer_resolution = 0UL; /* in usec */
00098   static void           (*old_sigalrm)(int);
00099   static struct itimerval old_itimer;
00100 #endif
00101
00102 #if defined(HAVE_TIMER_ISR) && !(DOSX & DJGPP)
00103   static DWORD tick_timer_8254 = 0UL;
00104
00105   /* 1193181 = 4.77MHz/4 pulses per sec.
00106    */
00107   #define TIMER_8254_COUNT ((1193181UL * TIMER_ISR_PERIOD) / 1000UL)
00108 #endif
00109
00110
00111
00116 void init_timers (void)
00117 {
00118 #if (DOSX)             /* problems using 64-bit types in small/large models */
00119   hires_timer (TRUE);
00121 #if defined(HAVE_UINT64)
00122   if (use_rdtsc && has_rdtsc)
00123   {
00124     clocks_per_usec = (DWORD) (get_cpu_speed() / S64_SUFFIX(1000000));
00125     if (clocks_per_usec == 0UL)
00126     {
00127       outsnl ("CPU speed is 0?");
00128       use_rdtsc = FALSE;
00129       has_rdtsc = FALSE;
00130     }
00131   }
00132   set_utc_offset();  /* don't pull in gettod.c unneccesary */
00133 #endif
00134 #endif
00135
00136   chk_timeout (0UL); /* init 'date' variables */
00137 }
00138
00148 void init_userSuppliedTimerTick (void)
00149 {
00150   SIO_TRACE (("init_userSuppliedTimerTick"));
00151   user_tick_active = TRUE;
00152   user_tick_base = time (NULL);
00153   has_8254 = FALSE;
00154 }
00155
00156 /*
00157  * Disable stack-checking here
00158  */
00159 #if defined(__HIGHC__)
00160   #pragma off(Call_trace)
00161   #pragma off(Prolog_trace)
00162   #pragma off(Epilog_trace)
00163 #endif
00164
00165 #include "nochkstk.h"
00166
00175 void userTimerTick (DWORD elapsed_time_msec)
00176 {
00177   user_tick_msec += elapsed_time_msec;
00178 }
00179
00180 #if defined(HAVE_TIMER_ISR)
00181
00184 #if (DOSX & (DJGPP|PHARLAP|X32VM))
00185   static void new_int_8 (void) /* not really an intr-handler */
00186 #else
00187   static INTR_PROTOTYPE new_int_8 (void)
00188 #endif
00189 {
00190 #if !(DOSX & DJGPP)
00191   tick_timer_8254 += TIMER_8254_COUNT;
00192
00193   if (tick_timer_8254 >= 0x10000)
00194   {
00195     tick_timer_8254 -= 0x10000;
00196
00197 #if defined(__WATCOMC__)
00198     _chain_intr (old_int_8);    /* chain now */
00199 #elif (DOSX & (PHARLAP|X32VM))
00200     _dx_call_real (old_int_8, &rmBlock_int8, 1);
00201 #else
00202     (*old_int_8)();
00203 #endif
00204   }
00205   else
00206     _outportb (0x20, 0x60);  /* specific EOI for IRQ 0 */
00207
00208   userTimerTick (TIMER_ISR_PERIOD);
00209
00210 #else
00211   userTimerTick (itimer_resolution / 1000UL);
00212 #endif   /* !DJGPP */
00213
00214
00215 #if (DOSX & DJGPP)
00216   /* BEEP(); */  /* !! test */
00217 #endif
00218 }
00219
00220 void exit_timer_isr (void)
00221 {
00222   if (!using_int8)
00223      return;
00224
00225 #if (DOSX & DJGPP)
00226   signal (SIGALRM, old_sigalrm);
00227   setitimer (ITIMER_REAL, &old_itimer, NULL);
00228 #else
00229   if (old_int_8)
00230   {
00231     _outportb (0x43, 0x34);  /* restore default timer rate */
00232     _outportb (0x40, 0);
00233     _outportb (0x40, 0);
00234
00235     PUSHF_CLI();
00236
00237 #if (DOSX & (PHARLAP|X32VM))
00238     _dx_rmiv_set (TIMER_INTR, old_int_8);
00239     if (int8_cback)
00240        _dx_free_rmode_wrapper (int8_cback);
00241     old_int_8 = 0;
00242 #else
00243     _dos_setvect (TIMER_INTR, old_int_8);
00244     old_int_8 = NULL;
00245 #endif
00246
00247     POPF();
00248   }
00249 #endif  /* DJGPP */
00250
00251   /* This causes timeout calculations for timers started earlier
00252    * to go wrong.
00253    */
00254   user_tick_active = FALSE;
00255   using_int8 = FALSE;
00256 }
00257
00258 /*
00259  * Hook INT 8 and modify rate of timer channel 0 for 55msec (djgpp)
00260  * or 10 msec (others) period.
00261  */
00262 void init_timer_isr (void)
00263 {
00264   /* Caller must do exit_timer_isr() before doing this again
00265    */
00266   if (using_int8)
00267      return;
00268
00269 #if (DOSX & DJGPP)
00270   {
00271     struct itimerval tim;
00272
00273     memset (&tim, 0, sizeof(tim));
00274     tim.it_interval.tv_usec = 1;
00275     setitimer (ITIMER_REAL, &tim, NULL);
00276     setitimer (ITIMER_REAL, NULL, &tim);
00277     itimer_resolution = 1000000UL * tim.it_interval.tv_sec + /* should become 55000 */
00278                         tim.it_interval.tv_usec;
00279     tim.it_value.tv_sec  = tim.it_interval.tv_sec;
00280     tim.it_value.tv_usec = tim.it_interval.tv_usec;
00281
00282     memset (&old_itimer, 0, sizeof(old_itimer));
00283     old_sigalrm = signal (SIGALRM, (W32_IntrHandler)new_int_8);
00284     setitimer (ITIMER_REAL, &tim, &old_itimer);
00285   }
00286
00287 #elif (DOSX & (PHARLAP|X32VM))
00288   #if 1
00289     int8_cback = _dx_alloc_rmode_wrapper_iret ((pmodeHook)new_int_8, 256);
00290     if (!int8_cback)
00291     {
00292       outsnl (_LANG("Cannot allocate real-mode timer callback"));
00293       return;
00294     }
00295     _dx_rmiv_get (8, &old_int_8);
00296     _dx_rmiv_set (8, int8_cback);
00297   #else
00298   {
00299     FARPTR fp;
00300     FP_SET (fp, new_int_8, MY_CS());
00301     _dx_pmiv_get (8, &old_int_8_pm);
00302     _dx_apmiv_set (8, fp);
00303   }
00304   #endif
00305 #else
00306   old_int_8 = _dos_getvect (8);
00307   _dos_setvect (8, new_int_8);
00308 #endif
00309
00310 #if !(DOSX & DJGPP)
00311   _outportb (0x43, 0x34);
00312   _outportb (0x40, loBYTE(TIMER_8254_COUNT));
00313   _outportb (0x40, hiBYTE(TIMER_8254_COUNT));
00314 #endif
00315
00316   init_userSuppliedTimerTick();
00317   using_int8 = TRUE;
00318
00319   /* release it very early */
00320   RUNDOWN_ADD (exit_timer_isr, -2);
00321 }
00322
00323 #else
00324
00325 void init_timer_isr (void)
00326 {
00327 #if defined(USE_DEBUG)
00328   if (debug_on)
00329      outsnl ("No timer-ISR in this environment");
00330 #endif
00331 }
00332
00333 void exit_timer_isr (void)
00334 {
00335 }
00336 #endif
00337
00347 int cmp_timers (DWORD t1, DWORD t2)
00348 {
00349   if (t1 == t2)
00350      return (0);
00351   return (t1 < t2 ? -1 : +1);
00352 }
00353
00363 int hires_timer (int on)
00364 {
00365   int old = has_8254;
00366
00367   SIO_TRACE (("hires_timer %s", on ? "on" : "off"));
00368   has_8254 = on;
00369   chk_timeout (0UL);
00370   return (old);
00371 }
00372
00373
00374 #if !defined(WIN32)
00375 /*
00376  * The following 2 routines are modified versions from KA9Q NOS
00377  * by Phil Karn.
00378  *
00379  * clockbits() - Read low order bits of timer 0 (the TOD clock)
00380  * This works only for the 8254 chips used in ATs and 386+.
00381  *
00382  * Old version:
00383  *   The timer 0 runs in mode 3 (square wave mode), counting down
00384  *   by 2s, twice for each cycle. So it is necessary to read back the
00385  *   OUTPUT pin to see which half of the cycle we're in. I.e., the OUTPUT
00386  *   pin forms the most significant bit of the count. Unfortunately,
00387  *   the 8253 in the PC/XT lacks a command to read the OUTPUT pin...
00388  *
00389  * Now simply:
00390  *   The timer 0 runs in mode 2 (rate generator), counting down.
00391  *   We don't compare the OUTPUT pin to see what cycle we're in.
00392  *   A bit lower precision, but a bit faster.
00393  *
00394  * WARNING!: This can cause serious trouble if anything else is also using
00395  * timer interrupts. In that case use the above "userSuppliedTimerTick".
00396  * The reading of I/O registers gives bad precision under Windows.
00397  */
00398 DWORD clockbits (void)
00399 {
00400   static VOLATILE DWORD count;  /* static because of PUSHF_CLI() */
00401 #if 1
00402   /*
00403    * The following version was suggested by Andrew Paulsen
00404    * <andrew.paulsen@ndsu.nodak.edu>. Seem to work fine.
00405    */
00406   static BOOL started = FALSE;
00407
00408   PUSHF_CLI();
00409
00410   if (!started)                  /* Initialize once, it is periodic */
00411   {
00412     _outportb (0x43, 0x34);      /* Set timer 0, mode 2 */
00413     _outportb (0x40, 0x00);      /* Count is decremented, then compared to 0 */
00414     _outportb (0x40, 0x00);      /* so set count to 0 to get 65536 */
00415     started = TRUE;
00416   }
00417
00418   _outportb (0x43, 0x04);        /* Latch present counter value command */
00419   count  = _inportb (0x40);      /* LSB of count */
00420   count |= _inportb (0x40) << 8; /* MSB of count */
00421
00422   POPF();
00423
00424   return (count);
00425
00426 #else
00427   static VOLATILE DWORD stat, count;  /* static because of PUSHF_CLI() */
00428
00429   do
00430   {
00431     PUSHF_CLI();
00432     _outportb (0x43, 0xC2);        /* Read Back Command (timer 0, 8254 only) */
00433     stat   = _inportb (0x40);      /* get status of timer 0 */
00434     count  = _inportb (0x40);      /* LSB of count */
00435     count |= _inportb (0x40) << 8; /* MSB of count */
00436     POPF();
00437   }
00438   while (stat & 0x40);             /* reread if NULL COUNT bit set */
00439
00440   stat = (stat & 0x80) << 8;       /* Shift OUTPUT to MSB of 16-bit word */
00441   count >>= 1;                     /* count = count/2 */
00442   if (count == 0)
00443      return (stat ^ 0x8000UL);     /* return complement of OUTPUT bit */
00444   return (count | stat);           /* Combine OUTPUT with counter */
00445 #endif
00446 }
00447
00448 /*
00449  * Return hardware time-of-day in milliseconds. Resolution is improved
00450  * beyond 55 ms (the clock tick interval) by reading back the instantaneous
00451  * 8254 counter value and combining it with the clock tick counter.
00452  *
00453  * Reading the 8254 is a bit tricky since a tick could occur asynchronously
00454  * between the two reads in clockbits(). The tick counter is examined before
00455  * and after the hardware counter is read. If the tick counter changes, try
00456  * again.
00457  *
00458  * \note The hardware counter (lo) counts down from 65536 at a rate of
00459  *       1.193181 MHz (4.77/4). System tick count (hi) counts up.
00460  */
00461 DWORD millisec_clock (void)
00462 {
00463   DWORD  hi;
00464   WORD   lo;
00465   double x;
00466
00467   do
00468   {
00469     hi = PEEKL (0, BIOS_CLK);
00470     lo = clockbits();
00471   }
00472   while (hi != PEEKL(0, BIOS_CLK));   /* tick count changed, try again */
00473   lo = 0 - lo;
00474
00475   /* Emulating this would be slow. We'd better have a math-processor
00476    */
00477   x = ldexp ((double)hi, 16) + (double)lo;  /* x = hi*2^16 + lo */
00478   return (DWORD) (x * 4.0 / 4770.0);
00479 }
00480 #endif  /* !WIN32 */
00481
00482
00487 DWORD set_timeout (DWORD msec)
00488 {
00489   DWORD ret;
00490
00491   if (user_tick_active)  /* using timer ISR or user-timer */
00492   {
00493     ret = user_tick_msec + msec;
00494   }
00495 #if defined(HAVE_UINT64) /* CPU-clock, 8254 PIT or 55msec ticks */ || \
00496     defined(WIN32)       /* GetSystemTimeAsFileTime() */
00497   else
00498   {
00499     struct timeval now;
00500
00501     gettimeofday2 (&now, NULL);
00502     ret = msec + 1000 * now.tv_sec + (DWORD)(now.tv_usec / 1000);
00503   }
00504 #else
00505   else if (has_8254)    /* high-resolution PIT */
00506   {
00507     ret = msec + date_ms + millisec_clock();
00508   }
00509   else /* fallback to 55msec ticks */
00510   {
00511     DWORD ticks = 1;
00512
00513     if (msec > 55)
00514        ticks = msec / 55UL;
00515  /* ret = ticks + ms_clock();  !!!! try this */
00516     ret = ticks + date + PEEKL (0,BIOS_CLK);
00517   }
00518 #endif
00519
00520   return (ret == 0 ? 1 : ret);
00521 }
00522
00528 BOOL chk_timeout (DWORD value)
00529 {
00530   if (user_tick_active)      /* using timer ISR or user-timer */
00531   {
00532     if (value == 0)
00533        return (0);
00534     return (user_tick_msec >= value);
00535   }
00536
00537 #if defined(HAVE_UINT64) || defined(WIN32)
00538   if (value == 0UL)
00539      return (0);
00540   return (set_timeout(0) >= value);
00541
00542 #else
00543   {
00544     static char  oldHour = -1;
00545     static DWORD now_ms;
00546     static DWORD now;
00547     char   hour;
00548
00549     now  = (DWORD) PEEKL (0, BIOS_CLK);
00550 #if 1
00551     hour = (char)(now >> 16U);
00552 #else
00553     hour = (char)(now/65543.33496093);  /* Jan De Geeter 17.12.01 */
00554 #endif
00555
00556     if (hour != oldHour)
00557     {
00558       if (hour < oldHour)               /* midnight passed */
00559       {
00560 #define CORR 290UL                      /* experimental correction */
00561         date    += 1572750UL + CORR;    /* Update date (0x1800B0UL) */
00562         date_ms += 3600UL*24UL*1000UL;  /* ~2^26 */
00563       }
00564       oldHour = hour;
00565     }
00566
00567     if (value == 0L)        /* timer not initialised */
00568        return (0);          /* (or stopped) */
00569
00570     if (has_8254)
00571     {
00572       now_ms = millisec_clock();
00573       return (now_ms + date_ms >= value);
00574     }
00575     now += date;            /* date extend current time */
00576     return (now >= value);  /* return true if expired */
00577   }
00578 #endif   /* HAVE_UINT64 || WIN32 */
00579 }
00580
00585 int set_timediff (long msec)
00586 {
00587   date_ms -= msec;
00588   date    -= msec/55;
00589   return (0);
00590 }
00591
00598 long get_timediff (DWORD now, DWORD tim)
00599 {
00600 #if defined(HAVE_UINT64) || defined(WIN32)
00601   return (long)(now - tim);
00602 #else
00603   long dt = (long)(now - tim);
00604
00605   if (has_8254)
00606        dt = dt % (3600L*24L*1000L);
00607   else dt = dt % (1572750L + CORR);
00608   return (dt);
00609 #endif
00610 }
00611
00612 /*
00613  * Return difference (in micro-sec) between timevals `*newer' and `*older'
00614  */
00615 double timeval_diff (const struct timeval *newer, const struct timeval *older)
00616 {
00617   long d_sec  = (long)newer->tv_sec - (long)older->tv_sec;
00618   long d_usec = newer->tv_usec - older->tv_usec;
00619   return (1E6 * (double)d_sec + (double)d_usec);
00620 }
00621
00622 #if defined(WIN32)
00623 /*
00624  * Return FILETIME in seconds.
00625  */
00626 double filetime_sec (const void *filetime)
00627 {
00628 #if 0
00629   const FILETIME *ft = (const FILETIME*) filetime;
00630   long double rc = (long double)ft->dwHighDateTime * (long double)(ULONG_MAX+1);
00631
00632   rc += (long double) ft->dwLowDateTime;
00633 #else
00634   const LARGE_INTEGER ft = *(const LARGE_INTEGER*) filetime;
00635   long double rc = (long double)ft.QuadPart;
00636 #endif
00637   return (double) (rc/1E7);    /* from 100 nano-sec periods to sec */
00638 }
00639 #endif
00640
00641 #if defined(USE_DEBUG)
00642 /*
00643  * Return string "x.xx" for timeout value.
00644  * 'val' is always in milli-sec units if we're using the 8254 PIT,
00645  * RDTSC timestamps, timer ISR or user-supplied timer.
00646  */
00647 const char *time_str (DWORD val)
00648 {
00649   static char  buf[30];
00650   char   fmt[6];
00651   double flt_val;
00652
00653   if (has_8254 || has_rdtsc || user_tick_active)
00654   {
00655     flt_val = (double)val / 1000.0F;
00656     strcpy (fmt, "%.3f");
00657   }
00658   else
00659   {
00660     flt_val = (double)val / 18.2F;
00661     strcpy (fmt, "%.2f");
00662   }
00663
00664 #if (!DOSX) && defined(__BORLANDC__) && 0 /* Bug? Try "%.xlf" */
00665   fmt[3] = 'l';
00666   fmt[4] = 'f';
00667   fmt[5] = '\0';
00668 #endif
00669
00670   sprintf (buf, fmt, flt_val);
00671   return (buf);
00672 }
00673
00674 /*
00675  * Return string "HH:MM:SS" for a time in seconds.
00676  */
00677 const char *hms_str (DWORD sec)
00678 {
00679   static char buf[30];
00680   WORD   hour = (WORD) (sec / 3600UL);
00681   WORD   min  = (WORD) (sec / 60) - (60 * hour);
00682
00683   sprintf (buf, "%02u:%02u:%02u", hour, min, (UINT)(sec % 60UL));
00684   return (buf);
00685 }
00686
00687 /*
00688  * Return string "xx:xx" for time elapsed since started.
00689  * Handles max 24 days. Or max 49 days with user_tick_active.
00690  */
00691 const char *elapsed_str (DWORD val)
00692 {
00693   static char buf[30];
00694   WORD   hour, min, msec;
00695   DWORD  sec;
00696   BOOL   is_win = (DOSX & WINWATT);
00697
00698   if (val == 0UL)
00699      return ("00:00:00.000");
00700
00701   if (!user_tick_active && val < start_time)   /* wrapped? */
00702      val = ULONG_MAX - val + start_time;
00703
00704   /* If user-ticks is used, 'val' should be correct msec count
00705    * since init_userSuppliedTimerTick()() was called.
00706    */
00707   if (user_tick_active)
00708   {
00709     sec  = val / 1000UL;
00710     msec = (WORD) (val % 1000UL);
00711   }
00712   else if (has_8254 || has_rdtsc || is_win)
00713   {
00714     val -= start_time;
00715     sec  = val / 1000UL;
00716     msec = (WORD) (val % 1000UL);
00717   }
00718   else
00719   {
00720     val -= start_time;
00721     sec  = val / 18;
00722     msec = 55 * (WORD)(val % 18UL);
00723   }
00724
00725   hour = (WORD) (sec / 3600UL);
00726   min  = (WORD) (sec / 60UL) - 60 * hour;
00727   sec  = sec % 60UL;
00728   sprintf (buf, "%02u:%02u:%02lu.%03u", hour, min, sec, msec);
00729   return (buf);
00730 }
00731 #endif /* USE_DEBUG */
00732
00733
00734 #if !defined(WIN32)
00735 /*
00736  * The following was contributed by
00737  * "Alain" <alainm@pobox.com>
00738  */
00739 #define TICKS_DAY 1573067UL   /* Number of ticks in one day */
00740
00741 DWORD ms_clock (void)
00742 {
00743   static DWORD lastTick, tickOffset;
00744   static char  firstTime = 1;
00745   DWORD  tick = PEEKL (0, 0x46C);
00746
00747   if (firstTime)
00748   {
00749     firstTime = 0;
00750     lastTick  = tickOffset = tick;
00751     return (0);
00752   }
00753   if (lastTick > tick)        /* day changed */
00754      tickOffset -= TICKS_DAY;
00755   lastTick = tick;
00756   return (tick - tickOffset);
00757 }
00758 #endif  /* WIN32 */
00759
00760
00761 #if defined(USE_PROFILER)
00762 /*
00763  * Called on entry of something to profile.
00764  */
00765 void profile_start (const char *str)
00766 {
00767   if (prof_fout)
00768   {
00769     fprintf (prof_fout, "  profiling %-12.12s ", str);
00770     prof_start = get_rdtsc();
00771     num_profs++;
00772   }
00773 }
00774
00775 /*
00776  * Dumps the time taken (milli-sec and CPU clocks).
00777  */
00778 void profile_stop (void)
00779 {
00780   if (prof_fout && clocks_per_usec)
00781   {
00782     int64  clocks = (int64) (get_rdtsc() - prof_start);
00783     double msec   = (double)clocks / ((double)clocks_per_usec * 1000.0);
00784     fprintf (prof_fout, "%10.3f msec (%" S64_FMT " clk)\n", msec, clocks);
00785   }
00786 }
00787
00788 static void profile_exit (void)
00789 {
00790   if (prof_fout)
00791   {
00792     fclose (prof_fout);
00793     prof_fout = NULL;
00794     if (num_profs)
00795        (*_printf) ("profiling info written to \"%s\"\n", profile_file);
00796   }
00797 }
00798
00799 /*
00800  * Dump some arbitrary data to profile dump file.
00801  */
00802 void profile_dump (const uint64 *data, size_t num)
00803 {
00804   unsigned i;
00805
00806   if (!prof_fout || !clocks_per_usec)
00807      return;
00808
00809   for (i = 0; i < num; i++)
00810   {
00811     double msec = (double)data[i] / ((double)clocks_per_usec * 1000.0);
00812
00813     fprintf (prof_fout, "profile_dump: %3u: %12.3f msec (%" U64_FMT " clk)\n",
00814              i, msec, data[i]);
00815   }
00816 }
00817
00818 /*
00819  * Profile speed of receving a packet. Write the difference of
00820  *   get - time of 2nd packet upcall for DOS or time reported
00821  *         by NPF.SYS on Windows.
00822  *   put - time when we called pkt_poll_recv().
00823  *
00824  * DOS:   the 'put' and 'get' are CPU clock timestamps.
00825  * WIN32: these are 'timeval' values.
00826  */
00827 void profile_recv (const uint64 *putp, const uint64 *getp)
00828 {
00829   uint64 put, get;
00830
00831   if (!prof_fout || !clocks_per_usec)
00832      return;
00833
00834   WATT_ASSERT (putp && getp);
00835
00836   put = *putp;
00837   get = *getp;
00838
00839   fputs ("  profiling pkt_receiver ", prof_fout);
00840   if (get == U64_SUFFIX(0) || put == U64_SUFFIX(0))
00841      fputs ("<not enabled>\n", prof_fout);
00842   else
00843   {
00844 #if defined(WIN32)
00845     const struct timeval *tv_get = (const struct timeval*)getp;
00846     const struct timeval *tv_put = (const struct timeval*)putp;
00847     double usec   = timeval_diff (tv_get, tv_put);
00848     int64  clocks = (int64) (usec * clocks_per_usec);
00849
00850     fprintf (prof_fout, "%10.3f msec (%" S64_FMT " clk)\n",
00851              usec / 1000.0, clocks);
00852 #else
00853     int64  clocks = (int64)(get - put);
00854     double msec   = (double)clocks / ((double)clocks_per_usec * 1000.0);
00855     fprintf (prof_fout, "%10.3f msec (%" S64_FMT " clk)\n", msec, clocks);
00856 #endif
00857   }
00858 }
00859
00860 /*
00861  * Must be called after init_timers() or init_misc().
00862  */
00863 int profile_init (void)
00864 {
00865   uint64 overhead, start;
00866   time_t now;
00867
00868   if (!profile_enable || !profile_file[0])
00869      return (0);
00870
00871   if (!has_rdtsc || !clocks_per_usec)
00872   {
00873     profile_enable = FALSE;
00874     (*_printf) (_LANG("Profiling not available (no RDTSC or $USE_RDTSC=1)\n"));
00875     return (0);
00876   }
00877
00878   prof_fout = fopen (profile_file, "at");
00879   if (!prof_fout)
00880   {
00881     (*_printf) (_LANG("Failed to open %s: %s\n"),
00882                 profile_file, strerror(errno));
00883     return (0);
00884   }
00885
00886 #if !defined(__BORLANDC__)  /* buggy output with this */
00887   {
00888     static char fbuf [256];
00889     setvbuf (prof_fout, fbuf, _IOLBF, sizeof(fbuf));  /* line-buffered */
00890   }
00891 #endif
00892
00893   now = time (NULL);
00894
00895   fprintf (prof_fout, "\nProfiling %s, %.15s, %s\n",
00896            get_argv0(), ctime(&now)+4, dos_extender_name());
00897
00898   num_profs = 0;
00899   start = get_rdtsc();
00900   profile_start ("dummy");
00901   profile_stop();
00902   overhead = get_rdtsc() - start;
00903
00904   fprintf (prof_fout, "  CPU-speed %lu MHz, overhead %" U64_FMT " clocks\n",
00905            clocks_per_usec, overhead);
00906   RUNDOWN_ADD (profile_exit, 90);
00907   return (1);
00908 }
00909
00910 int profile_on (void)
00911 {
00912   return (prof_fout != NULL);
00913 }
00914 #endif  /* USE_PROFILER */
00915
00916
00917 #if (DOSX) && defined(HAVE_UINT64)
00918 /*
00919  * Wait for BIOS timer-tick to change 'num' times.
00920  */
00921 static void Wait_N_ticks (int num)
00922 {
00923   DWORD tim;
00924
00925   while (num--)
00926   {
00927 #if defined(WIN32)
00928     tim = GetTickCount() + 55;
00929     while (GetTickCount() < tim)
00930           Sleep (0);
00931 #else
00932     tim = PEEKL (0, BIOS_CLK);
00933     while (PEEKL(0,BIOS_CLK) == tim)
00934     {
00935 #ifdef __DJGPP__
00936       ENABLE();    /* CWSDPMI requires this! */
00937 #else
00938       ((void)0);
00939 #endif
00940     }
00941 #endif
00942   }
00943 }
00944
00948 uint64 get_cpu_speed (void)
00949 {
00950   #define NUM_SAMPLES 3
00951   #define WAIT_TICKS  2
00952
00953   uint64 speed;
00954   uint64 sample [NUM_SAMPLES];
00955   int    i;
00956
00957   Wait_N_ticks (1);
00958
00959   for (i = 0; i < NUM_SAMPLES; i++)
00960   {
00961     uint64 start = get_rdtsc();
00962
00963     Wait_N_ticks (WAIT_TICKS);
00964     sample[i] = 1000 * (get_rdtsc() - start) / (WAIT_TICKS*55);
00965   }
00966
00967   speed = 0;
00968   for (i = 0; i < NUM_SAMPLES; i++)
00969       speed += sample[i];
00970   return (speed / NUM_SAMPLES);
00971 }
00972 #endif  /* DOSX && HAVE_UINT64 */
00973
Generated on Wed Jan 25 15:42:40 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/TIMER.H Source File

SRC/TIMER.H

Go to the documentation of this file.
00001
00003 #ifndef _w32_TIMER_H
00004 #define _w32_TIMER_H
00005
00006 #ifndef __SYS_WTIME_H
00007 #include <sys/wtime.h>      /* struct timeval */
00008 #endif
00009
00010 #define has_8254          NAMESPACE (has_8254)
00011 #define has_rdtsc         NAMESPACE (has_rdtsc)
00012 #define use_rdtsc         NAMESPACE (use_rdtsc)
00013 #define using_int8        NAMESPACE (using_int8)
00014 #define user_tick_active  NAMESPACE (user_tick_active)
00015 #define user_tick_base    NAMESPACE (user_tick_base)
00016 #define user_tick_msec    NAMESPACE (user_tick_msec)
00017 #define clocks_per_usec   NAMESPACE (clocks_per_usec)
00018 #define clockbits         NAMESPACE (clockbits)
00019 #define ms_clock          NAMESPACE (ms_clock)
00020 #define millisec_clock    NAMESPACE (millisec_clock)
00021 #define start_time        NAMESPACE (start_time)
00022 #define start_day         NAMESPACE (start_day)
00023 #define init_timers       NAMESPACE (init_timers)
00024 #define set_timeout       NAMESPACE (set_timeout)
00025 #define chk_timeout       NAMESPACE (chk_timeout)
00026 #define hires_timer       NAMESPACE (hires_timer)
00027 #define set_timediff      NAMESPACE (set_timediff)
00028 #define get_timediff      NAMESPACE (get_timediff)
00029 #define timeval_diff      NAMESPACE (timeval_diff)
00030 #define filetime_sec      NAMESPACE (filetime_sec)
00031 #define get_cpu_speed     NAMESPACE (get_cpu_speed)
00032 #define profile_start     NAMESPACE (profile_start)
00033 #define profile_stop      NAMESPACE (profile_stop)
00034 #define profile_init      NAMESPACE (profile_init)
00035 #define profile_on        NAMESPACE (profile_on)
00036 #define profile_dump      NAMESPACE (profile_dump)
00037 #define profile_recv      NAMESPACE (profile_recv)
00038 #define profile_file      NAMESPACE (profile_file)
00039 #define profile_enable    NAMESPACE (profile_enable)
00040
00041 #define time_str          NAMESPACE (time_str)
00042 #define hms_str           NAMESPACE (hms_str)
00043 #define elapsed_str       NAMESPACE (elapsed_str)
00044 #define init_timer_isr    NAMESPACE (init_timer_isr)
00045 #define exit_timer_isr    NAMESPACE (exit_timer_isr)
00046
00047 /*
00048  * System clock at BIOS location 40:6C (dword). Counts upwards.
00049  */
00050 #define BIOS_CLK 0x46C
00051
00052
00053 W32_DATA BOOL   has_8254, has_rdtsc, use_rdtsc;
00054 W32_DATA BOOL   user_tick_active, using_int8;
00055 W32_DATA DWORD  clocks_per_usec, user_tick_msec;
00056 W32_DATA time_t user_tick_base;
00057 W32_DATA DWORD  start_time, start_day;
00058
00059 W32_FUNC void   init_timers    (void);
00060 W32_FUNC DWORD  set_timeout    (DWORD msec);        /* return value for timeout */
00061 W32_FUNC BOOL   chk_timeout    (DWORD timeout);     /* check if time expired    */
00062 W32_FUNC int    cmp_timers     (DWORD t1, DWORD t2);
00063 W32_FUNC DWORD  millisec_clock (void);
00064 W32_FUNC int    hires_timer    (int on);
00065 extern   DWORD  clockbits      (void);
00066 extern   DWORD  ms_clock       (void);
00067
00068 W32_FUNC int    set_timediff   (long msec);
00069 W32_FUNC long   get_timediff   (DWORD now, DWORD t);
00070 W32_FUNC double timeval_diff   (const struct timeval *a, const struct timeval *b);
00071 W32_FUNC double filetime_sec   (const void *filetime);
00072
00073 extern const char *time_str   (DWORD val);
00074 extern const char *hms_str    (DWORD sec);
00075 extern const char *elapsed_str(DWORD val);
00076
00077 W32_FUNC void init_timer_isr (void);
00078 W32_FUNC void exit_timer_isr (void);
00079
00080 W32_FUNC void init_userSuppliedTimerTick (void);
00081 W32_FUNC void userTimerTick (DWORD elapsedTimeMs);
00082
00083
00084 #if defined(USE_PROFILER)
00085   extern BOOL   profile_enable;
00086   extern char   profile_file [MAX_PATHLEN+1];
00087
00088   extern uint64 get_cpu_speed (void);
00089   extern void   profile_start (const char *where);
00090   extern void   profile_stop  (void);
00091   extern int    profile_init  (void);
00092   extern int    profile_on    (void);
00093   extern void   profile_dump  (const uint64 *data, size_t num_elem);
00094   extern void   profile_recv  (const uint64 *put, const uint64 *get);
00095
00096   #define PROFILE_START(func) profile_start (func)
00097   #define PROFILE_STOP()      profile_stop()
00098   #define PROFILE_RECV(p,g)   profile_recv (p,g)
00099
00100 #else
00101   #define PROFILE_START(func) ((void)0)
00102   #define PROFILE_STOP()      ((void)0)
00103   #define PROFILE_RECV(p,g)   ((void)0)
00104 #endif
00105
00106
00107 #endif
00108
Generated on Wed Jan 25 15:42:40 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/TRANSMIT.C Source File

SRC/TRANSMIT.C

Go to the documentation of this file.
00001
00005 /*  BSD sockets functionality for Waterloo TCP/IP
00006  *
00007  *  Copyright (c) 1997-2002 Gisle Vanem <giva@bgnett.no>
00008  *
00009  *  Redistribution and use in source and binary forms, with or without
00010  *  modification, are permitted provided that the following conditions
00011  *  are met:
00012  *  1. Redistributions of source code must retain the above copyright
00013  *     notice, this list of conditions and the following disclaimer.
00014  *  2. Redistributions in binary form must reproduce the above copyright
00015  *     notice, this list of conditions and the following disclaimer in the
00016  *     documentation and/or other materials provided with the distribution.
00017  *  3. All advertising materials mentioning features or use of this software
00018  *     must display the following acknowledgement:
00019  *       This product includes software developed by Gisle Vanem
00020  *       Bergen, Norway.
00021  *
00022  *  THIS SOFTWARE IS PROVIDED BY ME (Gisle Vanem) AND CONTRIBUTORS ``AS IS''
00023  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00024  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00025  *  ARE DISCLAIMED.  IN NO EVENT SHALL I OR CONTRIBUTORS BE LIABLE FOR ANY
00026  *  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00027  *  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00028  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00029  *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00030  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00031  *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00032  *
00033  *  Version
00034  *
00035  *  0.5 : Dec 18, 1997 : G. Vanem - created
00036  */
00037
00038 #include "socket.h"
00039 #include "pcicmp6.h"
00040
00041 #if defined(USE_BSD_API)
00042
00043 static int raw_transmit (Socket *socket, const void *buf, unsigned len);
00044 static int udp_transmit (Socket *socket, const void *buf, unsigned len);
00045 static int tcp_transmit (Socket *socket, const void *buf, unsigned len, int flags);
00046 static int setup_udp_raw (Socket *socket, const struct sockaddr *to, int tolen);
00047
00048 static int transmit (const char *func, int s, const void *buf, unsigned len,
00049                      int flags, const struct sockaddr *to, int tolen,
00050                      BOOL from_sendto);
00051
00052 int W32_CALL sendto (int s, const void *buf, int len, int flags,
00053                      const struct sockaddr *to, int tolen)
00054 {
00055   return transmit ("sendto", s, buf, len, flags, to, tolen, TRUE);
00056 }
00057
00058 int W32_CALL send (int s, const void *buf, int len, int flags)
00059 {
00060   return transmit ("send", s, buf, len, flags, NULL, 0, FALSE);
00061 }
00062
00063 int write_s (int s, const char *buf, int nbyte)
00064 {
00065   return transmit ("write_s", s, buf, nbyte, 0, NULL, 0, FALSE);
00066 }
00067
00068 int writev_s (int s, const struct iovec *vector, size_t count)
00069 {
00070   int i, len, bytes = 0;
00071
00072   SOCK_DEBUGF (("\nwritev_s:%d, iovecs=%lu", s, (DWORD)count));
00073
00074   for (i = 0; i < (int)count; i++)
00075   {
00076 #if (DOSX)
00077     if (!valid_addr ((DWORD)vector[i].iov_base, vector[i].iov_len))
00078     {
00079       SOCK_DEBUGF ((", EFAULT (iovec[%d] = %p, len %d)",
00080                     i, vector[i].iov_base, vector[i].iov_len));
00081       SOCK_ERRNO (EFAULT);
00082       return (-1);
00083     }
00084 #endif
00085
00086     len = transmit (NULL, s, vector[i].iov_base, vector[i].iov_len,
00087                     0, NULL, 0, FALSE);
00088     if (len < 0)
00089     {
00090       bytes = -1;
00091       break;
00092     }
00093     bytes += len;
00094   }
00095
00096   SOCK_DEBUGF ((", total %d", bytes));  /* writing 0 byte is not an error */
00097   return (bytes);
00098 }
00099
00100 /*
00101  * sendmsg():
00102  */
00103 int sendmsg (int s, const struct msghdr *msg, int flags)
00104 {
00105   const struct iovec *iov;
00106   int   count = msg->msg_iovlen;
00107   int   i, bytes, len;
00108
00109   SOCK_DEBUGF (("\nsendmsg:%d, iovecs=%d", s, count));
00110
00111   iov = msg->msg_iov;
00112   if (!iov)
00113   {
00114     SOCK_DEBUGF ((", EFAULT"));
00115     SOCK_ERRNO (EFAULT);
00116     return (-1);
00117   }
00118
00119   for (i = bytes = 0; i < count; i++)
00120   {
00121 #if (DOSX)
00122     if (!valid_addr ((DWORD)iov[i].iov_base, iov[i].iov_len))
00123     {
00124       SOCK_DEBUGF ((", EFAULT (iovec[%d] = %p/%d)",
00125                    (int)i, iov[i].iov_base, iov[i].iov_len));
00126       SOCK_ERRNO (EFAULT);
00127       return (-1);
00128     }
00129 #endif
00130
00131     len = transmit (NULL, s, iov[i].iov_base, iov[i].iov_len,
00132                     flags, (struct sockaddr*)msg->msg_name,
00133                     msg->msg_namelen, TRUE);
00134     if (len < 0)
00135     {
00136       bytes = -1;
00137       break;
00138     }
00139     bytes += len;
00140   }
00141   SOCK_DEBUGF ((", total %d", bytes));
00142   return (bytes);
00143 }
00144
00145 /*
00146  * Close socket if MSG_EOR specified in flags.
00147  */
00148 static __inline void msg_eor_close (Socket *socket)
00149 {
00150   switch (socket->so_type)
00151   {
00152     case SOCK_STREAM:
00153          socket->so_state |= SS_CANTSENDMORE;
00154          sock_close ((sock_type*)socket->tcp_sock);
00155          break;
00156     case SOCK_DGRAM:
00157          socket->so_state |= SS_CANTSENDMORE;
00158          sock_close ((sock_type*)socket->udp_sock);
00159          break;
00160     case SOCK_RAW:
00161          socket->so_state |= SS_CANTSENDMORE;
00162          break;
00163   }
00164 }
00165
00166 /*
00167  * transmit() flags:
00168  *   MSG_DONTROUTE                                     (not supported)
00169  *   MSG_EOR       Close sending side after data sent
00170  *   MSG_TRUNC                                         (not supported)
00171  *   MSG_CTRUNC                                        (not supported)
00172  *   MSG_OOB                                           (not supported)
00173  *   MSG_WAITALL   Wait till room in tx-buffer         (not supported)
00174  *   MSG_NOSIGNAL  ??                                  (not supported)
00175  */
00176 static int transmit (const char *func, int s, const void *buf, unsigned len,
00177                      int flags, const struct sockaddr *to, int tolen,
00178                      BOOL from_sendto)    /* called from sendto() */
00179 {
00180   Socket *socket = _socklist_find (s);
00181   int     rc;
00182
00183   if (func)
00184   {
00185     SOCK_DEBUGF (("\n%s:%d, len=%d", func, s, len));
00186     if (flags)
00187        SOCK_DEBUGF ((", flags %d", flags));
00188   }
00189
00190   if (!socket)
00191   {
00192     if (_sock_dos_fd(s))
00193     {
00194       SOCK_DEBUGF ((", ENOTSOCK"));
00195       SOCK_ERRNO (ENOTSOCK);
00196       return (-1);
00197     }
00198     SOCK_DEBUGF ((", EBADF"));
00199     SOCK_ERRNO (EBADF);
00200     return (-1);
00201   }
00202
00203   if (socket->so_type == SOCK_STREAM ||      /* TCP-socket or */
00204       (socket->so_state & SS_ISCONNECTED))   /* "connected" udp/raw */
00205   {
00206     /* Note: SOCK_RAW doesn't really need a local address/port, but
00207      * makes the code more similar for all socket-types.
00208      * Disadvantage is that SOCK_RAW ties up a local port and a bit
00209      * more memory.
00210      */
00211
00212     if (!socket->local_addr)
00213     {
00214       SOCK_DEBUGF ((", no local_addr"));
00215       SOCK_ERRNO (ENOTCONN);
00216       return (-1);
00217     }
00218
00219     if (!socket->remote_addr)
00220     {
00221       SOCK_DEBUGF ((", no remote_addr"));
00222       SOCK_ERRNO (ENOTCONN);
00223       return (-1);
00224     }
00225
00226     if (socket->so_state & SS_CONN_REFUSED)
00227     {
00228       if (socket->so_error == ECONNRESET)  /* set in tcp_sockreset() */
00229       {
00230         SOCK_DEBUGF ((", ECONNRESET"));
00231         SOCK_ERRNO (ECONNRESET);
00232       }
00233       else
00234       {
00235         SOCK_DEBUGF ((", ECONNREFUSED"));
00236         SOCK_ERRNO (ECONNREFUSED);
00237       }
00238       return (-1);
00239     }
00240   }
00241
00242   /* connectionless protocol setup
00243    */
00244   if (socket->so_type == SOCK_DGRAM ||
00245       socket->so_type == SOCK_RAW   ||
00246       socket->so_type == SOCK_PACKET)
00247   {
00248     size_t sa_len = (socket->so_family == AF_INET6)  ?
00249                      sizeof(struct sockaddr_in6)     :
00250                     (socket->so_family == AF_PACKET) ?
00251                      sizeof(struct sockaddr_ll)      :
00252                      sizeof(struct sockaddr_in);
00253
00254     if (!from_sendto)
00255     {
00256       to = (const struct sockaddr*) socket->remote_addr;
00257       tolen = sa_len;
00258     }
00259     if (!to || tolen < (int)sa_len)
00260     {
00261       SOCK_DEBUGF ((", illegal to-addr (tolen = %d, sa_len %d)",
00262                     tolen, (int)sa_len));
00263       SOCK_ERRNO (EINVAL);
00264       return (-1);
00265     }
00266     if (socket->so_type != SOCK_PACKET &&
00267         setup_udp_raw(socket,to,tolen) < 0)
00268        return (-1);
00269   }
00270
00271   if (len > 0)
00272      VERIFY_RW (buf, len);
00273
00274   if (socket->so_type != SOCK_DGRAM && (!buf || len == 0))
00275   {
00276     SOCK_DEBUGF ((", EINVAL"));
00277     SOCK_ERRNO (EINVAL);
00278     return (-1);
00279   }
00280
00281   if (_sock_sig_setup() < 0)
00282   {
00283     SOCK_ERRNO (EINTR);
00284     return (-1);
00285   }
00286
00287   switch (socket->so_type)
00288   {
00289     case SOCK_DGRAM:
00290          rc = udp_transmit (socket, buf, len);
00291          break;
00292
00293     case SOCK_STREAM:
00294          rc = tcp_transmit (socket, buf, len, flags);
00295          break;
00296
00297     case SOCK_RAW:
00298          rc = raw_transmit (socket, buf, len);
00299          break;
00300
00301     case SOCK_PACKET:
00302          rc = sock_packet_transmit (socket, buf, len, to, tolen);
00303          break;
00304
00305     default:
00306          SOCK_DEBUGF ((", EPROTONOSUPPORT"));
00307          SOCK_ERRNO (EPROTONOSUPPORT);
00308          rc = -1;
00309          break;
00310   }
00311
00312   if (rc >= 0 && (flags & MSG_EOR))
00313      msg_eor_close (socket);
00314
00315   _sock_sig_restore();
00316   return (rc);
00317 }
00318
00319
00320 /*
00321  * Setup remote_addr for SOCK_RAW/SOCK_DGRAM (connectionless) protocols.
00322  * Must "reconnect" socket if 'remote_addr' or 'to' address are different.
00323  * I.e we're sending to another host/port than last time.
00324  */
00325 static int setup_udp_raw (Socket *socket, const struct sockaddr *to, int tolen)
00326 {
00327   const struct sockaddr_in *peer = (const struct sockaddr_in*) to;
00328   DWORD keepalive = socket->keepalive;
00329   WORD  lport     = 0;
00330   BOOL  is_ip6    = (socket->so_family == AF_INET6);
00331   BYTE *rdata     = NULL;
00332   int   rc;
00333
00334   if (socket->so_state & SS_ISCONNECTED)
00335   {
00336     if (!socket->remote_addr)
00337        SOCK_FATAL (("setup_udp_raw(): no remote_addr\n"));
00338
00339     /* No need to reconnect if same peer address/port.
00340      */
00341     if (!is_ip6)
00342     {
00343       const struct sockaddr_in *ra = (const struct sockaddr_in*)socket->remote_addr;
00344
00345       if (peer->sin_addr.s_addr == ra->sin_addr.s_addr &&
00346           peer->sin_port        == ra->sin_port)
00347         return (1);
00348     }
00349 #if defined(USE_IPV6)
00350     else
00351     {
00352       const struct sockaddr_in6 *ra    = (const struct sockaddr_in6*)socket->remote_addr;
00353       const struct sockaddr_in6 *peer6 = (const struct sockaddr_in6*)to;
00354
00355       if (!memcmp(&peer6->sin6_addr, &ra->sin6_addr, sizeof(peer6->sin6_addr)) &&
00356           peer6->sin6_port == ra->sin6_port)
00357         return (1);
00358     }
00359 #endif
00360
00361     SOCK_DEBUGF ((", reconnecting"));
00362
00363     free (socket->remote_addr);
00364     socket->remote_addr = NULL;
00365
00366     /* Clear any effect of previous ICMP errors etc.
00367      */
00368     socket->so_state &= ~(SS_CONN_REFUSED | SS_CANTSENDMORE | SS_CANTRCVMORE);
00369     socket->so_error  = 0;
00370
00371     if (socket->so_type == SOCK_DGRAM)
00372     {
00373       lport = socket->udp_sock->myport;
00374       rdata = socket->udp_sock->rx_data;  /* preserve current data */
00375     }
00376   }
00377
00378   /* For SOCK_DGRAM, udp_close() will be called when (re)opening socket.
00379    */
00380   SOCK_ENTER_SCOPE();
00381   rc = connect (socket->fd, to, tolen);
00382   SOCK_LEAVE_SCOPE();
00383
00384   if (rc < 0)
00385      return (-1);
00386
00387 #if 0
00388   if ((socket->so_state & SS_PRIV) && socket->so_type == SOCK_DGRAM)
00389   {
00390     SOCK_DEBUGF ((", SS_PRIV"));
00391
00392     /* Clear any effect of previous ICMP errors etc.
00393      */
00394     socket->so_state &= ~(SS_CONN_REFUSED | SS_CANTSENDMORE | SS_CANTRCVMORE);
00395     socket->so_error  = 0;
00396
00397     lport = socket->udp_sock->myport;
00398     grab_localport (lport);
00399   }
00400 #endif
00401
00402   if (rdata)  /* Must be SOCK_DGRAM */
00403   {
00404     _udp_Socket *udp = socket->udp_sock;
00405
00406     /* free new rx-buffer set in connect() / _UDP_open().
00407      */
00408     DISABLE();
00409     _sock_free_rcv_buf ((sock_type*)udp);
00410     udp->rx_data = rdata;      /* reuse previous data buffer */
00411     ENABLE();
00412
00413     grab_localport (lport);    /* Restore free'd localport */
00414   }
00415
00416   /* restore keepalive timer changed in connect()
00417    */
00418   socket->keepalive = keepalive;
00419   return (1);
00420 }
00421
00422 /*
00423  * Check for enough room in Tx-buffer for a non-blocking socket
00424  * to transmit without waiting. Only called for SOCK_DGRAM/SOCK_STREAM
00425  * sockets.
00426  *
00427  * If '*len > room', modify '*len' on output to 'room' (the size of
00428  * bytes left in Tx-buf).
00429  */
00430 static __inline BOOL check_non_block_tx (Socket *socket, unsigned *len)
00431 {
00432   sock_type *sk;
00433   unsigned   room;
00434
00435   if (socket->so_type == SOCK_DGRAM)
00436        sk = (sock_type*) socket->udp_sock;
00437   else sk = (sock_type*) socket->tcp_sock;
00438
00439   room = sock_tbleft (sk);
00440   if (*len <= room)
00441      return (TRUE);   /* okay, enough room, '*len' unmodified */
00442
00443 #if 0
00444   WATT_YIELD();       /* a small delay to clear up things */
00445   tcp_tick (sk);
00446
00447   room = sock_tbleft (sk);
00448   if (*len <= room)
00449      return (TRUE);
00450 #endif
00451
00452   /* Still no room, but cannot split up datagrams (only in IP-fragments)
00453    */
00454   if (socket->so_type == SOCK_DGRAM)
00455      return (FALSE);
00456
00457   /* Stream: Tx room below (or equal) low-water mark is failure.
00458    */
00459   if (*len > 0 && room <= socket->send_lowat)
00460      return (FALSE);
00461
00462   /* Streams may be split up, modify '*len'
00463    */
00464   *len = room;
00465   return (TRUE);
00466 }
00467
00468 /*
00469  * TCP transmitter.
00470  */
00471 static int tcp_transmit (Socket *socket, const void *buf, unsigned len,
00472                          int flags)
00473 {
00474   sock_type *sk = (sock_type*)socket->tcp_sock;
00475   int        rc;
00476
00477   /* Don't timeout BSD sockets on inactivity (not sending)
00478    */
00479   sk->tcp.datatimer = 0;
00480
00481   tcp_tick (sk);
00482   tcp_Retransmitter (TRUE);
00483
00486   if (sk->tcp.state < tcp_StateESTAB || sk->tcp.state >= tcp_StateLASTACK)
00487   {
00488     socket->so_state |= SS_CANTSENDMORE;
00489     SOCK_DEBUGF ((", EPIPE"));
00490     SOCK_ERRNO (EPIPE);       /* !! was ENOTCONN */
00491     return (-1);
00492   }
00493
00494   if (socket->so_state & SS_NBIO)
00495   {
00496     unsigned in_len = len;
00497
00498     if (!check_non_block_tx(socket,&len))
00499     {
00500       SOCK_DEBUGF ((", EWOULDBLOCK"));
00501       SOCK_ERRNO (EWOULDBLOCK);
00502       return (-1);
00503     }
00504     if (in_len != len)
00505        SOCK_DEBUGF ((" [%u]", len)); /* trace "len=x [y]" */
00506   }
00507
00508 #if defined(USE_IPV6)
00509   if (socket->so_family == AF_INET6)
00510   {
00511     struct sockaddr_in6 *ra = (struct sockaddr_in6*) socket->remote_addr;
00512
00513     SOCK_DEBUGF ((", %s (%d) / TCP",
00514                   _inet6_ntoa(&ra->sin6_addr),
00515                   ntohs(socket->remote_addr->sin_port)));
00516     ARGSUSED (ra);
00517   }
00518   else
00519 #endif
00520      SOCK_DEBUGF ((", %s (%d) / TCP",
00521                    inet_ntoa(socket->remote_addr->sin_addr),
00522                    ntohs(socket->remote_addr->sin_port)));
00523
00524 #if 0
00525   if (len > sizof(sk->tcp.max_tx_data) - 1)
00526   {
00527     unsigned total  = len;
00528     BYTE    *buffer = (BYTE*)buf;
00529
00530     while (1)
00531     {
00532       if (sock_tbused(sk) == 0)  /* Tx buffer empty */
00533       {
00534         unsigned bytes = min (sk->tcp.max_tx_data, total);
00535
00536         if (bytes > 0)
00537         {
00538           buffer += sock_enqueue (sk, buffer, bytes);
00539           total  -= bytes;
00540         }
00541         else
00542           break;
00543       }
00544       if (!tcp_tick(sk))
00545          break;
00546     }
00547     rc = buffer - (BYTE*)buf;
00548   }
00549   else
00550 #endif
00551     rc = sock_write (sk, (const BYTE*)buf, len);
00552
00553   socket->keepalive = 0UL;
00554
00555   if (rc <= 0)    /* error in tcp_write() */
00556   {
00557     if (sk->tcp.locflags & LF_GOT_ICMP) /* got ICMP host/port unreachable */
00558     {
00559       SOCK_DEBUGF ((", ECONNREFUSED")); /* !! a better code? */
00560       SOCK_ERRNO (ECONNREFUSED);
00561     }
00562     else if (sk->tcp.state != tcp_StateESTAB)
00563     {
00564       SOCK_DEBUGF ((", EPIPE"));
00565       SOCK_ERRNO (EPIPE);     /* !! was ENOTCONN */
00566     }
00567     else
00568     {
00569       SOCK_DEBUGF ((", ENETDOWN"));
00570       SOCK_ERRNO (ENETDOWN);
00571     }
00572     return (-1);
00573   }
00574   ARGSUSED (flags);
00575   return (rc);
00576 }
00577
00578
00579 /*
00580  * UDP transmitter
00581  */
00582 static int udp_transmit (Socket *socket, const void *buf, unsigned len)
00583 {
00584   sock_type  *sk     = (sock_type*) socket->udp_sock;
00585   BOOL        is_ip6 = (socket->so_family == AF_INET6);
00586   BOOL        is_bcast, is_mcast;
00587   unsigned    tx_room;
00588   int         rc;
00589   const void *dest;
00590
00591   if (!tcp_tick(sk))
00592   {
00593     socket->so_state |= SS_CANTSENDMORE;
00594     SOCK_DEBUGF ((", EPIPE (can't send)"));
00595     SOCK_ERRNO (EPIPE);     /* !! was ENOTCONN */
00596     return (-1);
00597   }
00598
00599   tcp_Retransmitter (TRUE);
00600
00601   if ((socket->so_state & SS_NBIO) &&
00602       !check_non_block_tx(socket,&len))
00603   {
00604     SOCK_DEBUGF ((", EWOULDBLOCK"));
00605     SOCK_ERRNO (EWOULDBLOCK);
00606     return (-1);
00607   }
00608
00609 #if defined(USE_IPV6)
00610   if (is_ip6)
00611   {
00612     const struct sockaddr_in6 *ra = (const struct sockaddr_in6*)socket->remote_addr;
00613
00614     dest = &ra->sin6_addr.s6_addr[0];
00615     is_bcast = IN6_IS_ADDR_MC_GLOBAL (dest);
00616     is_mcast = IN6_IS_ADDR_MULTICAST (dest);
00617
00618     SOCK_DEBUGF ((", %s (%d) / UDP %s", _inet6_ntoa(dest),
00619                   ntohs(socket->remote_addr->sin_port),
00620                   is_mcast ? "(mcast)" : ""));
00621   }
00622   else
00623 #endif
00624   {
00625     dest     = &socket->remote_addr->sin_addr.s_addr;
00626     is_bcast = (*(DWORD*)dest == INADDR_BROADCAST ||
00627                 *(DWORD*)dest == INADDR_ANY);
00628     is_mcast = IN_MULTICAST (ntohl(*(DWORD*)dest));
00629
00630     SOCK_DEBUGF ((", %s (%d) / UDP %s",
00631                   inet_ntoa(*(struct in_addr*)dest),
00632                   ntohs(socket->remote_addr->sin_port),
00633                   is_mcast ? "(mcast)" : ""));
00634   }
00635
00636   if (len == 0)   /* 0-byte probe packet */
00637      return raw_transmit (socket, NULL, 0);
00638
00639   tx_room = sock_tbleft (sk);  /* always MTU-28 */
00640
00641   /* Special tests for broadcast messages
00642    */
00643   if (is_bcast)
00644   {
00645     if (len > tx_room)   /* no room, fragmented broadcasts not allowed */
00646     {
00647       SOCK_DEBUGF ((", EMSGSIZE"));
00648       SOCK_ERRNO (EMSGSIZE);
00649       goto drop;
00650     }
00651     if (_pktserial)           /* Link-layer doesn't allow broadcast */
00652     {
00653       SOCK_DEBUGF ((", EADDRNOTAVAIL"));
00654       SOCK_ERRNO (EADDRNOTAVAIL);
00655       goto drop;
00656     }
00657   }
00658
00659   /* set new TTL if setsockopt() used before sending to Class-D socket
00660    */
00661   if (is_mcast)
00662      udp_SetTTL (socket->udp_sock, socket->ip_ttl);
00663
00664 #if defined(USE_FRAGMENTS)
00665   if (len > USHRT_MAX - sizeof(udp_Header))
00666   {
00667     SOCK_DEBUGF ((", EMSGSIZE"));
00668     SOCK_ERRNO (EMSGSIZE);
00669     if (!is_ip6)
00670        STAT (ip4stats.ips_toolong++);
00671     return (-1);
00672   }
00673
00674   if (!is_ip6 && len > tx_room)
00675      return _IP4_SEND_FRAGMENTS (sk, UDP_PROTO, *(DWORD*)dest, buf, len);
00676 #endif
00677
00678   sk->udp.hisaddr = ntohl (socket->remote_addr->sin_addr.s_addr);
00679   sk->udp.hisport = ntohs (socket->remote_addr->sin_port);
00680
00681   rc = sock_write (sk, (BYTE*)buf, len);
00682
00683   /* Patch hisaddr/hisport so that udp_demux() will handle further
00684    * traffic as broadcast.
00685    */
00686   if (socket->so_state & SS_PRIV)
00687   {
00688     sk->udp.hisaddr = INADDR_BROADCAST;
00689     sk->udp.hisport = IPPORT_ANY;
00690   }
00691
00692   if (rc <= 0)    /* error in udp_write() */
00693   {
00694     if (sk->udp.locflags & LF_GOT_ICMP)
00695     {
00696       SOCK_DEBUGF ((", ECONNREFUSED"));
00697       SOCK_ERRNO (ECONNREFUSED);
00698     }
00699     else
00700     {
00701       SOCK_DEBUGF ((", ENETDOWN"));
00702       SOCK_ERRNO (ENETDOWN);
00703     }
00704     return (-1);
00705   }
00706   return (rc);
00707
00708 drop:
00709   if (is_ip6)
00710        STAT (ip6stats.ip6s_odropped++);
00711   else STAT (ip4stats.ips_odropped++);
00712   return (-1);
00713 }
00714
00721 static int ip4_transmit (Socket *socket, const void *tx, unsigned len)
00722 {
00723   eth_address  eth;
00724   u_long       dest;
00725   unsigned     tx_len, tx_room;
00726   sock_type   *sk  = (sock_type*) socket->raw_sock;
00727   struct ip   *ip  = (struct ip*) tx;
00728   const  BYTE *buf = (const BYTE*) tx;
00729   UINT   h_len, o_len;
00730
00731   if (ip)            /* NULL if called from udp_transmit() */
00732   {
00733     if ((socket->so_state & SS_NBIO) &&
00734         sock_tbleft(sk) < (len + socket->send_lowat))
00735     {
00736       SOCK_DEBUGF ((", EWOULDBLOCK"));
00737       SOCK_ERRNO (EWOULDBLOCK);
00738       return (-1);
00739     }
00740   }
00741
00742   SOCK_DEBUGF ((", %s / Raw", inet_ntoa(socket->remote_addr->sin_addr)));
00743
00744   if (ip && (socket->inp_flags & INP_HDRINCL))
00745   {
00746     dest    = ip->ip_dst.s_addr;
00747     tx_len  = len;
00748     tx_room = _mtu;
00749   }
00750   else
00751   {
00752     dest    = socket->remote_addr->sin_addr.s_addr;
00753     tx_len  = len + sizeof (*ip);
00754     tx_room = _mtu + sizeof (*ip);
00755   }
00756
00757   if (socket->ip_opt &&
00758       socket->ip_opt->ip_dst.s_addr)   /* using source routing */
00759      dest = socket->ip_opt->ip_dst.s_addr;
00760
00761   if (!dest)
00762   {
00763     SOCK_DEBUGF ((", no dest"));
00764     SOCK_ERRNO (EHOSTUNREACH);
00765     STAT (ip4stats.ips_noroute++);
00766     return (-1);
00767   }
00768
00769   if (!_arp_resolve(ntohl(dest),&eth))
00770   {
00771     SOCK_DEBUGF ((", no route"));
00772     SOCK_ERRNO (EHOSTUNREACH);
00773     return (-1);
00774   }
00775
00776   if (socket->inp_flags & INP_HDRINCL)   /* IP-header included */
00777   {
00778     DWORD offset = ntohs (ip->ip_off);
00779     WORD  flags  = (WORD) (offset & ~IP_OFFMASK);
00780
00781     offset = (offset & IP_OFFMASK) << 3; /* 0 <= ip_ofs <= 65536-8 */
00782
00783     if ((flags & IP_DF) &&               /* DF requested */
00784         tx_len > tx_room)                /* tx-size above MTU */
00785     {
00786       SOCK_DEBUGF ((", EMSGSIZE"));
00787       SOCK_ERRNO (EMSGSIZE);
00788       STAT (ip4stats.ips_toolong++);
00789       return (-1);
00790     }
00791   }
00792   else if (tx_len + socket->ip_opt_len > tx_room)  /* tx-size above MTU */
00793 #if defined(USE_FRAGMENTS)
00794   {
00795     if (socket->ip_opt_len > 0)
00796        ((void)0);
00797     return _IP4_SEND_FRAGMENTS (sk, socket->so_proto, dest, buf, len);
00798   }
00799 #else
00800   {
00801     SOCK_DEBUGF ((", EMSGSIZE"));
00802     SOCK_ERRNO (EMSGSIZE);
00803     STAT (ip4stats.ips_toolong++);
00804     return (-1);
00805   }
00806 #endif
00807
00808
00809   /* "Normal" small (tx_len < MTU) IPv4 packets are sent below
00810    */
00811   ip = (struct ip*) _eth_formatpacket (&eth, IP4_TYPE);
00812
00813   if (socket->inp_flags & INP_HDRINCL)  /* caller provided IP-header */
00814   {
00815     memcpy (ip, buf, len);   /* SOCK_RAW can never have 0 length */
00816     if (ip->ip_src.s_addr == 0)
00817     {
00818       ip->ip_src.s_addr = gethostid();
00819       ip->ip_sum = 0;
00820       ip->ip_sum = ~CHECKSUM ((void*)ip, ip->ip_hl << 2);
00821     }
00822     if (ip->ip_sum == 0) /* add header checksum if needed */
00823         ip->ip_sum = ~CHECKSUM ((void*)ip, ip->ip_hl << 2);
00824   }
00825   else
00826   {
00827     if (socket->ip_opt && socket->ip_opt_len > 0)
00828     {
00829       BYTE *data;
00830
00831       o_len = min (socket->ip_opt_len, sizeof(socket->ip_opt->IP_opts));
00832       h_len = sizeof(*ip) + o_len;
00833       data  = (BYTE*)ip + h_len;
00834       memcpy (ip+1, &socket->ip_opt->IP_opts[0], o_len);
00835       if (buf && len > 0)
00836          memcpy (data, buf, len);
00837       tx_len += o_len;
00838     }
00839     else
00840     {
00841       if (buf && len > 0)
00842          memcpy (ip+1, buf, len);
00843       h_len = sizeof (*ip);
00844     }
00845
00846     ip->ip_v   = IPVERSION;
00847     ip->ip_hl  = h_len >> 2;
00848     ip->ip_tos = socket->ip_tos;
00849     ip->ip_len = htons (tx_len);
00850     ip->ip_id  = _get_ip4_id();
00851     ip->ip_off = 0;
00852     ip->ip_ttl = socket->ip_ttl;
00853     ip->ip_p   = socket->so_proto;
00854
00855     ip->ip_src.s_addr = gethostid();
00856     ip->ip_dst.s_addr = dest;
00857
00858     ip->ip_sum = 0;
00859     ip->ip_sum = ~CHECKSUM (ip, h_len);
00860   }
00861
00862   if (!_eth_send (tx_len, NULL, __FILE__, __LINE__))
00863   {
00864     SOCK_DEBUGF ((", ENETDOWN"));
00865     SOCK_ERRNO (ENETDOWN);
00866     return (-1);
00867   }
00868   return (len);
00869 }
00870
00871 #if defined(USE_IPV6)
00872
00878 static int ip6_transmit (Socket *socket, const void *tx, unsigned len)
00879 {
00880   eth_address eth;
00881   ip6_address dest;
00882   unsigned    tx_len, tx_room;
00883
00884   sock_type           *sk  = (sock_type*) socket->raw_sock;
00885   struct in6_Header   *ip6 = (struct in6_Header*) tx;
00886   struct sockaddr_in6 *ra  = (struct sockaddr_in6*) socket->remote_addr;
00887   const  BYTE         *buf = (const BYTE*) tx;
00888
00889   if ((socket->so_state & SS_NBIO) &&
00890       sock_tbleft(sk) < (len + socket->send_lowat))
00891   {
00892     SOCK_DEBUGF ((", EWOULDBLOCK"));
00893     SOCK_ERRNO (EWOULDBLOCK);
00894     return (-1);
00895   }
00896
00897   SOCK_DEBUGF ((", %s / Raw", _inet6_ntoa(&ra->sin6_addr)));
00898
00899   if (ip6 && (socket->inp_flags & INP_HDRINCL))
00900   {
00901     memcpy (dest, &ip6->destination[0], sizeof(dest));
00902     tx_len  = len;
00903     tx_room = _mtu;
00904   }
00905   else
00906   {
00907     memcpy (dest, &ra->sin6_addr, sizeof(dest));
00908     tx_len  = len + sizeof (*ip6);
00909     tx_room = _mtu + sizeof (*ip6);
00910   }
00911
00912   if (IN6_IS_ADDR_UNSPECIFIED(&dest) || !icmp6_neigh_solic(&dest,&eth))
00913   {
00914     SOCK_DEBUGF ((", no route"));
00915     SOCK_ERRNO (EHOSTUNREACH);
00916     STAT (ip6stats.ip6s_noroute++);
00917     return (-1);
00918   }
00919
00920   if (!(socket->inp_flags & INP_HDRINCL) &&
00921       tx_len + socket->ip_opt_len > tx_room)
00922   {
00923     SOCK_DEBUGF ((", EMSGSIZE"));
00924     SOCK_ERRNO (EMSGSIZE);
00925     STAT (ip6stats.ip6s_odropped++);
00926     return (-1);
00927   }
00928
00929   ip6 = (struct in6_Header*) _eth_formatpacket (&eth, IP6_TYPE);
00930
00931   if (socket->inp_flags & INP_HDRINCL)
00932   {
00933     if (buf && len > 0)
00934        memcpy (ip6, buf, len);
00935     if (IN6_IS_ADDR_UNSPECIFIED(&ip6->source))
00936        memcpy (&ip6->source[0], _gethostid6(), sizeof(ip6->source));
00937   }
00938   else
00939   {
00940 #if 0  /* option header not yet supported */
00941     if (socket->ip_opt && socket->ip_opt_len > 0)
00942     {
00943       BYTE *data;
00944       int   h_len;
00945
00946       o_len = min (socket->ip_opt_len, sizeof(socket->ip_opt->ip_opts));
00947       h_len = sizeof(*ip) + o_len;
00948       data  = (BYTE*)ip + h_len;
00949       memcpy (ip+1, &socket->ip_opt->ip_opts, o_len);
00950       if (buf && len > 0)
00951          memcpy (data, buf, len);
00952       tx_len += o_len;
00953       if (socket->ip_opt->ip_dst.s_addr)   /* using source routing */
00954          dest = socket->ip_opt->ip_dst.s_addr;
00955     }
00956     else
00957 #endif
00958     {
00959       if (buf && len > 0)
00960          memcpy (ip6+1, buf, len);
00961     }
00962     ip6->pri       = 0;
00963     ip6->ver       = 6;
00964     ip6->len       = htons (len);
00965     ip6->next_hdr  = socket->so_proto;
00966     ip6->hop_limit = _default_ttl;
00967
00968     memset (&ip6->flow_lbl[0], 0, sizeof(ip6->flow_lbl));
00969     memcpy (&ip6->source[0], _gethostid6(), sizeof(ip6->source));
00970     memcpy (&ip6->destination[0], dest, sizeof(ip6->destination));
00971   }
00972
00973   if (!_eth_send (tx_len, NULL, __FILE__, __LINE__))
00974   {
00975     SOCK_DEBUGF ((", ENETDOWN"));
00976     SOCK_ERRNO (ENETDOWN);
00977     return (-1);
00978   }
00979   return (len);
00980 }
00981 #endif  /* USE_IPV6 */
00982
00983
00984 static int raw_transmit (Socket *socket, const void *buf, unsigned len)
00985 {
00986 #if 0
00987   SOCK_ENTER_SCOPE();
00988   tcp_tick (NULL);       /* process other TCBs too */
00989   tcp_Retransmitter (TRUE);
00990   SOCK_LEAVE_SCOPE();
00991 #endif
00992
00993 #if defined(USE_IPV6)
00994   if (socket->so_family == AF_INET6)
00995      return ip6_transmit (socket, buf, len);
00996 #endif
00997
00998   if (socket->so_family == AF_INET)
00999      return ip4_transmit (socket, buf, len);
01000
01001   SOCK_DEBUGF ((", EAFNOSUPPORT "));
01002   SOCK_ERRNO (EAFNOSUPPORT );
01003   return (-1);
01004 }
01005 #endif  /* USE_BSD_API */
Generated on Wed Jan 25 15:42:40 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/TST.C Source File

SRC/TST.C

00001 #include <stdio.h>
00002 #include <stdlib.h>
00003 #include <windows.h>
00004
00005 int main (void)
00006 {
00007   char buf[256];
00008
00009   printf ("$foo = '%s'\n", getenv("foo"));
00010   printf ("$FOO = '%s'\n", getenv("FOO"));
00011
00012   buf[0] = '\0';
00013   GetEnvironmentVariable ("foo", buf, sizeof(buf));
00014   printf ("$foo = '%s'\n", buf);
00015
00016   buf[0] = '\0';
00017   GetEnvironmentVariable ("FOO", buf, sizeof(buf));
00018   printf ("$FOO = '%s'\n", buf);
00019
00020   return (0);
00021 }
00022
00023 #if 0
00024 #define ntohl(x)  (_EAX = x, \
00025                    __emit__(0x86,0xC4),      /* xchg al, ah  */ \
00026                    __emit__(0xC1,0xC8,0x10), /* ror  eax, 16 */ \
00027                    __emit__(0x86,0xC4),      /* xchg al, ah  */ \
00028                    _EAX)
00029
00030 #define IN_MULTICAST(i) (((long)(i) & 0xF0000000) == 0xE0000000)
00031
00032 #define IN6_IS_ADDR_MULTICAST(a) (((unsigned char*) (a))[0] == 0xff)
00033
00034 void chk_mcast (int is_ip6, void *addr)
00035 {
00036   unsigned long *a4 = (unsigned long*) addr;
00037
00038   if ( (!is_ip6 && IN_MULTICAST(ntohl(*a4))) ||
00039        (is_ip6 && IN6_IS_ADDR_MULTICAST(addr)) )
00040      puts ("Multicast");
00041 }
00042 #endif
00043
00044
Generated on Wed Jan 25 15:42:40 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/UDP_DOM.C Source File

SRC/UDP_DOM.C

Go to the documentation of this file.
00001
00033 #include <stdio.h>
00034 #include <stdlib.h>
00035 #include <string.h>
00036 #include <limits.h>
00037 #include <sys/werrno.h>
00038
00039 #include "copyrigh.h"
00040 #include "wattcp.h"
00041 #include "strings.h"
00042 #include "misc.h"
00043 #include "timer.h"
00044 #include "language.h"
00045 #include "pcconfig.h"
00046 #include "pcdbug.h"
00047 #include "pctcp.h"
00048 #include "netaddr.h"
00049 #include "idna.h"
00050 #include "ip6_out.h"
00051 #include "netaddr.h"
00052 #include "udp_dom.h"
00053
00057 #if defined(USE_BSD_API)
00058   #include <netdb.h>
00059
00060   BOOL called_from_resolve = FALSE;
00061   BOOL called_from_ghbn    = FALSE;
00062 #endif
00063
00067 char  defaultdomain [MAX_HOSTLEN+1] = "your.domain.com";
00068 char *def_domain = defaultdomain;
00069
00070 int (*_resolve_hook)(void);         /* user hook for terminating resolve() */
00071 BOOL  _resolve_exit;                /* user hook interrupted */
00072 BOOL  _resolve_timeout;             /* (reverse) lookup timeout */
00073 DWORD dom_ttl;                      /* Time-to-Live of last response */
00074 int   dom_errno;                    /* domain errno (DNS_SRV_xx/DNS_CLI_xx) */
00075 char  dom_cname [MAX_HOSTLEN+1];    /* CNAME of last response */
00076
00077 DWORD def_nameservers [MAX_NAMESERVERS];
00078 WORD  last_nameserver = 0;
00079 UINT  dns_timeout     = 0;
00080 BOOL  dns_recurse     = TRUE;    /* Recurse over dotless names */
00081 BOOL  dns_do_ipv6     = TRUE;    /* Do try to resolve to IPv6 */
00082 BOOL  dns_do_idna     = TRUE;    /* Convert non-ASCII names to/from ACE */
00083 WORD  dns_windns      = 0;       /* How to read/write the WinDns cache */
00084
00085 static const char *loc_domain;   /* current subname to be used */
00086 static DWORD       res_timeout;
00087
00088 /* Additional addresses from last resolve().
00089  * dom_a4_list is on network order!
00090  */
00091 DWORD dom_a4list [MAX_ADDRESSES+1];
00092
00093 #if defined(USE_IPV6)
00094 ip6_address dom_a6list [MAX_ADDRESSES+1];
00095 #endif
00096
00097
00101 static void query_init (struct DNS_query *q, BOOL is_ip6)
00102 {
00103   int i;
00104
00105   memset (&q->head, 0, sizeof(q->head));
00106   q->head.flags   = intel16 (DRD);  /* Query, Recursion desired */
00107   q->head.qdcount = intel16 (1);
00108
00109 #if defined(USE_IPV6)
00110   if (is_ip6)
00111      memset (&dom_a6list, 0, sizeof(dom_a6list));
00112   else
00113 #endif
00114     for (i = 0; i < DIM(dom_a4list); i++)
00115         dom_a4list[i] = INADDR_NONE;
00116   ARGSUSED (is_ip6);
00117 }
00118
00122 static void store_alt_address (const void *data, int idx, BOOL is_ip6)
00123 {
00124   if (idx < 0 || idx >= MAX_ADDRESSES)
00125      return;
00126
00127 #if defined(USE_IPV6)
00128   if (is_ip6)
00129      memcpy (&dom_a6list[idx], data, sizeof(ip6_address));
00130   else
00131 #endif
00132      dom_a4list [idx] = *(DWORD*)data;   /* store on network order */
00133   ARGSUSED (is_ip6);
00134 }
00135
00142 static int pack_domain (BYTE *dst, const char *src)
00143 {
00144   const char *p;
00145   BYTE *q, *savedst;
00146   BOOL  dotflag, defflag;
00147   int   i;
00148
00149   dotflag = defflag = FALSE;
00150   savedst = dst;
00151   p = src;
00152
00153   do                          /* copy whole string */
00154   {
00155     *dst = '\0';
00156     q = dst + 1;
00157     while (*p && *p != '.')
00158        *q++ = *p++;
00159
00160     i = p - src;
00161     if (i > MAX_LABEL_SIZE)    /* label length exceeded */
00162        return (-1);
00163
00164     *dst = i;
00165     *q   = '\0';
00166
00167     if (*p)                   /* update pointers */
00168     {
00169       dotflag = TRUE;
00170       src = ++p;
00171       dst = q;
00172     }
00173     else if (!dotflag && !defflag && loc_domain)
00174     {
00175       p = loc_domain;         /* continue packing with default */
00176       defflag = TRUE;
00177       src = p;
00178       dst = q;
00179     }
00180   }
00181   while (*p);
00182
00183   q++;
00184   return (q - savedst);       /* length of packed string */
00185 }
00186
00191 static int send_query (sock_type *sock, struct DNS_query *q,
00192                        const char *name, DWORD towho, WORD qtype)
00193 {
00194   WORD  len;
00195   BYTE *p;
00196   int   i;
00197
00198   if (!udp_open(&sock->udp,DOM_SRC_PORT,towho,DOM_DST_PORT,NULL))
00199   {
00200     dom_errno = DNS_CLI_SYSTEM;  /* errno ENETDOWN/EHOSTUNREACH etc. */
00201     if (debug_on)
00202     {
00203       outs (_LANG("Domain: "));
00204       outsnl (sock->udp.err_msg);
00205     }
00206     return (0);
00207   }
00208
00209   p = &q->body[0];
00210   i = pack_domain (p, name);
00211   if (i < 0)
00212   {
00213     dom_errno = DNS_CLI_TOOBIG;
00214     return (0);
00215   }
00216
00217   p += i;
00218   *(WORD*)p = intel16 (qtype);  /* QTYPE is A or AAAA */
00219   p += sizeof(WORD);
00220   *(WORD*)p = intel16 (DIN);    /* QCLASS is always internet */
00221   p += sizeof(WORD);
00222
00223   len = p - (BYTE*)q;
00224   if (sock_write (sock, (const BYTE*)q, len) < len)
00225   {
00226     dom_errno = DNS_CLI_SYSTEM;
00227     return (0);
00228   }
00229   return (len);
00230 }
00231
00232 static __inline int countpaths (const char *pathstring)
00233 {
00234   int   count = 0;
00235   const char *p;
00236
00237   for (p = pathstring; *p || *(p+1); p++)
00238       if (*p == '\0')
00239          count++;
00240   return (++count);
00241 }
00242
00243 static __inline const char *getpath (
00244                 const char *pathstring,  /* the path list to search        */
00245                 int         whichone)    /* which path to get, starts at 1 */
00246 {
00247   const char *p;
00248
00249   if (whichone > countpaths(pathstring))
00250      return (NULL);
00251
00252   whichone--;
00253   for (p = pathstring; whichone; p++)
00254       if (*p == '\0')
00255          whichone--;
00256   return (p);
00257 }
00258
00262 static void extract_cname (const struct DNS_query *q, const char *src,
00263                            char *dest, size_t max)
00264 {
00265   const char *p     = src;
00266   const char *start = dest;
00267   const char *end   = dest + max;
00268
00269   while (dest < end)
00270   {
00271     BYTE count = *p++;
00272     WORD ofs;
00273
00274     if ((count & 0xC0) == 0xC0)
00275     {
00276       ofs = ((count - 0xC0) << 8) + *p++;  /* new offset */
00277       p   = (const char*)q + ofs;
00278       count = *p++;
00279     }
00280     if (count == 0)
00281        break;
00282
00283     while (count > 0)
00284     {
00285       if (dest > end)
00286          break;
00287       *dest++ = *p++;
00288       count--;
00289     }
00290     *dest++ = '.';
00291   }
00292   if (dest > start && *(dest-1) == '.')   /* remove trailing '.' */
00293      dest--;
00294   *dest = '\0';
00295 }
00296
00297
00308 static int unpack_domain (const struct DNS_query *q,
00309                           const BYTE *src, size_t src_size,
00310                           BYTE       *dst, size_t dst_size)
00311 {
00312   int   retval = 0;
00313   const BYTE *start   = src;
00314   const BYTE *src_max = src + src_size;
00315   const BYTE *dst_max = dst + dst_size;
00316   const BYTE *base    = (const BYTE*)q;
00317
00318   while (*src && src < src_max && dst < dst_max)
00319   {
00320     int i, j = *src;
00321
00322     while ((j & 0xC0) == 0xC0)
00323     {
00324       if (!retval)
00325          retval = src - start + 2;
00326       src++;
00327       src = &base [((j - 0xC0) << 8) + *src];
00328       j = *src;
00329     }
00330
00331     src++;
00332     for (i = 0; i < (j & ~0xC0); i++)
00333     {
00334       if (dst >= dst_max-1)
00335          return (-1);
00336       *dst++ = *src++;
00337     }
00338     *dst++ = '.';
00339   }
00340
00341   if (src > start)
00342   {
00343     *(--dst) = '\0';     /* add terminator */
00344     src++;               /* account for terminator on src */
00345   }
00346
00347   if (!retval)
00348      retval = src - start;
00349   return (retval);
00350 }
00351
00352
00362 static int read_response (const struct DNS_query *q, int len,
00363                           WORD qtype, void *addr)
00364 {
00365   WORD  nans  = intel16 (q->head.ancount);   /* # of answers */
00366   WORD  flags = intel16 (q->head.flags);
00367   BYTE  rcode = (DRCODE & flags);
00368   BYTE  space [sizeof(q->body)];
00369   const BYTE *p;
00370   int   i, num_addr;
00371
00372   if (rcode != DNS_SRV_OK)  /* not okay reply */
00373   {
00374     dom_errno = rcode;
00375     return (0);
00376   }
00377
00378   if (nans == 0 ||         /* not at least one answer */
00379       !(flags & DQR))      /* response flag not set */
00380   {
00381     dom_errno = DNS_SRV_NAME;
00382     return (0);
00383   }
00384
00385   len -= sizeof(q->head);
00386   p = &q->body[0];
00387   i = unpack_domain (q, p, len, space, sizeof(space));
00388   if (i < 0)
00389   {
00390     dom_errno = DNS_CLI_ILL_RESP;
00391     return (0);
00392   }
00393
00394   /* spec defines name then QTYPE + QCLASS = 4 bytes
00395    */
00396   p += i + 4;
00397
00398   /* no canonical name yet
00399    */
00400   dom_cname[0] = '\0';
00401
00402   /* There may be several answers.  We will return the first A or
00403    * AAAA-record. If there's a CNAME-record, store the name too.
00404    */
00405   num_addr = 0;
00406   while (nans-- > 0 && len > 0)            /* look at each answer */
00407   {
00408     const struct DNS_resource *rrp;
00409     size_t rr_len;
00410     WORD   rr_type;
00411
00412     i = unpack_domain (q, p, len, space, sizeof(space));
00413     if (i < 0)
00414        break;
00415
00416     p  += i;                               /* account for string */
00417     rrp = (struct DNS_resource*) p;        /* resource record here */
00418     rr_len = intel16 (rrp->rdlength);      /* length of this record */
00419     rr_type = intel16 (rrp->rtype);
00420
00421     if (intel16(rrp->rclass) == DIN)       /* Internet (ARPA) class */
00422     {
00423       if (rr_type == qtype)                /* Record type A or AAAA */
00424       {
00425         BOOL is_ip6 = (qtype == DTYPE_AAAA);
00426
00427         if (num_addr == 0)   /* prefered address should always be 1st */
00428         {
00429           /* save IPv4/IPv6 address */
00430           if (is_ip6)
00431                memcpy (addr, &rrp->rdata[0], sizeof(ip6_address));
00432           else *(DWORD*)addr = intel (*(DWORD*)&rrp->rdata[0]);
00433
00434           dom_ttl   = intel (rrp->ttl);    /* TTL in seconds */
00435           dom_errno = DNS_SRV_OK;
00436         }
00437         else
00438           store_alt_address (&rrp->rdata[0], num_addr-1, is_ip6);
00439         num_addr++;
00440       }
00441       else if (rr_type == DTYPE_CNAME && !dom_cname[0])
00442       {
00443         size_t max = sizeof(dom_cname) - 1;
00444         extract_cname (q, (const char*)rrp->rdata, dom_cname, max);
00445       }
00446     }
00447     p   += RESOURCE_HEAD_SIZE + rr_len;    /* length of rest of RR */
00448     len -= RESOURCE_HEAD_SIZE + rr_len;
00449   }
00450
00451   if (num_addr > 0)
00452      return (1);
00453
00454   /* Could be a reponse with a CNAME record but no A record, so
00455    * turn it into a "Name not found" error.
00456    */
00457   dom_errno = DNS_SRV_NAME;
00458   return (0);
00459 }
00460
00461 /*
00462  * Check if the ID in the reply is among our ID(s) sent.
00463  * If not, ignore the response and keep waiting.
00464  */
00465 static __inline BOOL legal_ident (WORD id, const WORD *cache, int num)
00466 {
00467   int i;
00468
00469   for (i = 0; i < num; i++)
00470       if (id == cache[i])
00471          return (TRUE);
00472   return (FALSE);
00473 }
00474
00484 static int lookup_domain (
00485        struct DNS_query *q,        /* the UDP/IPv4 query packet */
00486        const char  *mname,         /* the host-name to query */
00487        BOOL         add_dom,       /* append domain suffix */
00488        DWORD        nameserver,    /* nameserver to use */
00489        BOOL        *timedout,      /* set on timeout */
00490        BOOL         is_ip4,        /* Query A or AAAA record */
00491        void        *addr)          /* return address */
00492 {
00493   _udp_Socket sock;
00494   sock_type  *dom_sock = NULL;
00495
00496   struct DNS_query reply;
00497   char   namebuf [3*MAX_HOSTLEN]; /* may overflow!! */
00498   size_t len;
00499   int    rc;
00500   WORD   qtype = is_ip4 ? DTYPE_A : DTYPE_AAAA;
00501   WORD   id_cache [100];        /* should be plenty */
00502   int    id_index = 0;
00503   UINT   sec;
00504
00505   *timedout = TRUE;  /* assume we will timeout */
00506
00507   if (!nameserver)   /* no nameserver, give up now */
00508   {
00509     _resolve_exit = TRUE;
00510     dom_errno = DNS_CLI_NOSERV;
00511     outsnl (dom_strerror(dom_errno));
00512     return (0);
00513   }
00514
00515   while (*mname && *mname <= ' ')   /* kill leading cruft */
00516      mname++;
00517
00518   if (*mname == '\0')
00519   {
00520     dom_errno = DNS_CLI_OTHER;
00521     return (0);
00522   }
00523
00524   strcpy (namebuf, mname);
00525
00526 #if defined(USE_IDNA)
00527   /*
00528    * Convert 'namebuf' to ACE form if needed
00529    */
00530   len = sizeof (namebuf);
00531   if (dns_do_idna && !IDNA_convert_to_ACE(namebuf,&len))
00532   {
00533     dom_errno = DNS_CLI_ILL_IDNA;
00534     return (0);
00535   }
00536 #endif
00537
00538   if (add_dom)
00539   {
00540     int dot = strlen (namebuf) - 1;
00541
00542     if (namebuf[dot] != '.')     /* if no trailing dot */
00543     {
00544       if (loc_domain)            /* there is a search list */
00545       {
00546         strcat (namebuf, ".");
00547         strcat (namebuf, getpath(loc_domain,1));
00548       }
00549     }
00550     else
00551       namebuf [dot] = '\0';      /* kill trailing dot */
00552   }
00553
00554   /*
00555    * This is not terribly good, but it attempts to use a binary
00556    * exponentially increasing delay.
00557    */
00558
00559   for (sec = 2; sec < dns_timeout-1 && !_resolve_exit; sec *= 2)
00560   {
00561     q->head.ident = Random (1, USHRT_MAX);
00562
00563     /* We might get a reply for a previous request with different ID.
00564      * We therefore use a small cache of IDs sent.
00565      */
00566     if (id_index < DIM(id_cache))
00567          id_cache [id_index++] = q->head.ident;
00568     else outsnl (_LANG("udp_dom(): ID cache full"));
00569
00570     dom_sock = (sock_type*) &sock;
00571
00572     if (!send_query(dom_sock,q,namebuf,nameserver,qtype))
00573     {
00574       _resolve_timeout = TRUE;
00575       rc = 0;
00576       goto quit; /* doesn't hurt to do sock_close() if udp_open() fails */
00577     }
00578
00579 again:
00580     ip_timer_init (dom_sock, sec);
00581     do
00582     {
00583       if (!tcp_tick(dom_sock))   /* ICMP Port unreachable etc. */
00584       {
00585         rc = 0;
00586         dom_errno = DNS_CLI_REFUSE;
00587         goto quit;
00588       }
00589
00590       if (ip_timer_expired(dom_sock) || chk_timeout(res_timeout))
00591       {
00592         /* continue the for-loop with a new request */
00593         break;
00594       }
00595
00596       if (_watt_cbroke || (_resolve_hook && (*_resolve_hook)() == 0))
00597       {
00598         dom_errno = DNS_CLI_USERQUIT;
00599         _resolve_exit = TRUE;
00600         rc = 0;
00601         goto quit;
00602       }
00603
00604       if (dom_sock->udp.usr_yield)
00605           (*dom_sock->udp.usr_yield)();
00606       else WATT_YIELD();
00607
00608       if (sock_dataready(dom_sock))
00609          *timedout = FALSE;
00610     }
00611     while (*timedout);
00612
00613     if (!*timedout)           /* got an answer */
00614        break;
00615   }
00616
00617   if (*timedout || !dom_sock)
00618   {
00619     _resolve_timeout = TRUE;
00620     rc = 0;
00621     dom_errno = DNS_CLI_TIMEOUT;
00622   }
00623   else
00624   {
00625     memset (&reply, 0, sizeof(reply));
00626     len = sock_fastread (dom_sock, (BYTE*)&reply, sizeof(reply));
00627     if (len < SIZEOF(reply.head))
00628     {
00629       dom_errno = DNS_CLI_ILL_RESP;
00630       rc = 0;
00631     }
00632     else if (!legal_ident(reply.head.ident,id_cache,id_index))
00633     {
00634       *timedout = TRUE;
00635       goto again;
00636     }
00637     else
00638     {
00639       rc = read_response (&reply, len, qtype, addr);
00640 #if defined(USE_IDNA)
00641       if (dns_do_idna && dom_cname[0])
00642       {
00643         len = sizeof (dom_cname);
00644         IDNA_convert_from_ACE (dom_cname, &len);
00645       }
00646 #endif
00647     }
00648   }
00649
00650 quit:
00651   if (dom_sock)  /* if we ran the above for-loop */
00652      sock_close (dom_sock);
00653   return (rc);
00654 }
00655
00660 static const char *next_domain (const char *domain, int count)
00661 {
00662   const char *p = domain;
00663   int   i;
00664
00665   for (i = 0; i < count; i++)
00666   {
00667     p = strchr (p, '.');
00668     if (!p)
00669        return (NULL);
00670     p++;
00671   }
00672   return (p);
00673 }
00674
00678 static const char *server_error (enum DNS_serv_resp err)
00679 {
00680   switch (err)
00681   {
00682     case DNS_SRV_OK:
00683          return ("Success");
00684     case DNS_SRV_FORM:
00685          return ("Format error");
00686     case DNS_SRV_FAIL:
00687          return ("Error in response");
00688     case DNS_SRV_NAME:
00689          return ("Name not found");
00690     case DNS_SRV_NOTIMPL:
00691          return ("Not implemented");
00692     case DNS_SRV_REFUSE:
00693          return ("Service refused");
00694     case DNS_SRV_MAX:
00695          break;
00696   }
00697   return (NULL);
00698 }
00699
00703 static const char *client_error (enum DNS_client_code err)
00704 {
00705   switch (err)
00706   {
00707     case DNS_CLI_SYSTEM:
00708          return (char*) strerror_s (_w32_errno);
00709     case DNS_CLI_USERQUIT:
00710          return ("User terminated");
00711     case DNS_CLI_NOSERV:
00712          return ("No nameserver defined");
00713     case DNS_CLI_TIMEOUT:
00714          return ("Request timeout");
00715     case DNS_CLI_ILL_RESP:
00716          return ("Illegal short response");
00717     case DNS_CLI_ILL_IDNA:
00718          return ("IDNA convertion failed");
00719     case DNS_CLI_TOOBIG:
00720          return ("Name too large");
00721     case DNS_CLI_REFUSE:
00722          return ("Service refused");
00723     case DNS_CLI_NOIP:
00724          return ("Cannot resolve without IP");
00725     case DNS_CLI_NOIPV6:
00726          return ("IPv6 DNS disabled");
00727     case DNS_CLI_OTHER:
00728          return ("Other error");
00729     case DNS_CLI_MAX:
00730          break;
00731   }
00732   return (NULL);
00733 }
00734
00735
00739 const char *dom_strerror (int err)
00740 {
00741   static char buf[80];
00742   const char *rc = err < DNS_SRV_MAX ? server_error (err) :
00743                    err < DNS_CLI_MAX ? client_error (err) : NULL;
00744   if (rc)
00745      return (rc);
00746   strcpy (buf, "Unknown error ");
00747   itoa (err, buf+strlen(buf), 10);
00748   return (buf);
00749 }
00750
00756 DWORD resolve (const char *name)
00757 {
00758   DWORD       ip4_addr = 0UL;
00759   int         count;
00760   char        namebuf [MAX_HOSTLEN], *dot;
00761   BOOL        timeout [MAX_NAMESERVERS];
00762   BOOL        got_ip  = FALSE;
00763   BOOL        recurse = TRUE;
00764   unsigned    len;
00765   static WORD brk_mode;
00766   struct DNS_query request;
00767
00768   if (!name || *name == '\0')
00769   {
00770     dom_errno = DNS_CLI_OTHER;
00771     return (0);
00772   }
00773
00774   len = strlen (name);
00775   if (len >= sizeof(namebuf)-1)
00776   {
00777     dom_errno = DNS_CLI_TOOBIG;
00778     return (0);
00779   }
00780
00781   memcpy (namebuf, name, len+1); /* make a copy of 'name' */
00782   rip (namebuf);                 /* strip off '\r' and/or '\n' */
00783
00784   if (isaddr(namebuf))
00785   {
00786     dom_errno = 0;
00787     return aton (namebuf);
00788   }
00789
00790   /* Names with trailing '.' shall not perform a DNS recursion
00791    */
00792   dot = strrchr (namebuf, '.');
00793   if (dot && dot[1] == '\0')
00794   {
00795     *dot = '\0';
00796     recurse = FALSE;
00797   }
00798
00799 #if defined(USE_BSD_API)
00800   if (!called_from_ghbn)         /* This hack avoids reentrancy */
00801   {                              /* from gethostbyname() */
00802     const struct hostent *h;
00803
00804     called_from_resolve = TRUE;  /* ditto hack ! (vice versa) */
00805     h = gethostbyname (namebuf);
00806     called_from_resolve = FALSE;
00807     if (h)                       /* IP from host-file or cache */
00808     {
00809       /*
00810        * NOTE: gethostbyname() returns network order
00811        *       We assume IPv4 (32-bit)
00812        */
00813       dom_errno = 0;
00814       return intel (*(DWORD*)h->h_addr_list[0]);
00815     }
00816
00817     /* not found in host-file or cache, ask the DNS server(s)
00818      */
00819   }
00820 #endif
00821
00822 #if defined(WIN32) && defined(HAVE_WINDNS_H)
00823   /*
00824    * Try the WinDns cache first
00825    */
00826   if (WinDnsQuery_A4(namebuf, &ip4_addr))
00827      return (ip4_addr);
00828 #endif
00829
00830   /* If no nameserver or no IP-address, give up now
00831    */
00832   if (last_nameserver == 0)
00833   {
00834     dom_errno = DNS_CLI_NOSERV;
00835     outsnl (dom_strerror(dom_errno));
00836     return (0);
00837   }
00838
00839   if (my_ip_addr == 0)
00840   {
00841     dom_errno = DNS_CLI_NOIP;
00842     outsnl (dom_strerror(dom_errno));
00843     return (0);
00844   }
00845
00846   if (dns_timeout == 0)
00847       dns_timeout = (UINT)sock_delay << 2;
00848   res_timeout = set_timeout (1000 * dns_timeout);
00849
00850   count = 0;
00851   memset (&timeout, 0, sizeof(timeout));
00852   query_init (&request, FALSE);
00853
00854   NEW_BREAK_MODE (brk_mode, 1);
00855
00856   _resolve_exit = _resolve_timeout = FALSE;
00857
00858   do
00859   {
00860     int i;
00861
00862     if (!recurse || strchr(namebuf,'.'))
00863     {
00864       loc_domain = NULL;
00865       count = -1;
00866     }
00867     else if (!dns_recurse && count == 0)
00868     {
00869       loc_domain = NULL;
00870       count = -1;
00871     }
00872     else
00873     {
00874       loc_domain = next_domain (def_domain, count);
00875       if (!loc_domain)
00876          count = -1;     /* use default name */
00877     }
00878
00879     for (i = 0; i < last_nameserver; i++)
00880     {
00881       if (!timeout[i])
00882       {
00883         int rc = lookup_domain (&request, namebuf, count != -1,
00884                                 def_nameservers[i], timeout+i,
00885                                 TRUE, &ip4_addr);
00886         if (rc)
00887         {
00888           got_ip = TRUE;
00889           break;            /* got address, bail out of for loop */
00890         }
00891         if (_resolve_exit)
00892            break;           /* an error occured, return to caller */
00893       }
00894
00895       /*
00896        * Should we really try the other nameservers if the first
00897        * says the host doesn't exist? Maybe a trusting mechanism
00898        * is needed (?)
00899        */
00900     }
00901     if (count == -1)
00902        break;
00903     count++;
00904   }
00905   while (!got_ip && !_resolve_exit);
00906
00907 #if defined(WIN32) && defined(HAVE_WINDNS_H)
00908   /* Put the result in the WinDns cache.
00909    */
00910   if (got_ip)
00911      WinDnsCachePut_A4 (namebuf, ip4_addr);
00912 #endif
00913
00914   OLD_BREAK_MODE (brk_mode);
00915
00916   return (ip4_addr);
00917 }
00918
00919 #if defined(USE_IPV6)
00920 int resolve_ip6 (const char *name, void *addr)
00921 {
00922   struct DNS_query request;
00923   ip6_address      ip6_addr;
00924
00925   int      count;
00926   unsigned len;
00927   char     namebuf [MAX_HOSTLEN];
00928   BOOL     timeout [MAX_NAMESERVERS];
00929   WORD     brk_mode;
00930   BOOL     got_ip = FALSE;
00931
00932   if (!dns_do_ipv6)
00933   {
00934     dom_errno = DNS_CLI_NOIPV6;
00935     TCP_CONSOLE_MSG (1, ("%s\n", dom_strerror(dom_errno)));
00936     return (0);
00937   }
00938
00939   len = strlen (name);
00940   if (len >= sizeof(namebuf)-1)
00941   {
00942     dom_errno = DNS_CLI_TOOBIG;
00943     TCP_CONSOLE_MSG (1, ("%s\n", dom_strerror(dom_errno)));
00944     return (0);
00945   }
00946
00947   memcpy (namebuf, name, len+1);
00948   rip (namebuf);
00949
00950 #if defined(WIN32) && defined(HAVE_WINDNS_H)
00951   /*
00952    * Try the WinDns cache first
00953    */
00954   if (WinDnsQuery_A6(namebuf, &ip6_addr))
00955   {
00956     memcpy (addr, &ip6_addr, sizeof(ip6_addr));
00957     return (1);
00958   }
00959 #endif
00960
00961   if (last_nameserver == 0)
00962   {
00963     dom_errno = DNS_CLI_NOSERV;
00964     outsnl (dom_strerror(dom_errno));
00965     return (0);
00966   }
00967
00968   if (my_ip_addr == 0)
00969   {
00970     dom_errno = DNS_CLI_NOIP;
00971     outsnl (dom_strerror(dom_errno));
00972     return (0);
00973   }
00974
00975   if (dns_timeout == 0)
00976       dns_timeout = (UINT)sock_delay << 2;
00977   res_timeout = set_timeout (1000 * dns_timeout);
00978
00979   count = 0;
00980   memset (&timeout, 0, sizeof(timeout));
00981   query_init (&request, TRUE);
00982
00983   NEW_BREAK_MODE (brk_mode, 1);
00984   _resolve_exit = _resolve_timeout = FALSE;
00985
00986   do
00987   {
00988     int i;
00989
00990     if (strchr(namebuf,'.'))
00991     {
00992       loc_domain = NULL;
00993       count = -1;
00994     }
00995     else if (!dns_recurse && count == 0)
00996     {
00997       loc_domain = NULL;
00998       count = -1;
00999     }
01000     else
01001     {
01002       loc_domain = next_domain (def_domain, count);
01003       if (!loc_domain)
01004          count = -1;
01005     }
01006
01007     for (i = 0; i < last_nameserver; i++)
01008     {
01009       if (!timeout[i])
01010       {
01011         int rc = lookup_domain (&request, namebuf, count != -1,
01012                                 def_nameservers[i], timeout+i,
01013                                 FALSE, &ip6_addr);
01014         if (rc)
01015         {
01016           got_ip = TRUE;
01017           break;            /* got name, bail out of for loop */
01018         }
01019         if (_resolve_exit)
01020            break;           /* an error occured, return to caller */
01021       }
01022
01023       /*
01024        * Should we really try the other nameservers if the first
01025        * says the host doesn't exist? Maybe a trusting mechanism
01026        * is needed (?)
01027        */
01028     }
01029     if (count == -1)
01030        break;
01031     count++;
01032   }
01033   while (!got_ip && !_resolve_exit);
01034
01035   if (got_ip)
01036   {
01037     memcpy (addr, &ip6_addr, sizeof(ip6_addr));
01038
01039 #if defined(WIN32) && defined(HAVE_WINDNS_H)
01040     /* Put the result in the WinDns cache.
01041      */
01042     WinDnsCachePut_A6 (namebuf, &ip6_addr);
01043 #endif
01044   }
01045
01046   OLD_BREAK_MODE (brk_mode);
01047   return (got_ip ? 1 : 0);
01048 }
01049 #endif /* USE_IPV6 */
01050
Generated on Wed Jan 25 15:42:40 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/UDP_DOM.H Source File

SRC/UDP_DOM.H

Go to the documentation of this file.
00001
00003 #ifndef _w32_UDP_DOM_H
00004 #define _w32_UDP_DOM_H
00005
00006 #define MAX_NAMESERVERS   10  /* max # of nameservers supported (plenty!) */
00007 #define MAX_LABEL_SIZE    63  /* maximum length of a single domain label  */
00008 #define DOMSIZE          512  /* maximum domain message size to mess with */
00009 #define DOM_DST_PORT      53  /* destination port number for DNS protocol */
00010 #define DOM_SRC_PORT    1415  /* local port number for DNS protocol. Old  */
00011                               /* port 997 didn't work with some firewalls */
00012 #include <sys/packon.h>
00013
00014 /*
00015  * Header format (struct DNS_head), from RFC 1035:
00016  *                                  1  1  1  1  1  1
00017  *    0  1  2  3  4  5  6  7  8  9  0  1  2  3  4  5
00018  *  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
00019  *  |                      ID                       |
00020  *  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
00021  *  |QR|   Opcode  |AA|TC|RD|RA|   Z    |   RCODE   |
00022  *  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
00023  *  |                    QDCOUNT                    |
00024  *  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
00025  *  |                    ANCOUNT                    |
00026  *  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
00027  *  |                    NSCOUNT                    |
00028  *  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
00029  *  |                    ARCOUNT                    |
00030  *  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
00031  *
00032  * AA, TC, RA, and RCODE are only set in responses.
00033  * Brief description of the remaining fields:
00034  *      ID      Identifier to match responses with queries
00035  *      QR      Query (0) or response (1)
00036  *      Opcode  For our purposes, always QUERY
00037  *      RD      Recursion desired
00038  *      Z       Reserved (zero)
00039  *      QDCOUNT Number of queries
00040  *      ANCOUNT Number of answers
00041  *      NSCOUNT Number of name server records
00042  *      ARCOUNT Number of additional records
00043  *
00044  * Question format, from RFC 1035:
00045  *                                  1  1  1  1  1  1
00046  *    0  1  2  3  4  5  6  7  8  9  0  1  2  3  4  5
00047  *  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
00048  *  |                                               |
00049  *  /                     QNAME                     /
00050  *  /                                               /
00051  *  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
00052  *  |                     QTYPE                     |
00053  *  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
00054  *  |                     QCLASS                    |
00055  *  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
00056  *
00057  * The QNAME is encoded as a series of labels, each represented
00058  * as a one-byte length (maximum 63) followed by the text of the
00059  * label. The list is terminated by a label of length zero (which can
00060  * be thought of as the root domain).
00061  */
00062
00063 /*
00064  * Header for the DOMAIN queries.
00065  * ALL OF THESE ARE BYTE SWAPPED QUANTITIES!
00066  * We are the poor slobs who are incompatible with the world's byte order.
00067  */
00068 struct DNS_head {
00069        WORD  ident;          /* Unique identifier              */
00070 #if 1
00071        WORD  flags;          /* See below                      */
00072 #else
00073        unsigned rd     : 1;    /* Recursion desired */
00074        unsigned tc     : 1;    /* Truncated message */
00075        unsigned aa     : 1;    /* Authoritative answer */
00076        unsigned opcode : 4;    /* See below */
00077        unsigned qr     : 1;    /* Response = 1, Query = 0 */
00078        unsigned rcode  : 4;    /* Response code */
00079        unsigned cd     : 1;    /* Checking disabled by resolver */
00080        unsigned ad     : 1;    /* Authentic data from named */
00081        unsigned unused : 1;    /* Unused bits */
00082        unsigned ra     : 1;    /* Recursion available */
00083 #endif
00084        WORD  qdcount;        /* Question section, # of entries */
00085        WORD  ancount;        /* Answers, how many              */
00086        WORD  nscount;        /* Count of name server RRs       */
00087        WORD  arcount;        /* Number of "additional" records */
00088      };
00089
00090 /*
00091  * DNS_head::flags
00092  */
00093 #define DQR       0x8000     /* Query = 0, Response = 1 */
00094 #define DOPCODE   0x7100     /* Opcode mask, see below  */
00095 #define DAA       0x0400     /* Authoritative answer    */
00096 #define DTC       0x0200     /* Truncated response      */
00097 #define DRD       0x0100     /* Recursion desired       */
00098 #define DRA       0x0080     /* Recursion available     */
00099 #define DRCODE    0x000F     /* Response code mask, see below */
00100
00101 /*
00102  * Opcode possible values:
00103  */
00104 #define DOPQUERY  0          /* a standard query */
00105 #define DOPIQ     1          /* an inverse query */
00106 #define DOPCQM    2          /* a completion query, multiple reply */
00107 #define DOPCQU    3          /* a completion query, single reply   */
00108 #define DUPDATE   5          /* DNS update (RFC-2136) */
00109 /* the rest reserved for future */
00110
00111 /*
00112  * DNS server response codes; RCODE (stored in dom_errno)
00113  */
00114 enum DNS_serv_resp {
00115      DNS_SRV_OK = 0,         /* 0 = okay response */
00116      DNS_SRV_FORM,           /* 1 = format error  */
00117      DNS_SRV_FAIL,           /* 2 = server failed */
00118      DNS_SRV_NAME,           /* 3 = name error (NXDOMAIN) */
00119      DNS_SRV_NOTIMPL,        /* 4 = function not implemented */
00120      DNS_SRV_REFUSE,         /* 5 = service refused */
00121      DNS_SRV_MAX = 15
00122    };
00123
00124 /*
00125  * DNS client codes (stored in dom_errno)
00126  */
00127 enum DNS_client_code {
00128      DNS_CLI_SYSTEM = DNS_SRV_MAX,  /* See 'errno' */
00129      DNS_CLI_REFUSE,                /* Name server refused */
00130      DNS_CLI_USERQUIT,              /* User terminated via hook or ^C */
00131      DNS_CLI_NOSERV,                /* No nameserver defined */
00132      DNS_CLI_TIMEOUT,               /* Timeout, no reply */
00133      DNS_CLI_ILL_RESP,              /* Illegal/short response */
00134      DNS_CLI_ILL_IDNA,              /* Convert to/from international name failed */
00135      DNS_CLI_TOOBIG,                /* Name/label too large */
00136      DNS_CLI_NOIP,                  /* my_ip_addr == 0 */
00137      DNS_CLI_NOIPV6,                /* IPv6 DNS disabled */
00138      DNS_CLI_OTHER,                 /* Other general error */
00139      DNS_CLI_MAX
00140   };
00141
00142 /*
00143  * Query types (QTYPE)
00144  */
00145 #define DTYPE_A     1         /* host address resource record (A) */
00146 #define DTYPE_CNAME 5         /* host's canonical name record (CNAME) */
00147 #define DTYPE_AAAA  28        /* host address resource record (AAAA) */
00148 #define DTYPE_PTR   12        /* domain name ptr (PTR) */
00149 #define DTYPE_SOA   6         /* start of authority zone (SOA) */
00150 #define DTYPE_SRV   33        /* server selection (SRV), RFC-2052 */
00151
00152 /*
00153  * Query class (QCLASS)
00154  */
00155 #define DIN         1         /* ARPA internet class */
00156 #define DWILD       255       /* Wildcard for several classifications */
00157
00158 /*
00159  * DNS Query request/response header.
00160  */
00161 struct DNS_query {
00162        struct DNS_head head;
00163        BYTE   body [DOMSIZE];
00164      };
00165
00166 /*
00167  * A resource record is made up of a compressed domain name followed by
00168  * this structure.  All of these words need to be byteswapped before use.
00169  * Part of 'struct DNS_query::body'.
00170  */
00171 struct DNS_resource {
00172        WORD   rtype;              /* resource record type = DTYPE_A/AAAA */
00173        WORD   rclass;             /* RR class = DIN                      */
00174        DWORD  ttl;                /* time-to-live, changed to 32 bits    */
00175        WORD   rdlength;           /* length of next field                */
00176        BYTE   rdata [DOMSIZE-10]; /* data field                          */
00177      };
00178
00179 #define RESOURCE_HEAD_SIZE  10
00180
00181 #include <sys/packoff.h>
00182
00183 #define defaultdomain    NAMESPACE (defaultdomain)
00184 #define def_domain       NAMESPACE (def_domain)
00185 #define def_nameservers  NAMESPACE (def_nameservers)
00186 #define dns_timeout      NAMESPACE (dns_timeout)
00187 #define dns_recurse      NAMESPACE (dns_recurse)
00188 #define dns_do_idna      NAMESPACE (dns_do_idna)
00189 #define dns_do_ipv6      NAMESPACE (dns_do_ipv6)
00190 #define dns_windns       NAMESPACE (dns_windns)
00191 #define last_nameserver  NAMESPACE (last_nameserver)
00192 #define dom_ttl          NAMESPACE (dom_ttl)
00193 #define dom_errno        NAMESPACE (dom_errno)
00194 #define dom_cname        NAMESPACE (dom_cname)
00195 #define dom_a4list       NAMESPACE (dom_a4list)
00196 #define dom_a6list       NAMESPACE (dom_a6list)
00197
00198 W32_DATA int (*_resolve_hook)(void);
00199 W32_DATA BOOL  _resolve_exit;
00200 W32_DATA BOOL  _resolve_timeout;
00201
00202 W32_DATA char  defaultdomain [MAX_HOSTLEN+1];
00203 W32_DATA char *def_domain;
00204 W32_DATA DWORD def_nameservers [MAX_NAMESERVERS];
00205 W32_DATA WORD  last_nameserver;
00206 W32_DATA int   dom_errno;
00207
00208 extern char  dom_cname [MAX_HOSTLEN+1];
00209 extern DWORD dom_ttl;
00210 extern BOOL  dns_do_ipv6;
00211 extern BOOL  dns_do_idna;
00212 extern WORD  dns_windns;
00213 extern BOOL  called_from_resolve;
00214 extern BOOL  called_from_ghbn;
00215
00216 extern DWORD       dom_a4list [MAX_ADDRESSES+1];
00217 extern ip6_address dom_a6list [MAX_ADDRESSES+1];
00218
00219 W32_DATA UINT dns_timeout;
00220 W32_DATA BOOL dns_recurse;
00221
00222 W32_FUNC DWORD       resolve      (const char *name);
00223 W32_FUNC int         resolve_ip6  (const char *name, void *addr);
00224 W32_FUNC const char *dom_strerror (int err);
00225
00226 /* In udp_rev.c
00227  */
00228 extern int reverse_lookup_myip (void);
00229 extern int reverse_resolve_ip4 (DWORD ipv4, char *result, size_t size);
00230 extern int reverse_resolve_ip6 (const void *ipv6, char *result, size_t size);
00231
00232 /* In lookup.c
00233  */
00234 W32_FUNC DWORD lookup_host (const char *host, char *ip_str);
00235
00236 #endif
Generated on Wed Jan 25 15:42:40 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/UDP_REV.C Source File

SRC/UDP_REV.C

Go to the documentation of this file.
00001
00005 /*
00006  *  Reverse IPv4/IPv6 lookup functions
00007  *
00008  *  Copyright (c) 1997-2002 Gisle Vanem <giva@bgnett.no>
00009  *
00010  *  Redistribution and use in source and binary forms, with or without
00011  *  modification, are permitted provided that the following conditions
00012  *  are met:
00013  *  1. Redistributions of source code must retain the above copyright
00014  *     notice, this list of conditions and the following disclaimer.
00015  *  2. Redistributions in binary form must reproduce the above copyright
00016  *     notice, this list of conditions and the following disclaimer in the
00017  *     documentation and/or other materials provided with the distribution.
00018  *  3. All advertising materials mentioning features or use of this software
00019  *     must display the following acknowledgement:
00020  *       This product includes software developed by Gisle Vanem
00021  *       Bergen, Norway.
00022  *
00023  *  THIS SOFTWARE IS PROVIDED BY ME (Gisle Vanem) AND CONTRIBUTORS ``AS IS''
00024  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00025  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00026  *  ARE DISCLAIMED.  IN NO EVENT SHALL I OR CONTRIBUTORS BE LIABLE FOR ANY
00027  *  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00028  *  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00029  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00030  *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00031  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00032  *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00033  *
00034  *  \version 0.2
00035  *    \date 14-01-2003
00036  *    \author Yves-Ferrant@t-online.de, Bug-fix, see read_response() below.
00037  */
00038
00039 #include <stdio.h>
00040 #include <stdlib.h>
00041 #include <string.h>
00042
00043 #include "wattcp.h"
00044 #include "strings.h"
00045 #include "misc.h"
00046 #include "timer.h"
00047 #include "language.h"
00048 #include "netaddr.h"
00049 #include "pctcp.h"
00050 #include "pcconfig.h"
00051 #include "idna.h"
00052 #include "bsdname.h"
00053 #include "udp_dom.h"
00054
00059 static size_t query_init_ip4 (struct DNS_query *q, DWORD ip)
00060 {
00061   char *c;
00062   BYTE  i, x;
00063
00064   q->head.ident   = (WORD) set_timeout (0UL);  /* Random ID */
00065   q->head.flags   = intel16 (DRD);             /* Query, Recursion desired */
00066   q->head.qdcount = intel16 (1);
00067   q->head.ancount = 0;
00068   q->head.nscount = 0;
00069   q->head.arcount = 0;
00070
00071   c  = (char*) &q->body[0];
00072   ip = ntohl (ip);
00073   for (i = 0; i < sizeof(ip); i++)
00074   {
00075     x = (BYTE) ip;
00076     ip >>= 8;
00077     *c = (x < 10) ? 1 : (x < 100) ? 2 : 3;
00078     itoa (x, c+1, 10);
00079     c += *c + 1;
00080   }
00081   strcpy (c, "\7in-addr\4arpa");
00082   c += 14;
00083   *(WORD*) c = intel16 (DTYPE_PTR);
00084   c += sizeof(WORD);
00085   *(WORD*) c = intel16 (DIN);
00086   c += sizeof(WORD);
00087
00088   return (c - (char*)q);
00089 }
00090
00097 /*
00098 Here are the decompiled data of the DNS-answer datagramm
00099 DNS_head  CC CB       ID
00100           85 80       DQR | Opcode |AA|TC|RD|RA| Z | DRCODE |  (flags)
00101           00 01       qdcount
00102           00 01       ancount
00103           00 00       nscount
00104           00 00       arcount
00105           01 32 03 31 32 38 03 31 32 38 03 31 32 38 07 69 6E 2D  .2.128.128.128.in-
00106           61 64 64 72 04 61 72 70 61 00                          addr.arpa.
00107 qtype     00 0C
00108 qclass    00 01
00109
00110 Answer    01 32 03 31 32 38 03 31 32 38 03 31 32 38 07 69        .2.128.128.128.i
00111           6E 2D 61 64 64 72 04 61 72 70 61 00                    n-addr.arpa.
00112 qtype     00 0C
00113 qclass    00 01
00114 TTL       00 00 0E 10
00115 Length    00 10
00116 Answer    05 6C 69 6E 75 78 04 79 76 65 73 03 6E 65 74 00        .linux.yves.net
00117
00118 Yves-Ferrant noted that if DNS server does *not* use message compression,
00119 this function failed to find the answer.
00120 Ref. RFC1035, Section 4.1.4. Message compression
00121
00122 */
00123
00124 static BOOL read_response (sock_type *s, char *name, size_t size)
00125 {
00126   struct DNS_query            response;
00127   const  struct DNS_resource *rr;
00128   const  char *name_end;
00129   const  BYTE *c, *resp_end;
00130   size_t len;
00131   BYTE   rcode;
00132   BOOL   compressed;
00133
00134   memset (&response, 0, sizeof(response));
00135   len   = sock_fastread (s, (BYTE*)&response, sizeof(response));
00136   rcode = (DRCODE & intel16(response.head.flags));
00137
00138   if (len < sizeof(response.head) || response.head.qdcount != intel16(1))
00139      goto fail;
00140
00141   if (rcode != DNS_SRV_OK || response.head.ancount == 0)
00142      goto no_name;
00143
00144   resp_end   = (const BYTE*)&response + len;
00145   name_end   = name + size;
00146   compressed = FALSE;
00147
00148   /* Skip question */
00149   c = response.body;
00150   while (*c && c < resp_end)
00151         c++;
00152
00153   c += 5;          /* skip QNAME, QTYPE and QCLASS */
00154   if (c >= resp_end)
00155      goto fail;
00156
00157   /* Skip name */
00158   while (*c && c < resp_end)
00159   {
00160     if (*c >= 0xC0)  /* compressed result */
00161     {
00162       c += 2;
00163       compressed = TRUE;
00164       break;
00165     }
00166     c++;
00167   }
00168   if (!compressed)
00169      c++;
00170
00171   if (c + RESOURCE_HEAD_SIZE >= resp_end)
00172      goto fail;
00173
00174   rr = (const struct DNS_resource*) c;
00175
00176   if (rr->rtype != intel16(DTYPE_PTR))
00177      goto fail;
00178
00179   c = rr->rdata;
00180   dom_ttl = intel (rr->ttl);
00181
00182   while (*c && c < resp_end)  /* will truncate name if c >= resp_end */
00183   {
00184     len = *c;
00185     if (len >= 0xC0)
00186     {
00187       WORD ofs = (len - 0xC0) + c[1];
00188       c = response.body + ofs;
00189       len = *c;
00190     }
00191     if (name + len >= name_end-1)
00192        break;
00193     strncpy (name, (const char*)(c+1), len);
00194     name += len;
00195     c += len + 1;
00196     if (*c)
00197        *name++ = '.';
00198   }
00199   *name = '\0';
00200
00201 #if defined(USE_IDNA)
00202   if (dns_do_idna && !IDNA_convert_from_ACE(name,&size))
00203   {
00204     dom_errno = DNS_CLI_ILL_IDNA;
00205     return (FALSE);
00206   }
00207 #endif
00208
00209   dom_errno = DNS_SRV_OK;
00210   return (TRUE);
00211
00212 fail:
00213   dom_errno = DNS_CLI_ILL_RESP;
00214   return (FALSE);
00215
00216 no_name:
00217   dom_errno = rcode;
00218   return (FALSE);
00219 }
00220
00225 static BOOL reverse_lookup (const struct DNS_query *q, size_t qlen,
00226                             char *name, size_t size, DWORD nameserver)
00227 {
00228   BOOL        ret;
00229   BOOL        ready = FALSE;
00230   BOOL        quit  = FALSE;
00231   unsigned    sec;
00232   DWORD       timer;
00233   _udp_Socket dom_sock;
00234   sock_type  *sock = NULL;
00235
00236   if (!nameserver)      /* no nameserver, give up */
00237   {
00238     dom_errno = DNS_CLI_NOSERV;
00239     outsnl (dom_strerror(dom_errno));
00240     return (FALSE);
00241   }
00242
00243   if (!udp_open(&dom_sock, DOM_SRC_PORT, nameserver, DOM_DST_PORT, NULL))
00244   {
00245     dom_errno = DNS_CLI_SYSTEM;
00246     return (FALSE);
00247   }
00248
00249   timer = set_timeout (1000 * dns_timeout);
00250
00251   for (sec = 2; sec < dns_timeout-1 && !quit && !_resolve_exit; sec *= 2)
00252   {
00253     sock = (sock_type*)&dom_sock;
00254     sock_write (sock, (const BYTE*)q, qlen);
00255     ip_timer_init (sock, sec);
00256
00257     do
00258     {
00259       tcp_tick (sock);
00260
00261       if (_watt_cbroke || (_resolve_hook && (*_resolve_hook)() == 0))
00262       {
00263         _resolve_exit = 1;       /* terminate do_rresolve() */
00264         dom_errno = DNS_CLI_USERQUIT;
00265         quit  = TRUE;
00266         ready = FALSE;
00267         break;
00268       }
00269       if (sock_dataready(sock))
00270       {
00271         quit  = TRUE;
00272         ready = TRUE;
00273       }
00274       if (ip_timer_expired(sock) || chk_timeout(timer))
00275       {
00276         dom_errno = DNS_CLI_TIMEOUT;
00277         ready = FALSE;
00278         _resolve_timeout = 1;
00279         break;  /* retry */
00280       }
00281       if (sock->udp.usr_yield)
00282            (*sock->udp.usr_yield)();
00283       else WATT_YIELD();
00284     }
00285     while (!quit);
00286   }
00287
00288   if (ready && sock)
00289        ret = read_response (sock, name, size);
00290   else ret = FALSE;
00291
00292   if (sock)  /* if we ran the above for-loop */
00293      sock_close (sock);
00294   return (ret);
00295 }
00296
00301 int reverse_lookup_myip (void)
00302 {
00303   char name [MAX_HOSTLEN];
00304
00305   if (!reverse_resolve_ip4(htonl(my_ip_addr),name,sizeof(name)))
00306      return (0);
00307
00308   if (debug_on >= 1)
00309   {
00310     outs (_LANG("My FQDN: "));
00311     outsnl (name);
00312   }
00313   if (sethostname(name,sizeof(name)) < 0)
00314      return (0);
00315   return (1);
00316 }
00317
00318 /*------------------------------------------------------------------*/
00319
00320 static int do_rresolve (const struct DNS_query *q, size_t qlen,
00321                         char *result, size_t size)
00322 {
00323   WORD brk_mode;
00324   int  i;
00325
00326   if (dns_timeout == 0)
00327       dns_timeout = (UINT)sock_delay << 2;
00328
00329   NEW_BREAK_MODE (brk_mode, 1);
00330
00331   _resolve_exit = _resolve_timeout = 0;
00332
00333   *result = '\0';
00334   dom_cname[0] = '\0';
00335
00336   for (i = 0; i < last_nameserver; ++i)
00337       if (reverse_lookup(q,qlen,result,size,def_nameservers[i]) ||
00338           _resolve_exit)
00339          break;
00340
00341   OLD_BREAK_MODE (brk_mode);
00342   return (*result != '\0');
00343 }
00344
00345 /*------------------------------------------------------------------*/
00346
00347 int reverse_resolve_ip4 (DWORD ip, char *result, size_t size)
00348 {
00349   struct DNS_query q;
00350   size_t len = query_init_ip4 (&q, ip);
00351
00352   memset (&dom_a4list, 0, sizeof(dom_a4list));
00353
00354 #if defined(WIN32) && defined(HAVE_WINDNS_H)
00355   if (WinDnsQuery_PTR4(ip, result, size))
00356      return (1);
00357 #endif
00358   return do_rresolve (&q, len, result, size);
00359 }
00360
00361 #if defined(USE_IPV6)
00362
00363 #define USE_IP6_BITSTRING 0     /* RFC-2673 */
00364
00370 static size_t query_init_ip6 (struct DNS_query *q, const void *addr)
00371 {
00372   const BYTE *ip = (const BYTE*) addr;
00373   char *c;
00374   int   i;
00375
00376   q->head.ident   = (WORD) set_timeout (0UL);  /* Random ID */
00377   q->head.flags   = intel16 (DRD);             /* Query, Recursion desired */
00378   q->head.qdcount = intel16 (1);               /* 1 query */
00379   q->head.ancount = 0;
00380   q->head.nscount = 0;
00381   q->head.arcount = 0;
00382
00383   c = (char*) &q->body[0];
00384
00385 #if USE_IP6_BITSTRING
00386   strcpy (c, "\3\\[x");
00387   c += 4;
00388   for (i = 0; i < SIZEOF(ip6_address); i++)
00389   {
00390     int hi = ip[i] >> 4;
00391     int lo = ip[i] & 15;
00392
00393     if (i == SIZEOF(ip6_address) - 1)
00394          *c++ = 5;
00395     else *c++ = 4;
00396     *c++ = hex_chars_lower [hi];
00397     *c++ = hex_chars_lower [lo];
00398   }
00399   strcpy (c, "]\3ip6\4arpa");
00400   c += 11;
00401
00402 #else
00403   for (i = sizeof(ip6_address)-1; i >= 0; i--)
00404   {
00405     int hi = ip[i] >> 4;
00406     int lo = ip[i] & 15;
00407
00408     *c++ = 2;
00409     *c++ = hex_chars_lower [hi];
00410     *c++ = hex_chars_lower [lo];
00411   }
00412   strcpy (c, "\3ip6\4arpa");
00413   c += 10;
00414 #endif
00415
00416   *(WORD*) c = intel16 (DTYPE_PTR);
00417   c += sizeof(WORD);
00418   *(WORD*) c = intel16 (DIN);
00419   c += sizeof(WORD);
00420
00421   return (c - (char*)q);
00422 }
00423
00424 int reverse_resolve_ip6 (const void *addr, char *result, size_t size)
00425 {
00426   struct DNS_query q;
00427   size_t len = query_init_ip6 (&q, addr);
00428
00429   memset (&dom_a6list, 0, sizeof(dom_a6list));
00430 #if defined(WIN32) && defined(HAVE_WINDNS_H)
00431   if (WinDnsQuery_PTR6(addr, result, size))
00432      return (1);
00433 #endif
00434   return do_rresolve (&q, len, result, size);
00435 }
00436 #endif   /* USE_IPV6 */
00437
Generated on Wed Jan 25 15:42:40 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/UFORTIFY.H Source File

SRC/UFORTIFY.H

Go to the documentation of this file.
00001
00009 #define FORTIFY_STORAGE              /* storage for public functions */
00010
00011 #define FORTIFY_ALIGNMENT        sizeof(double) /* Byte alignment of all memory blocks */
00012
00013 #define FORTIFY_BEFORE_SIZE      32  /* Bytes to allocate before block */
00014 #define FORTIFY_BEFORE_VALUE   0xA3  /* Fill value before block */
00015
00016 #define FORTIFY_AFTER_SIZE       32  /* Bytes to allocate after block */
00017 #define FORTIFY_AFTER_VALUE    0xA5  /* Fill value after block */
00018
00019 #define FORTIFY_FILL_ON_ALLOCATE               /* Nuke out malloc'd memory */
00020 #define FORTIFY_FILL_ON_ALLOCATE_VALUE   0xA7  /* Value to initialize with */
00021
00022 #define FORTIFY_FILL_ON_DEALLOCATE             /* free'd memory is cleared */
00023 #define FORTIFY_FILL_ON_DEALLOCATE_VALUE 0xA9  /* Value to de-initialize with */
00024
00025 #define FORTIFY_FILL_ON_CORRUPTION             /* Nuke out corrupted memory */
00026
00027 #define FORTIFY_CHECK_ALL_MEMORY_ON_ALLOCATE
00028 #define FORTIFY_CHECK_ALL_MEMORY_ON_DEALLOCATE
00029 #define FORTIFY_PARANOID_DEALLOCATE
00030
00031 #define FORTIFY_WARN_ON_ZERO_MALLOC  /* A debug is issued on a malloc(0) */
00032 #define FORTIFY_FAIL_ON_ZERO_MALLOC  /* A malloc(0) will fail */
00033
00034 #define FORTIFY_WARN_ON_ALLOCATE_FAIL    /* A debug is issued on a failed alloc */
00035 #define FORTIFY_WARN_ON_FALSE_FAIL       /* See Fortify_SetAllocateFailRate */
00036 #define FORTIFY_WARN_ON_SIZE_T_OVERFLOW  /* Watch for breaking the 64K limit in */
00037                                          /* some braindead architectures... */
00038
00039 #define FORTIFY_TRACK_DEALLOCATED_MEMORY
00040
00041 #define FORTIFY_DEALLOCATED_MEMORY_LIMIT 1048576 /* Maximum amount of deallocated bytes to keep */
00042 #define FORTIFY_VERBOSE_WARN_WHEN_DISCARDING_DEALLOCATED_MEMORY
00043
00044 #define FORTIFY_STRDUP                   /* if you use non-ANSI strdup() */
00045 #define FORTIFY_GLOBAL_REPLACE           /* Replace GlobalAlloc*() on Win32 */
00046
00047 #ifdef __HIGHC__
00048   #define FORTIFY_LOCK()   /* Fortify_LockLocalData(1) */
00049   #define FORTIFY_UNLOCK() /* Fortify_LockLocalData(0) */
00050 #else
00051   #define FORTIFY_LOCK()
00052   #define FORTIFY_UNLOCK()
00053 #endif
00054
00055 #define FORTIFY_DELETE_STACK_SIZE    256
00056
00057 #ifdef __cplusplus                /* C++ only options go here */
00058
00059 /*  #define FORTIFY_PROVIDE_ARRAY_NEW     */
00060 /*  #define FORTIFY_PROVIDE_ARRAY_DELETE  */
00061
00062 /*  #define FORTIFY_AUTOMATIC_LOG_FILE */
00063     #define FORTIFY_LOG_FILENAME            "fortify.log"
00064     #include <iostream>
00065     #define FORTIFY_FIRST_ERROR_FUNCTION    cout << "\a\a\aFortify Hit Generated!\n"
00066
00067 #endif /* __cplusplus */
Generated on Wed Jan 25 15:42:40 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/VERSION.C Source File

SRC/VERSION.C

Go to the documentation of this file.
00001
00005 #include <stdio.h>
00006 #include <string.h>
00007
00008 #include "wattcp.h"
00009 #include "wdpmi.h"
00010 #include "misc.h"
00011
00012 #undef init_misc
00013 #undef Random
00014
00015 #include <tcp.h>  /* WATTCP_MAJOR_VER, WATTCP_MINOR_VER */
00016
00017 #if defined(WIN32)
00018   #if defined(_DEBUG)
00019     #define DBG_RELEASE  "debug"   /* Only with MSVC */
00020   #else
00021     #define DBG_RELEASE  "release"
00022   #endif
00023   #undef  VARIANT
00024   #define VARIANT   " Win32"
00025
00026 #elif defined(_WIN64)
00027   #if defined(_DEBUG)
00028     #define DBG_RELEASE  "debug"
00029   #else
00030     #define DBG_RELEASE  "release"
00031   #endif
00032   #undef  VARIANT
00033   #define VARIANT   " Win64"
00034
00035 #elif defined(WATT32_DOS_DLL)     /* not yet */
00036   #ifdef __DJGPP__
00037     #define VARIANT  " DXE"
00038   #else
00039     #define VARIANT  " DLL"
00040   #endif
00041
00042 #else
00043   #define VARIANT   ""
00044 #endif
00045
00046 const char *wattcpCopyright = "See COPYRIGHT.H for details";
00047
00048 #if defined(MAKE_TSR)
00049 const char *wattcpVersion (void)
00050 {
00051   static char buf[15];
00052   char  *p = buf + 8;
00053
00054   strcat (buf, "Watt-32 ");
00055   *p++ = '0' + WATTCP_MAJOR_VER;
00056   *p++ = '.';
00057   *p++ = '0' + WATTCP_MINOR_VER;
00058   *p = '\0';
00059   return (buf);
00060 }
00061
00062 #else
00063 const char *wattcpVersion (void)
00064 {
00065   static char buf[80];
00066   char  *p = buf;
00067
00068 #if defined(WATTCP_DEVEL_REL) && (WATTCP_DEVEL_REL > 0)
00069   p += sprintf (p, "Watt-32 (%d.%d.%d",
00070                 WATTCP_MAJOR_VER, WATTCP_MINOR_VER, WATTCP_DEVEL_REL);
00071 #else
00072   p += sprintf (p, "Watt-32 (%d.%d",
00073                 WATTCP_MAJOR_VER, WATTCP_MINOR_VER);
00074 #endif
00075
00076   p += sprintf (p, "%s), ", VARIANT);
00077
00078 #if defined(__GNUC__)
00079   p += sprintf (p, "GNU-C %d.%d", __GNUC__, __GNUC_MINOR__);
00080
00081   #if defined(__GNUC_PATCHLEVEL__) && (__GNUC_PATCHLEVEL__ > 0)
00082     p += sprintf (p, ".%d", __GNUC_PATCHLEVEL__);
00083   #endif
00084
00085   /* The `__tune_xx' defines were introduced in gcc 2.95.1 (?)
00086    */
00087   #if defined (__tune_i386__)         /* -mcpu=i386 */
00088     strcpy (p, " (386), ");
00089   #elif defined (__tune_i486__)       /* -mcpu=i486 */
00090     strcpy (p, " (486), ");
00091   #elif defined (__tune_pentium__)    /* -mcpu=pentium */
00092     strcpy (p, " (Pent), ");
00093   #elif defined (__tune_pentiumpro__) /* -mcpu=pentiumpro */
00094     strcpy (p, " (PentPro), ");
00095   #else
00096     strcpy (p, ", ");
00097   #endif
00098
00099 #elif defined(__HIGHC__)
00100   strcpy (p, "Metaware High-C, ");   /* no way to get version */
00101
00102 #elif defined(__POCC__)
00103   p += sprintf (p, "PellesC %d.%d, ", __POCC__/100, __POCC__ % 100);
00104
00105 #elif defined(__WATCOMC__)
00106   #if (__WATCOMC__ >= 1200)
00107     p += sprintf (p, "OpenWatcom %d.%d",
00108                   (__WATCOMC__/100) - 11, (__WATCOMC__ % 100) / 10);
00109   #else
00110     p += sprintf (p, "Watcom C %d.%d", __WATCOMC__/100, __WATCOMC__ % 100);
00111   #endif
00112
00113   #if defined(__SMALL__)
00114     strcpy (p, " (small model), ");
00115   #elif defined(__LARGE__)
00116     strcpy (p, " (large model), ");
00117   #else
00118     #if (_M_IX86 >= 600)              /* -6r/s */
00119       strcpy (p, " (686");
00120     #elif (_M_IX86 >= 500)            /* -5r/s */
00121       strcpy (p, " (586");
00122     #elif (_M_IX86 >= 400)            /* -4r/s */
00123       strcpy (p, " (486");
00124     #else                             /* -3r/s */
00125       strcpy (p, " (386");
00126     #endif
00127
00128     p += 5;
00129
00130     #if defined(__SW_3S)              /* -3/4/5/6s */
00131       strcpy (p, "S), ");
00132     #else
00133       strcpy (p, "R), ");    /* Register based calls is default */
00134     #endif
00135  #endif
00136
00137 #elif defined(__BORLANDC__)
00138   p += sprintf (p, "Borland C %X.%X", __BORLANDC__ >> 8, __BORLANDC__ & 0xFF);
00139
00140   #if defined(__SMALL__)
00141     strcpy (p, " (small model), ");
00142   #elif defined(__LARGE__)
00143     strcpy (p, " (large model), ");
00144   #else
00145     strcpy (p, ", ");
00146   #endif
00147
00148 #elif defined(__TURBOC__)
00149   p += sprintf (p, "Turbo C %X.%X", (__TURBOC__ >> 8) - 1, __TURBOC__ & 0xFF);
00150
00151   #if defined(__SMALL__)
00152     strcpy (p, " (small model), ");
00153   #elif defined(__LARGE__)
00154     strcpy (p, " (large model), ");
00155   #else
00156     strcpy (p, ", ");
00157   #endif
00158
00159 #elif defined(_MSC_VER)
00160   #if (_MSC_VER == 1300)
00161     p += sprintf (p, "Microsoft Visual Studio .NET (%s), ", DBG_RELEASE);
00162   #elif (_MSC_VER == 1310)
00163     p += sprintf (p, "Microsoft Visual Studio .NET 2003 (%s), ", DBG_RELEASE);
00164   #elif (_MSC_VER == 1400)
00165     p += sprintf (p, "Microsoft Visual Studio .NET 2005 (%s), ", DBG_RELEASE);
00166   #elif (_MSC_VER >= 1000)     /* Visual-C 4+ */
00167     p += sprintf (p, "Microsoft Visual-C %d.%d (%s), ",
00168                   (_MSC_VER / 100) - 6, _MSC_VER % 100, DBG_RELEASE);
00169   #else
00170     p += sprintf (p, "Microsoft Quick-C %d.%d",
00171                   _MSC_VER / 100, _MSC_VER % 100);
00172
00173     #if defined(__SMALL__)
00174       strcpy (p, " (small model), ");
00175     #elif defined(__LARGE__)
00176       strcpy (p, " (large model), ");
00177     #else
00178       strcpy (p, ", ");
00179     #endif
00180   #endif
00181
00182 #elif defined(__DMC__)
00183   p += sprintf (p, "Digital Mars C %X.%X", __DMC__ >> 8, __DMC__ & 0xFF);
00184
00185   #if defined(DOS386)
00186     strcpy (p, " (32-bit), ");
00187   #elif defined(__SMALL__)
00188     strcpy (p, " (small model), ");
00189   #elif defined(__LARGE__)
00190     strcpy (p, " (large model), ");
00191   #else
00192     strcpy (p, ", ");
00193   #endif
00194
00195 #elif defined(__CCDL__)
00196   p += sprintf (p, "LadSoft C %d.%d, ", __CCDL__/100, __CCDL__ % 100);
00197
00198 #elif defined(__LCC__) && defined(WIN32)
00199   p += sprintf (p, "lcc-win32, ");
00200
00201 #elif defined(__ICC__)
00202   p += sprintf (p, "Intel C %d.%d, ", __ICC__/100, __ICC__ % 100);
00203 #endif
00204
00205   p = strchr (buf, '\0');
00206
00207 #if defined(__MINGW32__)
00208   sprintf (p, "MingW %d.%d, ", __MINGW32_MAJOR_VERSION, __MINGW32_MINOR_VERSION);
00209
00210 #elif defined(__CYGWIN__)   /* !! not tested */
00211   sprintf (p, "CygWin %d.%d, ", __CYGWIN_MAJOR_VERSION, __CYGWIN_MINOR_VERSION);
00212
00213 #elif (DOSX == DJGPP)
00214   sprintf (p, "djgpp %d.%02d, ", __DJGPP__, __DJGPP_MINOR__);
00215
00216 #elif (DOSX == DOS4GW)
00217   {
00218     const char *extender = dos_extender_name();
00219     sprintf (p, "%s, ", extender ? extender : "unknown");
00220   }
00221
00222 #elif (DOSX == PHARLAP)
00223   sprintf (p, "Pharlap, ");
00224
00225 #elif (DOSX == X32VM)
00226   strcpy (p, "X32VM, ");
00227
00228 #elif (DOSX == POWERPAK)
00229   strcpy (p, "PowerPak, ");
00230 #endif
00231
00232   strcat (p, __DATE__);
00233   return (buf);
00234 }
00235 #endif   /* MAKE_TSR */
00236
00237
00241 static const char *capa[] = {
00242 #if defined(MAKE_TSR)
00243            "TSR",
00244 #endif
00245 #if defined(USE_DEBUG)
00246            "debug",
00247 #endif
00248 #if defined(USE_MULTICAST)
00249            "mcast",
00250 #endif
00251 #if defined(USE_BIND)
00252            "bind",
00253 #endif
00254 #if defined(USE_BSD_API)
00255            "BSDsock",
00256 #endif
00257 #if defined(USE_BSD_FATAL)
00258            "BSDfatal",
00259 #endif
00260 #if defined(USE_BOOTP)
00261            "bootp",
00262 #endif
00263 #if defined(USE_DHCP)
00264            "dhcp",
00265 #endif
00266 #if defined(USE_RARP)
00267            "rarp",
00268 #endif
00269 #if defined(USE_LANGUAGE)
00270            "lang",
00271 #endif
00272 #if defined(USE_FRAGMENTS)
00273            "frag",
00274 #endif
00275 #if defined(USE_STATISTICS)
00276            "stat",
00277 #endif
00278 #if defined(USE_FORTIFY)
00279            "fortify",
00280 #endif
00281 #if defined(USE_CRTDBG)
00282            "crt-dbg",
00283 #endif
00284 #if defined(USE_FSEXT)
00285            "fsext",
00286 #endif
00287 #if defined(USE_LOOPBACK)
00288            "loopback",
00289 #endif
00290 #if defined(USE_EMBEDDED)
00291            "embedded",
00292 #endif
00293 #if defined(USE_TFTP)
00294            "tftp",
00295 #endif
00296 #if defined(USE_TCP_SACK)
00297            "sack",
00298 #endif
00299 #if defined(USE_MTU_DISC)
00300            "MTU-disc",
00301 #endif
00302 #if defined(USE_UDP_ONLY)
00303            "udp-only",
00304 #endif
00305 #if defined(USE_ECHO_DISC)
00306            "echo",
00307 #endif
00308 #if defined(USE_PPPOE)
00309            "PPPoE",
00310 #endif
00311 #if defined(USE_IPV6)
00312            "IPv6",
00313 #endif
00314 #if defined(USE_RS232_DBG)
00315            "RS232",
00316 #endif
00317 #if defined(USE_DEAD_GWD)
00318            "dead-gw",
00319 #endif
00320 #if defined(USE_GZIP_COMPR)
00321            "gzip-compr",
00322 #endif
00323 #if defined(USE_SECURE_ARP)
00324            "sec-ARP",
00325 #endif
00326 #if defined(USE_TCP_MD5)
00327            "TCP-MD5",
00328 #endif
00329 #if defined(USE_DYNIP_CLI)
00330            "DynIP",
00331 #endif
00332 #if defined(USE_PROFILER)
00333            "profiler",
00334 #endif
00335 #if defined(USE_FAST_PKT)
00336            "fast-pkt",
00337 #endif
00338            NULL
00339          };
00340
00341 const char *wattcpCapabilities (void)
00342 {
00343   static char buf[240];
00344   char  *p = buf;
00345   int    i;
00346
00347   for (i = 0; capa[i]; i++)
00348   {
00349     *p++ = '/';
00350     if (p + strlen(capa[i]) - 2 >= buf + sizeof(buf))
00351     {
00352       *p++ = '.';
00353       *p++ = '.';
00354       break;
00355     }
00356     strcpy (p, capa[i]);
00357     p += strlen (capa[i]);
00358   }
00359   *p = '\0';
00360   return (buf);
00361 }
00362
00363 /*
00364  * Check some prototypes and decorations in <tcp.h> against the
00365  * local prototypes.
00366  */
00367 #undef init_misc
00368 #undef set_timeout
00369 #undef chk_timeout
00370 #undef hires_timer
00371 #undef set_timediff
00372 #undef get_timediff
00373 #undef timeval_diff
00374 #undef init_timer_isr
00375 #undef exit_timer_isr
00376 #undef has_rdtsc
00377 #undef clocks_per_usec
00378 #undef Random
00379
00380 #undef my_ip_addr
00381 #undef sin_mask
00382 #undef block_ip
00383 #undef block_tcp
00384 #undef block_udp
00385 #undef block_icmp
00386 #undef aton
00387 #undef isaddr
00388 #undef ctrace_on
00389 #undef _mss
00390 #undef _mtu
00391 #undef _inet_ntoa
00392 #undef _inet_addr
00393 #undef _printf
00394 #undef _outch
00395 #undef outs
00396 #undef outsnl
00397 #undef outsn
00398 #undef outhexes
00399 #undef outhex
00400 #undef rip
00401 #undef survive_eth
00402 #undef survive_bootp
00403 #undef survive_dhcp
00404 #undef survive_rarp
00405 #undef sock_inactive
00406 #undef sock_data_timeout
00407 #undef sock_delay
00408 #undef multihomes
00409 #undef usr_init
00410 #undef usr_post_init
00411 #undef cookies
00412 #undef last_cookie
00413 #undef loopback_handler
00414 #undef in_checksum
00415 #undef parse_config_table
00416
00417 /* hide some prototypes from <tcp.h>
00418  */
00419 #define udp_SetTTL  foo_udp_SetTTL
00420
00421 #include "socket.h"
Generated on Wed Jan 25 15:42:40 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/WATTCP.C Source File

SRC/WATTCP.C

Go to the documentation of this file.
00001
00004 #ifdef __HIGHC__
00005
00006 #if __HIGHC__ <= 0x0331
00007 #include <language.cf>
00008 #endif
00009
00010 #include "wattcp.h"
00011 #include "strings.h"
00012
00013 #pragma Calling_convention(PASCAL)
00014 #define DLL_PROCESS_DETACH 0
00015 #define DLL_PROCESS_ATTACH 1
00016
00017 /*
00018  * For imported data, we redefine the imported name with the
00019  * -import switch when linking, and then use a macro to dereference
00020  * the imported name to get to the real variable.
00021  */
00022
00023 #define IMP_PREFIX(name)  __imp_##name
00024 #define IMPVAR(name,type) (***(type ***)((BYTE*)(&IMP_PREFIX(name))+2))
00025
00026 DWORD DllEntryPoint (void *hDll, DWORD reason, void *reserved)
00027 {
00028 #if defined(USE_DEBUG)
00029   if (reason == DLL_PROCESS_ATTACH)
00030      outs ("WATTCP.DLL: Process attach\n"); /* cannot use _LANG() here */
00031 #endif
00032   ARGSUSED (hDll);
00033   ARGSUSED (reserved);
00034   return (1);
00035 }
00036
00037 #endif   /* __HIGHC__ */
Generated on Wed Jan 25 15:42:40 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/WATTCP.H Source File

SRC/WATTCP.H

Go to the documentation of this file.
00001 #ifndef _w32_WATTCP_H
00002 #define _w32_WATTCP_H
00003
00007 #if defined(WIN32) || defined(_WIN32)
00008   #undef WIN32
00009   #undef _WIN32
00010   #define WIN32  1
00011   #define _WIN32 1
00012
00013   /*
00014    * This must come before "target.h".
00015    * Prevent including <winsock*.h>.
00016    */
00017   #ifndef WIN32_LEAN_AND_MEAN
00018   #define WIN32_LEAN_AND_MEAN
00019   #endif
00020
00021   /* Required by bsdname.c + winpcap.c
00022    */
00023   #if !defined(_WIN32_WINNT) || (_WIN32_WINNT < 0x0500)
00024   #undef _WIN32_WINNT
00025   #define _WIN32_WINNT 0x0500
00026   #endif
00027
00028   #include <windows.h>
00029
00030   /*
00031    * Wattcp basic types.
00032    */
00033 #else
00034   typedef unsigned char   BYTE;
00035   typedef unsigned short  WORD;
00036   typedef unsigned long   DWORD;
00037   typedef unsigned int    UINT;
00038 #endif
00039
00040 #ifndef WATT32_BUILD
00041 #define WATT32_BUILD
00042 #endif
00043
00044 typedef BYTE  eth_address[6];
00045 typedef BYTE  tok_address[6];
00046 typedef BYTE  fddi_address[6];
00047 typedef BYTE  ax25_address[7];
00048 typedef BYTE  arcnet_address;
00049 typedef BYTE  ip6_address[16];
00051 #define mac_address eth_address  /* !!fix-me: breaks AX25 drivers */
00052
00055 typedef int (*ProtoHandler) (void *sock, const void *data, unsigned len,
00056                                    const void *tcp_pseudo_hdr, const void *udp_hdr);
00057
00060 typedef int (*UserHandler) (void *sock);
00061
00064 typedef int (*icmp_upcall) (void *socket, BYTE icmp_type, BYTE icmp_code);
00065
00068 #if defined(__HIGHC__) || defined(__GNUC__) || defined(__CCDL__) || \
00069     defined(__LCC__)   || defined(__POCC__)
00070   typedef unsigned long long  uint64;
00071   typedef long long           int64;
00072   #define HAVE_UINT64
00074 #elif defined(__DMC__) && (__INTSIZE == 4)
00075   typedef unsigned long long  uint64;
00076   typedef long long           int64;
00077   #define HAVE_UINT64
00078
00079 #elif defined(__WATCOMC__) && defined(__WATCOM_INT64__) && !(defined(__SMALL__) || defined(__LARGE__))
00080   typedef unsigned __int64 uint64;
00081   typedef __int64          int64;
00082   #define HAVE_UINT64
00083
00084 #elif defined(_MSC_VER) && (_MSC_VER >= 900)
00085   typedef unsigned __int64 uint64;
00086   typedef __int64          int64;
00087   #define HAVE_UINT64
00088
00089 #elif defined(__BORLANDC__) && defined(WIN32)
00090   typedef unsigned __int64 uint64;
00091   typedef __int64          int64;
00092   #define HAVE_UINT64
00093 #endif
00094
00095 struct ulong_long {
00096        DWORD lo;
00097        DWORD hi;
00098       };
00099
00100
00107 #define NAMESPACE(x)  _w32_ ## x
00108
00109 #define STATIC        /* ease disassembly */
00110
00111 #define loBYTE(w)     (BYTE)(w)
00112 #define hiBYTE(w)     (BYTE)((WORD)(w) >> 8)
00113 #define DIM(x)        (int) (sizeof(x) / sizeof((x)[0]))
00114 #define SIZEOF(x)     (int) sizeof(x)
00115
00116 #ifdef __LCC__
00117   #define ARGSUSED(foo)  foo = foo
00118   #define ATOI(x)        atoi ((char*)(x))
00119   #define ATOL(x)        atol ((char*)(x))
00120 #else
00121   #define ARGSUSED(foo)  (void)foo
00122   #define ATOI(x)        atoi (x)
00123   #define ATOL(x)        atol (x)
00124 #endif
00125
00129 #include "target.h"
00130 #include "config.h"
00132 #include <sys/w32api.h>
00133 #include <sys/werrno.h>
00135 #if defined(USE_CRTDBG)
00136   #define _CRTDBG_MAP_ALLOC
00137   #include <crtdbg.h>
00138
00139 #elif defined(USE_FORTIFY)
00140   #include "fortify.h"
00141 #endif
00142
00143 #if defined(WATT32_DOS_DLL) && defined(__DJGPP__)
00144 #include "dxe_sym.h"
00145 #endif
00146
00147 #if defined(MAKE_TSR)
00148 #undef HAVE_UINT64
00149 #endif
00150
00151 #ifndef FALSE
00152 #define FALSE  0
00153 #endif
00154
00155 #ifndef TRUE
00156 #define TRUE   (!FALSE)
00157 #endif
00158
00159
00163 #define ETH_MAX_DATA     1500
00164 #define ETH_MIN          60
00165 #define ETH_MAX          (ETH_MAX_DATA + sizeof(eth_Header))
00166
00167 #define TOK_MAX_DATA     ETH_MAX_DATA  /* could be much larger */
00168 #define TOK_MIN          sizeof(tok_Header)
00169 #define TOK_MAX          (TOK_MAX_DATA + sizeof(tok_Header))
00170
00171 #define FDDI_MAX_DATA    ETH_MAX_DATA  /* really is 4470 */
00172 #define FDDI_MIN         (3 + sizeof(fddi_Header))
00173 #define FDDI_MAX         (FDDI_MAX_DATA + sizeof(fddi_Header))
00174
00175 #define ARCNET_MAX_DATA  512    /* Long frame or Exception frame */
00176 #define ARCNET_MIN       257
00177 #define ARCNET_MAX       (ARCNET_MAX_DATA + sizeof(arcnet_Header))
00178
00179 #define AX25_MAX_DATA    ETH_MAX_DATA
00180 #define AX25_MIN         sizeof(ax25_Header)
00181 #define AX25_MAX         (AX25_MAX_DATA + sizeof(ax25_Header))
00182
00183 #define PPPOE_MAX_DATA   (ETH_MAX_DATA - 8)
00184 #define PPPOE_MIN        sizeof(pppoe_Header)
00185 #define PPPOE_MAX        (PPPOE_MAX_DATA + sizeof(pppoe_Header))
00186
00187 #define VLAN_MAX_DATA    (ETH_MAX_DATA - 4)
00188 #define VLAN_MAX         (VLAN_MAX_DATA + sizeof(vlan_Header))
00189 #define VLAN_MIN         sizeof(vlan_Header)
00190
00191 #define TCP_OVERHEAD     (sizeof(in_Header) + sizeof(tcp_Header))
00192 #define UDP_OVERHEAD     (sizeof(in_Header) + sizeof(udp_Header))
00193
00194
00198 #define IP4_TYPE         0x0008
00199 #define IP6_TYPE         0xDD86
00200 #define IEEE802_1Q_TYPE  0x0081
00201 #define ARP_TYPE         0x0608
00202 #define RARP_TYPE        0x3580
00203 #define PPPOE_DISC_TYPE  0x6388
00204 #define PPPOE_SESS_TYPE  0x6488
00205
00209 #define ARCNET_DP_BOOT    0
00210 #define ARCNET_DP_MOUNT   1
00211 #define ARCNET_PL_BEACON  8
00212 #define ARCNET_PL_BEACON2 243
00213
00214 #define ARCNET_DIAG       128
00215 #define ARCNET_IP6        196
00216 #define ARCNET_BACNET     205
00217 #define ARCNET_IP_1201    212
00218 #define ARCNET_ARP_1201   213
00219 #define ARCNET_RARP_1201  214
00220 #define ARCNET_ATALK      221
00221 #define ARCNET_ETHER      232
00222 #define ARCNET_NOVELL     236
00223 #define ARCNET_IP_1051    240
00224 #define ARCNET_ARP_1051   241
00225 #define ARCNET_BANYAN     247
00226 #define ARCNET_IPX        250
00227 #define ARCNET_LANSOFT    251
00228
00229
00230 #if (DOSX)
00231   #define MAX_FRAGMENTS   45UL
00232   #define MAX_WINDOW      (64*1024U)
00233 #else
00234   #define MAX_FRAGMENTS   30UL
00235   #define MAX_WINDOW      (32*1024U)
00236 #endif
00237
00240 #define MAX_IP4_DATA      (ETH_MAX_DATA - sizeof(in_Header))
00241 #define MAX_IP6_DATA      (ETH_MAX_DATA - sizeof(in6_Header))
00242 #define MAX_FRAG_SIZE     (MAX_FRAGMENTS * MAX_IP4_DATA)
00243
00244 #define MAX_NAMELEN       80
00245 #define MAX_VALUELEN      80
00246 #define MAX_PATHLEN       256
00248 #define MAX_COOKIES       10
00249 #define MAX_HOSTLEN       80
00250 #define MAX_ADDRESSES     10
00252 #define SAFETY_TCP        0x538F25A3L
00253 #define SAFETY_UDP        0x3E45E154L
00254
00258 #define UDP_PROTO         17
00259 #define TCP_PROTO         6
00260 #define ICMP_PROTO        1
00261 #define IGMP_PROTO        2
00262 #define IPCOMP_PROTO      108
00263
00267 #define SOCK_MODE_BINARY  0x01
00268 #define SOCK_MODE_UDPCHK  0x02
00269 #define SOCK_MODE_NAGLE   0x04
00270 #define SOCK_MODE_LOCAL   0x08
00271 #define SOCK_MODE_SAWCR   0x10
00272 #define SOCK_MODE_MASK    0x07
00279 #define LF_WINUPDATE    0x00001
00280 #define LF_NOPUSH       0x00002
00281 #define LF_NOOPT        0x00004
00282 #define LF_REUSEADDR    0x00008
00283 #define LF_KEEPALIVE    0x00010
00284 #define LF_LINGER       0x00020
00285 #define LF_NOCLOSE      0x00040
00286 #define LF_NO_IPFRAGS   0x00080
00287 #define LF_OOBINLINE    0x00100
00288 #define LF_SNDTIMEO     0x00200
00289 #define LF_RCVTIMEO     0x00400
00290 #define LF_GOT_FIN      0x00800
00291 #define LF_GOT_PUSH     0x01000
00292 #define LF_GOT_ICMP     0x02000
00293 #define LF_USE_TSTAMP   0x04000
00294 #define LF_RCVD_SCALE   0x08000
00295 #define LF_IS_SERVER    0x10000
00296 #define LF_SACK_PERMIT  0x20000
00297
00302 #define SOCKESTABLISHED  1
00303 #define SOCKDATAREADY    2
00304 #define SOCKCLOSED       4
00305
00306
00307 #include <sys/packon.h>
00313 typedef struct in_Header {
00314 #if defined(USE_BIGENDIAN)
00315         BYTE   ver    : 4;
00316         BYTE   hdrlen : 4;
00317 #elif defined(OLD_TURBOC) || defined(__CCDL__)
00318         int    hdrlen : 4;
00319         int    ver    : 4;
00320 #else
00321         BYTE   hdrlen : 4;     /* Watcom requires BYTE here */
00322         BYTE   ver    : 4;
00323 #endif
00324         BYTE   tos;
00325         WORD   length;
00326         WORD   identification;
00327         WORD   frag_ofs;
00328         BYTE   ttl;
00329         BYTE   proto;
00330         WORD   checksum;
00331         DWORD  source;
00332         DWORD  destination;
00333       } in_Header;
00334
00337 #define IP_CE      0x8000
00338 #define IP_DF      0x4000
00339 #define IP_MF      0x2000
00340 #define IP_OFFMASK 0x1FFF
00344 #define IP_MINCOST     0x02
00345 #define IP_RELIABILITY 0x04
00346 #define IP_THROUGHPUT  0x08
00347 #define IP_LOWDELAY    0x10
00348 #define IP_TOSMASK    (IP_MINCOST|IP_RELIABILITY|IP_THROUGHPUT|IP_LOWDELAY)
00349
00350 #define in_GetHdrLen(ip) ((ip)->hdrlen << 2)
00352 #define IP_BCAST_ADDR    0xFFFFFFFFUL
00353
00358 typedef struct in6_Header {
00359 #if defined(USE_BIGENDIAN)
00360         BYTE        ver : 4;
00361         BYTE        pri : 4;
00362 #else
00363         BYTE        pri : 4;
00364         BYTE        ver : 4;
00365 #endif
00366         BYTE        flow_lbl[3];
00367         WORD        len;
00368         BYTE        next_hdr;
00369         BYTE        hop_limit;
00370         ip6_address source;
00371         ip6_address destination;
00372       } in6_Header;
00373
00378 typedef struct ip_Packet {
00379         in_Header head;
00380         BYTE      data [MAX_IP4_DATA];
00381       } ip_Packet;
00382
00383
00388 typedef struct udp_Header {
00389         WORD   srcPort;
00390         WORD   dstPort;
00391         WORD   length;
00392         WORD   checksum;
00393       } udp_Header;
00394
00395
00400 typedef struct tcp_Header {
00401         WORD   srcPort;
00402         WORD   dstPort;
00403         DWORD  seqnum;
00404         DWORD  acknum;
00405
00406 #if defined(USE_BIGENDIAN)
00407         BYTE   offset : 4;
00408         BYTE   unused : 4;
00409 #elif defined(OLD_TURBOC) || defined(__CCDL__)
00410         int    unused : 4;
00411         int    offset : 4;
00412 #else
00413         BYTE   unused : 4;   /* Watcom requires BYTE here */
00414         BYTE   offset : 4;
00415 #endif
00416         BYTE   flags;
00417         WORD   window;
00418         WORD   checksum;
00419         WORD   urgent;
00420       } tcp_Header;
00421
00425 #define tcp_FlagFIN   0x01
00426 #define tcp_FlagSYN   0x02
00427 #define tcp_FlagRST   0x04
00428 #define tcp_FlagPUSH  0x08
00429 #define tcp_FlagACK   0x10
00430 #define tcp_FlagURG   0x20
00431 #define tcp_FlagECN   0x40    /* ECN-Echo */
00432 #define tcp_FlagCWR   0x80    /* congestion window reduced */
00433 #define tcp_FlagMASK  0x3F    /* ignore ECN/CWR for now */
00434
00439 typedef struct tcp_PseudoHeader {
00440         DWORD  src;
00441         DWORD  dst;
00442         BYTE   mbz;
00443         BYTE   protocol;
00444         WORD   length;
00445         WORD   checksum;
00446       } tcp_PseudoHeader;
00447
00448
00453 typedef struct tcp_PseudoHeader6 {
00454         ip6_address  src;
00455         ip6_address  dst;
00456         WORD         length;
00457         BYTE         zero[3];
00458         BYTE         next_hdr;
00459       } tcp_PseudoHeader6;
00460
00461
00466 typedef struct IGMP_packet {
00467 #if defined(USE_BIGENDIAN)
00468         int    version : 4;
00469         int    type    : 4;
00470 #else
00471         int    type    : 4;
00472         int    version : 4;
00473 #endif
00474         BYTE   mbz;
00475         WORD   checksum;
00476         DWORD  address;
00477       } IGMP_packet;
00478
00479 #define IGMP_VERSION   1
00480 #define IGMPv1_QUERY   1
00481 #define IGMPv1_REPORT  2
00482
00483
00488 typedef struct arp_Header {
00489         WORD        hwType;
00490         WORD        protType;
00491         BYTE        hwAddrLen;
00492         BYTE        protoAddrLen;
00493         WORD        opcode;
00494         eth_address srcEthAddr;
00495         DWORD       srcIPAddr;
00496         eth_address dstEthAddr;
00497         DWORD       dstIPAddr;
00498       } arp_Header;
00499
00500 #include <sys/packoff.h>
00502 #define rarp_Header arp_Header
00503
00507 #define ARP_REQUEST    0x0100
00508 #define ARP_REPLY      0x0200
00509 #define RARP_REQUEST   0x0300
00510 #define RARP_REPLY     0x0400
00511
00512
00520 #define tcp_StateLISTEN   0      /* listening for connection */
00521 #define tcp_StateRESOLVE  1      /* resolving IP, waiting on ARP reply */
00522 #define tcp_StateSYNSENT  2      /* SYN sent, active open */
00523 #define tcp_StateSYNREC   3      /* SYN received, ACK+SYN sent. */
00524 #define tcp_StateESTAB    4      /* established */
00525 #define tcp_StateESTCL    5      /* established, but will FIN */
00526 #define tcp_StateFINWT1   6      /* sent FIN */
00527 #define tcp_StateFINWT2   7      /* sent FIN, received FINACK */
00528 #define tcp_StateCLOSWT   8      /* received FIN waiting for close */
00529 #define tcp_StateCLOSING  9      /* sent FIN, received FIN (waiting for FINACK) */
00530 #define tcp_StateLASTACK  10     /* FIN received, FINACK+FIN sent */
00531 #define tcp_StateTIMEWT   11     /* dally after sending final FINACK */
00532 #define tcp_StateCLOSED   12     /* FIN+ACK received */
00533
00534 #define tcp_MaxBufSize    2048   /* maximum bytes to buffer on input */
00535 #define udp_MaxBufSize    1520
00536 #define tcp_MaxTxBufSize  tcp_MaxBufSize  /* and on tcp output */
00537
00545 #define UDP_TCP_COMMON                                                       \
00546         WORD         ip_type;          /* UDP_PROTO,TCP_PROTO or IPx_TYPE */ \
00547         BYTE         ttl;              /* Time To Live */                    \
00548         BYTE         fill_1;                                                 \
00549         const char  *err_msg;          /* NULL when all is okay */           \
00550         char         err_buf[100];     /* room for error message */          \
00551         void       (*usr_yield)(void); /* yield while waiting */             \
00552         icmp_upcall  icmp_callb;       /* socket-layer callback (icmp) */    \
00553         BYTE         rigid;                                                  \
00554         BYTE         stress;                                                 \
00555         WORD         sockmode;         /* a logical OR of bits */            \
00556         WORD         fill_2;                                                 \
00557         DWORD        usertimer;        /* ip_timer_set, ip_timer_timeout */  \
00558         ProtoHandler protoHandler;     /* called with incoming data */       \
00559         eth_address  his_ethaddr;      /* peer's ethernet address */         \
00560                                                                              \
00561         DWORD        myaddr;           /* my IPv4-address */                 \
00562         DWORD        hisaddr;          /* peer's IPv4 address */             \
00563         WORD         hisport;          /* peer's source port */              \
00564         WORD         myport;           /* my source port */                  \
00565         DWORD        locflags;         /* local option flags */              \
00566         BOOL         is_ip6;           /* TRUE if IPv6 socket */             \
00567         int          rx_datalen;       /* Rx length, must be signed */       \
00568         UINT         max_rx_data;      /* Last index for rx_data[] */        \
00569         BYTE        *rx_data           /* Rx data buffer (default rx_buf[]) */
00570
00575 typedef struct _udp_Socket {
00576         struct _udp_Socket *next;
00577         UDP_TCP_COMMON;
00578         BYTE rx_buf[udp_MaxBufSize+1];
00580 #if defined(USE_IPV6)
00581         ip6_address  my6addr;
00582         ip6_address  his6addr;
00583 #endif
00584         DWORD        safetysig;
00585       } _udp_Socket;
00586
00587
00592 typedef struct _tcp_Socket {
00593         struct _tcp_Socket *next;
00594         UDP_TCP_COMMON;
00595
00596         BYTE rx_buf[tcp_MaxBufSize+1];
00598 #if defined(USE_IPV6)
00599         ip6_address  my6addr;
00600         ip6_address  his6addr;
00601 #endif
00602         UINT         state;
00603         DWORD        recv_next;
00604         DWORD        send_next;
00605         long         send_una;
00607 #if defined(USE_DEBUG)
00608         DWORD        last_acknum[2];
00609         DWORD        last_seqnum[2];
00610 #endif
00611         DWORD        timeout;
00612         BYTE         unhappy;
00613         BYTE         recent;
00614         WORD         flags;
00616         UINT         window;
00617         UINT         adv_win;
00619         BYTE         cwindow;
00620         BYTE         wwindow;
00621         WORD         fill_4;
00622
00623         DWORD        vj_sa;
00624         DWORD        vj_sd;
00625         DWORD        vj_last;
00626         UINT         rto;
00627         BYTE         karn_count;
00628         BYTE         tos;
00629         WORD         fill_5;
00630
00631         DWORD        rtt_time;
00632         DWORD        rtt_lasttran;
00634         DWORD        ts_sent;
00635         DWORD        ts_recent;
00636         DWORD        ts_echo;
00638         UINT         max_seg;
00645         DWORD        missed_seq[2];
00646      /* void        *reasm_buf; */
00648 #if defined(USE_TCP_MD5)
00649         char        *secret;
00650 #endif
00651         DWORD        inactive_to;
00652         DWORD        datatimer;
00653      /* int          sock_delay; ?? */
00654
00655         BYTE         tx_wscale;
00656         BYTE         rx_wscale;
00657         UINT         tx_queuelen;
00658         const BYTE  *tx_queue;
00659
00660         UINT         tx_datalen;
00661         UINT         max_tx_data;
00662         BYTE        *tx_data;
00663         BYTE         tx_buf[tcp_MaxTxBufSize+1];
00664         DWORD        safetysig;
00665         DWORD        safetytcp;
00666       } _tcp_Socket;
00667
00668
00673 typedef struct _raw_Socket {
00674         struct _raw_Socket *next;
00675         WORD   ip_type;
00676         BOOL   used;
00677         DWORD  seq_num;
00678         struct in_Header ip;
00679         BYTE   rx_data [MAX_FRAG_SIZE];
00680       } _raw_Socket;
00681
00686 typedef struct _raw6_Socket {
00687         struct _raw6_Socket *next;
00688         WORD   ip_type;
00689         BOOL   used;
00690         DWORD  seq_num;
00691         struct in6_Header ip6;
00692         BYTE   rx_data [MAX_IP6_DATA];
00693       } _raw6_Socket;
00694
00699 typedef union sock_type {
00700         _udp_Socket  udp;
00701         _tcp_Socket  tcp;
00702         _raw_Socket  raw;
00703         _raw6_Socket raw6;
00704       } sock_type;
00705
00710 typedef struct watt_sockaddr {
00711         WORD   s_type;
00712         WORD   s_port;
00713         DWORD  s_ip;
00714         BYTE   s_spares[6];
00715       } watt_sockaddr;
00716
00717 #endif /* _w32_WATTCP_H */
00718
Generated on Wed Jan 25 15:42:40 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/WDPMI.C Source File

SRC/WDPMI.C

Go to the documentation of this file.
00001
00018 #include <stdio.h>
00019 #include <stdlib.h>
00020 #include <string.h>
00021
00022 #include "wattcp.h"
00023 #include "strings.h"
00024 #include "language.h"
00025 #include "pcsed.h"
00026 #include "printk.h"
00027 #include "sock_ini.h"
00028 #include "cpumodel.h"
00029 #include "misc.h"
00030 #include "wdpmi.h"
00031
00032 #if !defined(WIN32)  /* rest of file */
00033
00034 /* Don't put this in config.h, but define to 1 here when it works.
00035  */
00036 #undef USE_EXCEPT_HANDLER
00037
00038 #if defined(WATCOM386)
00039   /*
00040    * Values for '_Extender'
00041    */
00042   #define DOSX_ERGO     0
00043   #define DOSX_RATIONAL 1  /* DOS4Gxx, WDOSX, Pmode/W, CauseWay, EDOS */
00044   #define DOSX_PHAR_V2  2
00045   #define DOSX_PHAR_V3  3
00046   #define DOSX_PHAR_V4  4
00047   #define DOSX_PHAR_V5  5
00048   #define DOSX_PHAR_V6  6
00049   #define DOSX_PHAR_V7  7
00050   #define DOSX_PHAR_V8  8
00051   #define DOSX_INTEL    9  /* Intel C-Builder */
00052   #define DOSX_WIN386  10  /* Windows 3.11+ */
00053
00054   /*
00055    * Values for '_ExtenderSubtype'
00056    */
00057   #define XS_NONE                  0
00058   #define XS_RATIONAL_ZEROBASE     0
00059   #define XS_RATIONAL_NONZEROBASE  1  /* Only in DOS4G Pro */
00060
00061   extern void cdecl cstart_ (void);
00062   extern char      _Extender;
00063   extern char      _ExtenderSubtype;
00064 #endif
00065
00066 #if defined(DMC386)
00067   #define int386     int86_real
00068   #define int386x    int86x_real
00069   #define AX_REG(r)  r.x.ax
00070   #define BX_REG(r)  r.x.bx
00071   #define CX_REG(r)  r.x.cx
00072   #define DX_REG(r)  r.x.dx
00073   #define EAX_REG(r) r.e.eax
00074   #define EBX_REG(r) r.e.ebx
00075   #define ECX_REG(r) r.e.ecx
00076   #define EDX_REG(r) r.e.edx
00077   #define ESI_REG(r) r.e.esi
00078   #define EDI_REG(r) r.e.edi
00079   #define CARRY(r)   (r.x.cflag & 1)
00080
00081 #else
00082   #define AX_REG(r)  r.w.ax
00083   #define BX_REG(r)  r.w.bx
00084   #define CX_REG(r)  r.w.cx
00085   #define DX_REG(r)  r.w.dx
00086   #define EAX_REG(r) r.x.eax
00087   #define EBX_REG(r) r.x.ebx
00088   #define ECX_REG(r) r.x.ecx
00089   #define EDX_REG(r) r.x.edx
00090   #define ESI_REG(r) r.x.esi
00091   #define EDI_REG(r) r.x.edi
00092   #define CARRY(r)   (r.w.cflag & 1)
00093 #endif
00094
00095 #if (DOSX & (DOS4GW|POWERPAK))
00096
00097 #if defined(__CCDL__)
00098 #define int386 _int386
00099 #endif
00100
00101 WORD __dpmi_errno = 0;        /* last DPMI error */
00102
00103 #if (!(DOSX & POWERPAK))
00104
00105 WORD causeway_ver = 0;        /* major=MSB, minor=LSB */
00106 BOOL dos32a_nullptr_chk = 0;  /* NULL-ptr traps active */
00107
00108 #define DOS32A_SIGN  (('I'<<24) + ('D'<<16) + ('3'<<8) + ('2'<<0))
00109 #define PMODEW_SIGN  (('P'<<24) + ('M'<<16) + ('D'<<8) + ('W'<<0))
00110 #define WDOSX_SIGN   (('W'<<24) + ('D'<<16) + ('S'<<8) + ('X'<<0))
00111
00112 #if (DOSX & DOS4GW) && defined(WATCOM386) && defined(USE_EXCEPT_HANDLER)
00113 static struct FAULT_STRUC exc_struct;
00114 static exceptionHook      user_exc_hook = NULL;
00115
00116 static void far __loadds exception_main (void);
00117 #endif
00118
00119 /*
00120  * WDOSX and Pmode/W uses same detect function with
00121  * unique signatures.
00122  */
00123 static BOOL is_wdosx_or_pmodew (DWORD sign)
00124 {
00125   union REGS reg;
00126 #ifdef __DJGPP__
00127   reg.x.eax = 0xEEFF;
00128   int86 (0x31, &reg, &reg);
00129 #else
00130   EAX_REG(reg) = 0xEEFF;
00131   int386 (0x31, &reg, &reg);
00132 #endif
00133   return (EAX_REG(reg) == sign);
00134 }
00135
00136 BOOL dpmi_is_wdosx (void)
00137 {
00138   return is_wdosx_or_pmodew (WDOSX_SIGN);
00139 }
00140
00141 BOOL dpmi_is_pmodew (void)
00142 {
00143   return is_wdosx_or_pmodew (PMODEW_SIGN);
00144 }
00145
00146 BOOL dpmi_is_dos32a (void)
00147 {
00148   union REGS reg;
00149 #ifdef __DJGPP__
00150   reg.x.eax = 0xFF89;  /* Get configuation info */
00151   int86 (0x21, &reg);
00152 #else
00153   EAX_REG(reg) = 0xFF89;
00154   int386 (0x21, &reg, &reg);
00155 #endif
00156
00157   if (EAX_REG(reg) == DOS32A_SIGN)
00158   {
00159     dos32a_nullptr_chk = (EDX_REG(reg) & 0x80);
00160     return (TRUE);
00161   }
00162   return (FALSE);
00163 }
00164
00165 BOOL dpmi_is_dos4gw (void)
00166 {
00167   union REGS reg;
00168 #ifdef __DJGPP__   /* doubt DOS4GW and djgpp is possible */
00169   reg.x.eax = 0xFF00;
00170   reg.x.edx = 0x78;
00171   int86 (0x21, &reg);
00172 #else
00173   EAX_REG(reg) = 0xFF00;
00174   EDX_REG(reg) = 0x78;
00175   int386 (0x21, &reg, &reg);
00176 #endif
00177   return (EAX_REG(reg) == 0xFFFF3447);
00178 }
00179
00180 BOOL dpmi_is_causeway (void)
00181 {
00182 #if defined(__DJGPP__)
00183   union  REGS  r;
00184   struct SREGS s;
00185   DWORD  rp;
00186   char   sign[10];
00187
00188   s.ds = s.es = _my_ds();
00189   r.x.eax = 0x3531;
00190   int86x (0x21, &r, &r, &s);
00191   if (s.es == 0 || !SelReadable(s.es) ||
00192       __dpmi_get_segment_limit(s.es) < r.x.ebx)
00193      return (FALSE);
00194
00195   movedata (s.es, r.x.ebx, _my_ds(), (unsigned)&sign, sizeof(sign));
00196   if (!memcmp(sign,"CAUSEWAY",8))
00197   {
00198     causeway_ver = (sign[8] << 8) + sign[9];
00199     return (TRUE);
00200   }
00201
00202 #elif defined(__CCDL__)
00203   /* !! to-do */
00204
00205 #elif defined(__WATCOMC__)
00206   union  REGS  r;
00207   struct SREGS s;
00208   BYTE  _far *rp;
00209
00210   EAX_REG(r) = 0x3531;
00211   segread (&s);
00212   int386x (0x21, &r, &r, &s);
00213
00214   rp = MK_FP (s.es, EBX_REG(r)-10);
00215
00216   if (s.es && SelReadable(s.es)    &&
00217       EAX_REG(r) < GET_LIMIT(s.es) &&
00218       !_fstrncmp(rp,"CAUSEWAY",8))
00219   {
00220     rp += 8;
00221     causeway_ver = (rp[0] << 8) + rp[1];
00222     return (TRUE);
00223   }
00224 #endif
00225   return (FALSE);
00226 }
00227
00228 BOOL dpmi_is_hxdos (void)
00229 {
00230   union REGS reg;
00231   char  buf[128] = { '\0' };
00232
00233 #ifdef __DJGPP__
00234   reg.x.eax = 0x401;
00235   reg.x.edi = (DWORD) &buf;
00236   int86 (0x31, &reg, &reg);
00237 #else
00238   EAX_REG(reg) = 0x401;
00239   EDI_REG(reg) = (DWORD) &buf;
00240   int386 (0x31, &reg, &reg);
00241 #endif
00242   return !strncmp(buf+2,"HDPMI",5);
00243 }
00244
00245 const char *dos4gw_extender_name (void)
00246 {
00247   if (dpmi_is_causeway())
00248      return ("CAUSEWAY");
00249   if (dpmi_is_wdosx())
00250      return ("WDOSX");
00251   if (dpmi_is_pmodew())
00252      return ("PMODEW");
00253   if (dpmi_is_dos32a())
00254      return ("DOS32A");
00255   if (dpmi_is_dos4gw())
00256      return ("DOS4GW");
00257   if (dpmi_is_hxdos())
00258      return ("HXDOS");
00259   return ("DOS4GW");  /* assume the rest are DOS4GW compatible */
00260 }
00261
00262 /*
00263  * Exception handler for Causeway stubbed programs.
00264  * Setup to call 'exc_func' when exception occurs.
00265  */
00266 int dpmi_except_handler (exceptionHook exc_func)
00267 {
00268 #if defined(WATCOM386) && defined(USE_EXCEPT_HANDLER)
00269   union  REGS  r;
00270   struct SREGS s;
00271
00272   if (!dpmi_is_causeway())
00273   {
00274     __dpmi_errno = 0x8001;
00275     return (0);
00276   }
00277
00278   __dpmi_errno = 0;
00279   segread (&s);
00280   s.ds    = FP_SEG (exception_main); /* vector address */
00281   r.x.esi = FP_OFF (exception_main);
00282   s.es    = FP_SEG (&exc_struct);    /* info dump address */
00283   r.x.edi = FP_OFF (&exc_struct);
00284   r.h.cl  = 1;                       /* 32-bit routine */
00285   r.w.ax  = 0xFF31;                  /* USER_ERR_TERM */
00286   int386x (0x31, &r, &r, &s);
00287   if (CARRY(r))
00288   {
00289     __dpmi_errno = AX_REG(r);
00290     return (0);
00291   }
00292   r.w.ax = 0xFF30;                   /* SetDump */
00293   r.h.cl = 0;
00294   int386 (0x31, &r, &r);
00295
00296   user_exc_hook = exc_func;
00297   memset (&exc_struct, 0, sizeof(exc_struct));
00298   dpmi_lock_region ((void*)&exc_struct, sizeof(exc_struct));
00299   dpmi_lock_region ((void*)exception_main, 100);
00300   return (1);
00301 #else
00302   ARGSUSED (exc_func);
00303   __dpmi_errno = 0x8001;
00304   return (0);
00305 #endif
00306 }
00307 #endif /* !(DOSX & POWERPAK) */
00308
00309
00310 void *dpmi_get_real_vector (int intr)
00311 {
00312   union REGS r;
00313
00314   __dpmi_errno = 0;
00315   EAX_REG(r) = 0x200;
00316   EBX_REG(r) = (DWORD) intr;
00317   int386 (0x31, &r, &r);
00318   return SEG_OFS_TO_LIN (CX_REG(r), DX_REG(r));
00319 }
00320
00321 int dpmi_get_base_address (WORD sel, DWORD *base)
00322 {
00323   union REGS r;
00324
00325   __dpmi_errno = 0;
00326   EAX_REG(r) = 0x06;
00327   EBX_REG(r) = sel;
00328   int386 (0x31, &r, &r);
00329   if (CARRY(r))
00330   {
00331     __dpmi_errno = AX_REG(r);
00332     return (0);
00333   }
00334   *base = (CX_REG(r) << 16) + DX_REG(r);
00335   return (1);
00336 }
00337
00338 WORD dpmi_real_malloc (WORD size, WORD *selector)
00339 {
00340   union REGS r;
00341
00342   __dpmi_errno = 0;
00343   EAX_REG(r) = 0x0100;           /* DPMI allocate DOS memory */
00344   EBX_REG(r) = (size + 15) / 16; /* Number of paragraphs requested */
00345   int386 (0x31, &r, &r);
00346   if (CARRY(r))
00347   {
00348     __dpmi_errno = AX_REG(r);
00349     return (0);
00350   }
00351   *selector = DX_REG(r);         /* Return selector */
00352   return AX_REG(r);              /* Return segment address */
00353 }
00354
00355 int dpmi_real_free (WORD selector)
00356 {
00357   union REGS r;
00358
00359   __dpmi_errno = 0;
00360   EAX_REG(r) = 0x101;            /* DPMI free DOS memory */
00361   EBX_REG(r) = selector;         /* Selector to free */
00362   int386 (0x31, &r, &r);
00363   if (CARRY(r))
00364   {
00365     __dpmi_errno = AX_REG(r);
00366     return (0);
00367   }
00368   return (1);
00369 }
00370
00371 int dpmi_lock_region (void *address, unsigned length)
00372 {
00373   union REGS r;
00374   DWORD base, linear;
00375
00376   if (!dpmi_get_base_address(MY_CS(),&base))
00377      return (0);
00378
00379   linear = base + (DWORD)address;
00380   __dpmi_errno = 0;
00381
00382   EAX_REG(r) = 0x600;            /* DPMI Lock Linear Region */
00383   EBX_REG(r) = (linear >> 16);   /* Linear address in BX:CX */
00384   ECX_REG(r) = (linear & 0xFFFF);
00385   ESI_REG(r) = (length >> 16);   /* Length in SI:DI */
00386   EDI_REG(r) = (length & 0xFFFF);
00387   int386 (0x31, &r, &r);
00388   if (CARRY(r))
00389   {
00390     __dpmi_errno = AX_REG(r);
00391     return (0);
00392   }
00393   return (1);
00394 }
00395
00396 int dpmi_unlock_region (void *address, unsigned length)
00397 {
00398   union REGS r;
00399   DWORD base, linear;
00400
00401   if (!dpmi_get_base_address(MY_CS(),&base))
00402      return (0);
00403
00404   linear = base + (DWORD)address;
00405   __dpmi_errno = 0;
00406
00407   EAX_REG(r) = 0x601;            /* DPMI Unlock Linear Region */
00408   EBX_REG(r) = (linear >> 16);   /* Linear address in BX:CX */
00409   ECX_REG(r) = (linear & 0xFFFF);
00410   ESI_REG(r) = (length >> 16);   /* Length in SI:DI */
00411   EDI_REG(r) = (length & 0xFFFF);
00412   int386 (0x31, &r, &r);
00413   if (CARRY(r))
00414   {
00415     __dpmi_errno = AX_REG(r);
00416     return (0);
00417   }
00418   return (1);
00419 }
00420
00421 #if !defined(__CCDL__)
00422 int dpmi_real_interrupt (int intr, IREGS *reg)
00423 {
00424   union  REGS  r;
00425   struct SREGS s;
00426
00427   __dpmi_errno = 0;
00428   memset (&r, 0, sizeof(r));
00429   segread (&s);
00430   EAX_REG(r) = 0x300;
00431   EBX_REG(r) = intr;
00432   ECX_REG(r) = 0;
00433   s.es       = FP_SEG (reg);
00434   EDI_REG(r) = FP_OFF (reg);
00435   reg->r_flags = 0;
00436   reg->r_ss = reg->r_sp = 0;     /* DPMI host provides stack */
00437
00438   int386x (0x31, &r, &r, &s);
00439   if (CARRY(r))
00440   {
00441     reg->r_flags |= 1;
00442     __dpmi_errno = AX_REG(r);
00443     return (0);
00444   }
00445   return (1);
00446 }
00447 #endif
00448
00449 int dpmi_real_call_retf (IREGS *reg)
00450 {
00451   union  REGS  r;
00452   struct SREGS s;
00453
00454   __dpmi_errno = 0;
00455   memset (&r, 0, sizeof(r));
00456   segread (&s);
00457   EAX_REG(r) = 0x301;
00458   EBX_REG(r) = 0;
00459   ECX_REG(r) = 0;
00460   s.es       = FP_SEG (reg);
00461   EDI_REG(r) = FP_OFF (reg);
00462   reg->r_flags = 0;
00463   reg->r_ss = reg->r_sp = 0;     /* DPMI host provides stack */
00464
00465   int386x (0x31, &r, &r, &s);
00466   if (CARRY(r))
00467   {
00468     reg->r_flags |= 1;
00469     __dpmi_errno = AX_REG(r);
00470     return (0);
00471   }
00472   return (1);
00473 }
00474
00475 /*
00476  * PowerPak already have int386().
00477  */
00478 #if (defined(DMC386) || defined(MSC386) || defined(BORLAND386)) && \
00479     !(DOSX & POWERPAK)
00480 static int real_interrupt (int intr, IREGS *reg)
00481 {
00482   __asm {
00483       push ebx
00484       push edi
00485       mov  edi, reg        /* es:edi -> reg */
00486       mov  edx, esp        /* save esp */
00487       mov  ebx, intr
00488       mov  eax, 300h       /* simulate real-int */
00489       int  31h
00490       mov  esp, edx
00491       xor  eax, eax        /* assume ok */
00492       pop  edi
00493       pop  ebx
00494       jc   fail
00495       pop  ebp
00496       ret
00497   }
00498 fail:
00499   return (-1);
00500 }
00501
00502 int int386 (int intno, union REGS *ireg, union REGS *oreg)
00503 {
00504   struct SREGS sreg;
00505
00506   segread (&sreg);
00507   return int386x (intno, ireg, oreg, &sreg);
00508 }
00509
00510 int int386x (int intno, union REGS *ireg, union REGS *oreg, struct SREGS *sreg)
00511 {
00512   static IREGS rm_reg;
00513
00514   rm_reg.r_ss = rm_reg.r_sp = rm_reg.r_flags = 0;
00515   rm_reg.r_ax = ireg->x.eax;
00516   rm_reg.r_bx = ireg->x.ebx;
00517   rm_reg.r_cx = ireg->x.ecx;
00518   rm_reg.r_dx = ireg->x.edx;
00519   rm_reg.r_si = ireg->x.esi;
00520   rm_reg.r_di = ireg->x.edi;
00521   rm_reg.r_ds = sreg->ds;
00522   rm_reg.r_es = sreg->es;
00523   rm_reg.r_gs = 0;     /* needed? */
00524   rm_reg.r_fs = 0;     /* needed? */
00525
00526   if (real_interrupt(intno,&rm_reg) < 0)
00527   {
00528     oreg->x.cflag |= 1; /* Set carry bit */
00529     return (-1);
00530   }
00531   oreg->x.eax   = rm_reg.r_ax;
00532   oreg->x.ebx   = rm_reg.r_bx;
00533   oreg->x.ecx   = rm_reg.r_cx;
00534   oreg->x.edx   = rm_reg.r_dx;
00535   oreg->x.esi   = rm_reg.r_si;
00536   oreg->x.edi   = rm_reg.r_di;
00537   oreg->x.flags = rm_reg.r_flags;
00538   return (int)rm_reg.r_ax;
00539 }
00540
00541 void segread (struct SREGS *sreg)
00542 {
00543   sreg->ds = MY_DS();
00544   sreg->es = MY_ES();
00545   sreg->ss = MY_SS();
00546   sreg->cs = MY_CS();
00547 }
00548 #endif  /* (DMC386 || MSC386 || BORLAND386) && !(DOSX & POWERPAK) */
00549
00550
00551 #if (DOSX & DOS4GW) && defined(WATCOM386)
00552
00553 #if defined(USE_EXCEPT_HANDLER)
00554
00555 extern int _STACKTOP;  /* internal variable, top of Watcom stack */
00556
00557 /*
00558  * Various contortions necessary to set CauseWay internal stack to
00559  * Watcom DGROUP-based stack and to keep the unknown number of stack
00560  * parameters relative to register EBP unchanged.
00561  */
00562 extern void SS_TO_DGROUP (void);
00563 #pragma aux SS_TO_DGROUP =          \
00564         "sub ebp, esp"              \
00565         "xor eax, eax"              \
00566         "mov ax, ss"                \
00567         "mov es, ax"                \
00568         "mov ebx, esp"              \
00569         "mov edx, _STACKTOP"        \
00570         "mov cx, ds"                \
00571         "mov ss, cx"                \
00572         "mov esp, edx"              \
00573         "mov edx, esi"              \
00574         "mov edi, esi"              \
00575         "sub edi, ebx"              \
00576         "sub edx, 2"                \
00577         "looper: mov cx, es:[edx]"  \
00578         "sub esp, 2"                \
00579         "mov ss:[esp], cx"          \
00580         "sub edx, 2"                \
00581         "sub edi, 2"                \
00582         "jg  looper"                \
00583         "add ebp, esp"              \
00584         "push eax"                  \
00585         "push esi"                  \
00586         modify [eax ebx ecx edx edi];
00587
00588 extern void RESTORE_SS_AND_GO (void);
00589 #pragma aux RESTORE_SS_AND_GO = \
00590         "pop esi"               \
00591         "pop eax"               \
00592         "sub esi, 8"            \
00593         "mov ss, ax"            \
00594         "mov esp, esi"          \
00595         "retf";
00596
00597 /*
00598  * Termination routine MUST NOT have stack-checking enabled.
00599  * If virtual memory is in use, this routine and all code and data called
00600  * or used by the routine (including Watcom runtime library functions)
00601  * must be locked in memory.
00602  */
00603 #include "nochkstk.h"
00604
00605 static void far __loadds exception_main (void)
00606 {
00607   SS_TO_DGROUP();
00608
00609   exc_struct.mode = (exc_struct.cs != MY_CS());
00610
00611   if (user_exc_hook)
00612        (*user_exc_hook) (&exc_struct);
00613   else _printk ("Exception %d at CS:EIP %04X:%08X\n)",
00614                 exc_struct.fault_num, exc_struct.cs, exc_struct.eip);
00615   RESTORE_SS_AND_GO();
00616 }
00617 #endif /* USE_EXCEPT_HANDLER */
00618
00621 static DWORD exc_app_start = 4096UL;
00622
00623 /*
00624  * Perform a stack trace back to CRT. Function arguments printed only
00625  * for stack-based calls (-3s).
00626  *
00627  * \todo Merge this function with the one in x32vm.c.
00628  */
00629 void stack_rewind (DWORD start, DWORD base)
00630 {
00631   int   loop  = 10;                           /* print max 10 stack frames */
00632   DWORD eip   = start;
00633   DWORD limit = get_cs_limit();
00634   const DWORD *context = (const DWORD*) base; /* EBP increases as we rewind */
00635   BOOL  reg_calls = FALSE;
00636
00637 #if defined(__SW_3R)
00638   reg_calls = TRUE;
00639 #endif
00640
00641   _printk ("Stack trace:\r\n");
00642
00643   while (context >= (DWORD*)base && ((DWORD)context & 3) == 0 && --loop)
00644   {
00645     const DWORD *next;
00646
00647     if ((DWORD)context >= limit - 4 || eip >= limit ||
00648         (DWORD)context <= exc_app_start || eip <= exc_app_start)
00649        break;
00650
00651     _printk ("  %08X ", eip);
00652
00653     next = (const DWORD*) *context;  /* get ESP stack value from context */
00654
00655     /* Compute number of args to display
00656      */
00657     if (next == NULL ||              /* we're rewound back to CRT */
00658         next <= (const DWORD*)exc_app_start || reg_calls)
00659        _printk ("( *** )");
00660
00661     else
00662     {
00663       const DWORD *argv;
00664       DWORD        argc = next - context - 2;
00665
00666       argc = (argc > 5) ? 5 : argc;
00667       _printk ("(");
00668
00669       argv = context + 2; /* Args start after saved EBP and return address */
00670       while (argc--)
00671       {
00672         if (argc == 0)
00673              _printk ("%04X)\r\n", *argv++);
00674         else _printk ("%04X ",     *argv++);
00675       }
00676     }
00677     eip     = *(context+1);  /* get next return address */
00678     context = next;
00679   }
00680   _printk ("\r\n");
00681 }
00682 #endif  /* (DOSX & DOS4GW) && WATCOM386 */
00683 #endif  /* DOSX & (DOS4GW|POWERPAK) */
00684
00685
00686 #if defined(WATCOM386)
00687 BOOL dpmi_init (void)
00688 {
00689   switch (_Extender)
00690   {
00691     case DOSX_PHAR_V2:  /* Test for Pharlap extenders */
00692     case DOSX_PHAR_V3:
00693     case DOSX_PHAR_V4:
00694     case DOSX_PHAR_V5:
00695     case DOSX_PHAR_V6:
00696     case DOSX_PHAR_V7:
00697     case DOSX_PHAR_V8:
00698 #if (DOSX & PHARLAP)
00699          return (TRUE);
00700 #else
00701          outsnl (_LANG("\7The Watt-32 library was not compiled for Pharlap."));
00702          return (FALSE);
00703
00704     case DOSX_RATIONAL:
00705          if (_ExtenderSubtype & XS_RATIONAL_NONZEROBASE)
00706          {
00707            outsnl (_LANG("\7Only zero-based DOS4GW application supported."));
00708            return (FALSE);
00709          }
00710          break;  /* okay */
00711 #endif
00712
00713     default:
00714 #if (DOSX & PHARLAP)
00715          outsnl (_LANG("\7Only Pharlap extenders supported"));
00716 #else
00717          outsnl (_LANG("\7Only DOS4GW style extenders supported"));
00718 #endif
00719          return (FALSE);
00720   }
00721   return (TRUE);
00722 }
00723 #endif  /* WATCOM386 */
00724 #endif  /* WIN32 */
Generated on Wed Jan 25 15:42:40 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/WDPMI.H Source File

SRC/WDPMI.H

Go to the documentation of this file.
00001
00003 #ifndef _w32_WDPMI_H
00004 #define _w32_WDPMI_H
00005
00006 #if defined(WATCOM386)
00007   extern BOOL dpmi_init (void);
00008 #endif
00009
00010 #if (DOSX & (DOS4GW|POWERPAK))
00011
00012   #include "misc.h"       /* IREGS */
00013   #include <sys/packon.h>
00014
00015   struct FAULT_STRUC {   /* Exception structure (only used by CauseWay) */
00016          DWORD  ebp, edi, esi, edx, ecx, ebx, eax;
00017          WORD   gs, fs, es, ds;
00018          DWORD  eip;
00019          WORD   cs, reserved1;
00020          DWORD  eflags, esp;
00021          WORD   ss, reserved2;
00022          WORD   tr;
00023          DWORD  cr0, cr1, cr2, cr3;
00024          DWORD  csAddr;
00025          DWORD  dsAddr;
00026          DWORD  esAddr;
00027          DWORD  fsAddr;
00028          DWORD  gsAddr;
00029          DWORD  ssAddr;
00030          WORD   fault_num;
00031          DWORD  code;
00032          BOOL   mode;  /* 0: exception in pmode, 1: real-mode */
00033        };
00034
00035   #include <sys/packoff.h>
00036
00037   #define SEG_OFS_TO_LIN(seg,ofs) (void*)(((WORD)(seg) << 4) + (WORD)(ofs))
00038
00039   extern WORD __dpmi_errno;
00040
00041   extern WORD  dpmi_real_malloc     (WORD size, WORD *sel);
00042   extern int   dpmi_real_free       (WORD selector);
00043   extern int   dpmi_get_base_address(WORD sel, DWORD *base);
00044   extern int   dpmi_lock_region     (void *address, unsigned length);
00045   extern int   dpmi_unlock_region   (void *address, unsigned length);
00046   extern void *dpmi_get_real_vector (int intr);
00047   extern int   dpmi_real_interrupt  (int intr, IREGS *reg);
00048   extern int   dpmi_real_call_retf  (IREGS *reg);
00049 #endif
00050
00051 #if (DOSX & DOS4GW)
00052   extern BOOL  dpmi_is_wdosx    (void);
00053   extern BOOL  dpmi_is_pmodew   (void);
00054   extern BOOL  dpmi_is_dos32a   (void);
00055   extern BOOL  dpmi_is_dos4gw   (void);
00056   extern BOOL  dpmi_is_causeway (void);
00057
00058   typedef void (*exceptionHook) (const struct FAULT_STRUC *);
00059
00060   extern int dpmi_except_handler (exceptionHook exc_func);
00061   extern const char *dos4gw_extender_name (void);
00062
00063   #define stack_rewind  NAMESPACE (stack_rewind)
00064   extern void stack_rewind (DWORD start, DWORD base);
00065 #endif
00066
00067 #endif /* !_w32_WDPMI_H */
00068
Generated on Wed Jan 25 15:42:40 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/WINMISC.C Source File

SRC/WINMISC.C

Go to the documentation of this file.
00001
00032 #include "socket.h"
00033 #include "udp_dom.h"
00034 #include "get_xby.h"
00035 #include "sock_ini.h"
00036
00037 #if defined(WIN32) && defined(HAVE_WINDNS_H)
00038
00039 #include <winsock.h>
00040 #include <windns.h>
00041
00042 CRITICAL_SECTION _watt_crit_sect;
00043 BOOL             _watt_is_win9x = FALSE;
00044
00045 static BOOL is_gui_app = FALSE;
00046
00047 /*
00048  * 'dns_windns' bits.
00049  */
00050 #define WINDNS_QUERY_A4     0x0001
00051 #define WINDNS_QUERY_A6     0x0002
00052 #define WINDNS_QUERY_PTR4   0x0004
00053 #define WINDNS_QUERY_PTR6   0x0008
00054 #define WINDNS_CACHEPUT_A4  0x0100
00055 #define WINDNS_CACHEPUT_A6  0x0200
00056
00057 #ifndef DNS_TYPE_AAAA
00058 #define DNS_TYPE_AAAA  0x001C
00059 #endif
00060
00061 #ifndef DNS_ERROR_RESPONSE_CODES_BASE
00062 #define DNS_ERROR_RESPONSE_CODES_BASE  9000
00063 #endif
00064
00065 #ifndef DNS_ERROR_RCODE_LAST
00066 #define DNS_ERROR_RCODE_LAST  9018
00067 #endif
00068
00069 #ifndef IN
00070 #define IN
00071 #endif
00072
00073 #ifndef OUT
00074 #define OUT
00075 #endif
00076
00077 #ifndef OPTIONAL
00078 #define OPTIONAL
00079 #endif
00080
00081 /*
00082  * DnsApi.dll is used dynamically. So we need
00083  * these function pointers.
00084  */
00085 typedef DNS_STATUS (WINAPI *DnsQuery_A_func) (
00086         IN     const char  *name,
00087         IN     WORD         wType,
00088         IN     DWORD        options,
00089         IN     IP4_ARRAY   *aipServers,
00090         IN OUT DNS_RECORD **queryResults,
00091         IN OUT void       **reserved);
00092
00093 typedef DNS_STATUS (WINAPI *DnsModifyRecordsInSet_A_func) (
00094         IN     DNS_RECORD *addRecords,
00095         IN     DNS_RECORD *deleteRecords,
00096         IN     DWORD       options,
00097         IN     HANDLE      context,    OPTIONAL
00098         IN     IP4_ARRAY  *serverList, OPTIONAL
00099         IN     void       *reserved);
00100
00101 typedef void (WINAPI *DnsFree_func) (
00102         IN OUT void *data,
00103         IN     DNS_FREE_TYPE freeType);
00104
00105 static DnsFree_func                 _DnsFree                 = NULL;
00106 static DnsQuery_A_func              _DnsQuery_A              = NULL;
00107 static DnsModifyRecordsInSet_A_func _DnsModifyRecordsInSet_A = NULL;
00108
00109 static HINSTANCE windns_mod = NULL;
00110
00111 /*
00112  * Various stuff to initialise.
00113  */
00114 static BOOL get_win_version (WORD *ver, BOOL *is_win9x)
00115 {
00116   OSVERSIONINFO ovi;
00117   DWORD os_ver = GetVersion();
00118   DWORD major_ver = LOBYTE (LOWORD(os_ver));
00119
00120   *is_win9x = (os_ver >= 0x80000000 && major_ver >= 4);
00121
00122   memset (&ovi, 0, sizeof(ovi));
00123   ovi.dwOSVersionInfoSize = sizeof(ovi);
00124   if (!GetVersionEx(&ovi))
00125      return (FALSE);
00126
00127   *ver = (WORD)(ovi.dwMajorVersion << 8) +
00128          (WORD)ovi.dwMinorVersion;
00129   return (TRUE);
00130 }
00131
00132 /*
00133  * Check if program is a GUI app.
00134  */
00135 static BOOL check_gui_app (void)
00136 {
00137   const IMAGE_DOS_HEADER *dos;
00138   const IMAGE_NT_HEADERS *nt;
00139   HMODULE mod = GetModuleHandle (NULL);
00140   HANDLE  hnd = GetStdHandle (STD_OUTPUT_HANDLE);
00141
00142   WIN_ASSERT (mod != NULL);
00143
00144   if (hnd && GetFileType(hnd) != FILE_TYPE_UNKNOWN)
00145      return (FALSE);
00146
00147   dos = (const IMAGE_DOS_HEADER*) mod;
00148   nt  = (const IMAGE_NT_HEADERS*) ((const BYTE*)mod + dos->e_lfanew);
00149   return (nt->OptionalHeader.Subsystem == IMAGE_SUBSYSTEM_WINDOWS_GUI);
00150 }
00151
00152 static int gui_printf (const char *fmt, ...)
00153 {
00154   char    buf[1024];
00155   int     len;
00156   char   *prog_name, *s;
00157   DWORD   mb_flags;
00158   va_list args;
00159
00160   va_start (args, fmt);
00161   len = _vsnprintf (buf, sizeof(buf), fmt, args);
00162
00163   s = (char*) get_argv0();
00164   if ((prog_name = strrchr(s,'\\')) == NULL &&
00165       (prog_name = strrchr(s, ':')) == NULL)
00166        prog_name = s;
00167   else prog_name++;
00168
00169   mb_flags = MB_ICONSTOP | MB_SETFOREGROUND;
00170   mb_flags |= _watt_is_win9x ? MB_SYSTEMMODAL : MB_TASKMODAL;
00171   MessageBox (NULL, buf, prog_name, mb_flags);
00172
00173   va_end (args);
00174   return (len);
00175 }
00176
00177 static void win32_exit (void)
00178 {
00179   if (windns_mod)
00180      FreeLibrary (windns_mod);
00181   windns_mod = NULL;
00182
00183 #if defined(__LCC__)
00184   DeleteCriticalSection ((struct _CRITICAL_SECTION*)&_watt_crit_sect);
00185 #else
00186   DeleteCriticalSection (&_watt_crit_sect);
00187 #endif
00188 }
00189
00190 /*
00191  * Return err-number+string for 'err'. Use only with GetLastError().
00192  * Does not handle libc errno's. Remove trailing [\r\n.]
00193  */
00194 char *win_strerror (DWORD err)
00195 {
00196   static char buf[512+20];
00197   char   err_buf[512], *p;
00198
00199   if (!FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, err,
00200                       LANG_NEUTRAL, err_buf, sizeof(err_buf)-1, NULL))
00201      strcpy (err_buf, "Unknown error");
00202   _snprintf (buf, sizeof(buf), "%lu/0x%lX %s", err, err, err_buf);
00203   rip (buf);
00204   p = strrchr (buf, '.');
00205   if (p && p[1] == '\0')
00206      *p = '\0';
00207   return (buf);
00208 }
00209
00210 /*
00211  * WIN_ASSERT() fail handler.
00212  */
00213 void assert_fail_win (const char *file, unsigned line, const char *what)
00214 {
00215   _snprintf (_watt_assert_buf, sizeof(_watt_assert_buf),
00216              "%s (%u): Assertion `%s' failed. GetLastError() %s\n\n",
00217              file, line, what, win_strerror(GetLastError()));
00218
00219   is_gui_app ? gui_printf(_watt_assert_buf) : (*_printf)("%s\n", _watt_assert_buf);
00220   rundown_run();
00221   exit (-1);
00222 }
00223
00224 /*
00225  * Called from init_misc() to initialise Win32 specific things.
00226  */
00227 BOOL init_winmisc (void)
00228 {
00229 #if defined(__LCC__)
00230   InitializeCriticalSection ((struct _CRITICAL_SECTION*)&_watt_crit_sect);
00231 #else
00232   InitializeCriticalSection (&_watt_crit_sect);
00233 #endif
00234
00235   _watt_os_ver = 0x0400;   /* defaults to Win-NT 4.0 */
00236   if (!get_win_version (&_watt_os_ver, &_watt_is_win9x))
00237      return (FALSE);
00238
00239   windns_mod = LoadLibrary ("dnsapi.dll");
00240   if (windns_mod)
00241   {
00242     _DnsQuery_A = (DnsQuery_A_func)
00243       GetProcAddress (windns_mod, "DnsQuery_A");
00244
00245     _DnsFree = (DnsFree_func)
00246       GetProcAddress (windns_mod, "DnsFree");
00247
00248     _DnsModifyRecordsInSet_A = (DnsModifyRecordsInSet_A_func)
00249       GetProcAddress (windns_mod, "DnsModifyRecordsInSet_A");
00250   }
00251
00252   is_gui_app = check_gui_app();
00253
00254   RUNDOWN_ADD (win32_exit, 310);
00255   return (TRUE);
00256 }
00257
00258 /*
00259  * Perform a query on the WinDns cache. We ask only for
00260  * an address (A/AAAA records) or a name (PTR record).
00261  */
00262 static BOOL WinDnsQueryCommon (WORD type, const void *what,
00263                                void *result, size_t size)
00264 {
00265   DNS_RECORD *rr, *dr = NULL;
00266   DNS_STATUS  rc;
00267   BOOL   found;
00268   DWORD  opt = DNS_QUERY_NO_WIRE_QUERY | /* query the cache only */
00269                DNS_QUERY_NO_NETBT |      /* no NetBT names */
00270                DNS_QUERY_NO_HOSTS_FILE;  /* no Winsock hosts file */
00271
00272   if (!_DnsQuery_A || !_DnsFree)
00273      return (FALSE);
00274
00275   rc = (*_DnsQuery_A) ((const char*)what, type, opt, NULL, &dr, NULL);
00276
00277   TCP_CONSOLE_MSG (2, ("DnsQuery_A: type %d, dr %p: %s\n",
00278                    type, dr, win_strerror(rc)));
00279
00280   if (rc != ERROR_SUCCESS || !dr)
00281      return (FALSE);
00282
00283   dom_ttl = dr->dwTtl;
00284   found = FALSE;
00285
00286   for (rr = dr; rr; rr = rr->pNext)
00287   {
00288     TCP_CONSOLE_MSG (2, ("RR-type: %d: ", rr->wType));
00289
00290     /* Use only 1st A/AAAA record
00291      */
00292     if (rr->wType == DNS_TYPE_A && type == DNS_TYPE_A)
00293     {
00294       DWORD ip = ntohl (rr->Data.A.IpAddress);
00295
00296       TCP_CONSOLE_MSG (2, ("A: %s, ttl %lus\n",
00297                        _inet_ntoa(NULL,ip), rr->dwTtl));
00298       if (!found)
00299          *(DWORD*) result = ip;
00300       found = TRUE;
00301     }
00302
00303 #if defined(USE_BSD_API) || defined(USE_IPV6)
00304     else if (rr->wType == DNS_TYPE_AAAA && type == DNS_TYPE_AAAA)
00305     {
00306       const void *ip6 = &rr->Data.AAAA.Ip6Address.IP6Dword[0];
00307
00308       TCP_CONSOLE_MSG (2, ("AAAA: %s\n", _inet6_ntoa(ip6)));
00309       if (!found)
00310          memcpy (result, ip6, size);
00311       found = TRUE;
00312     }
00313 #endif
00314
00315     else if (rr->wType == DNS_TYPE_PTR && type == DNS_TYPE_PTR)
00316     {
00317       StrLcpy (result, dr->Data.PTR.pNameHost, size);
00318       TCP_CONSOLE_MSG (2, ("PTR: %s\n", (const char*)result));
00319     }
00320     else if (rr->wType == DNS_TYPE_CNAME)
00321     {
00322       StrLcpy (dom_cname, dr->Data.CNAME.pNameHost, sizeof(dom_cname));
00323       TCP_CONSOLE_MSG (2, ("CNAME: %s\n", dom_cname));
00324     }
00325     else
00326       TCP_CONSOLE_MSG (2, ("\n"));
00327   }
00328   (*_DnsFree) (dr, DnsFreeRecordList);
00329   return (TRUE);
00330 }
00331
00332 BOOL WinDnsQuery_A4 (const char *name, DWORD *ip)
00333 {
00334   if (!(dns_windns & WINDNS_QUERY_A4))
00335      return (FALSE);
00336   return WinDnsQueryCommon (DNS_TYPE_A, name, ip, sizeof(*ip));
00337 }
00338
00339 BOOL WinDnsQuery_A6 (const char *name, void *ip)
00340 {
00341   if (!(dns_windns & WINDNS_QUERY_A6))
00342      return (FALSE);
00343   return WinDnsQueryCommon (DNS_TYPE_AAAA, name, ip, sizeof(ip6_address));
00344 }
00345
00346 BOOL WinDnsQuery_PTR4 (DWORD ip, char *name, size_t size)
00347 {
00348   if (!(dns_windns & WINDNS_QUERY_PTR4))
00349      return (FALSE);
00350   return WinDnsQueryCommon (DNS_TYPE_PTR, &ip, name, size);
00351 }
00352
00353 BOOL WinDnsQuery_PTR6 (const void *ip, char *name, size_t size)
00354 {
00355   if (!(dns_windns & WINDNS_QUERY_PTR6))
00356      return (FALSE);
00357   return WinDnsQueryCommon (DNS_TYPE_PTR, &ip, name, size);
00358 }
00359
00360 /*
00361  * This doesn't seem to simply put a name/IP pair in the
00362  * local cache, but do a complete registration with the
00363  * Winsock registered DNS serve(s). Hence off by default.
00364  */
00365 BOOL WinDnsCachePut_A4 (const char *name, DWORD ip4)
00366 {
00367   DNS_RECORD rr;
00368   DNS_STATUS rc;
00369   DWORD      opt = DNS_UPDATE_SECURITY_OFF |
00370                    DNS_UPDATE_CACHE_SECURITY_CONTEXT;
00371
00372   if (!_DnsModifyRecordsInSet_A ||
00373       !(dns_windns & WINDNS_CACHEPUT_A4))
00374      return (FALSE);
00375
00376   memset (&rr, 0, sizeof(rr));
00377
00378   rr.pName = strdup (name);
00379   rr.wType = DNS_TYPE_A;
00380   rr.dwTtl = netdbCacheLife;
00381   rr.Data.A.IpAddress = htonl (ip4);
00382   rr.wDataLength      = sizeof(rr.Data.A);
00383
00384   rc = (*_DnsModifyRecordsInSet_A) (&rr, NULL, opt,
00385                                     NULL, NULL, NULL);
00386   if (rr.pName)
00387      free (rr.pName);
00388
00389   TCP_CONSOLE_MSG (2, ("DnsModifyRecordsInSet_A: %s ",
00390                    win_strerror(rc)));
00391
00392   if (rc >= DNS_ERROR_RESPONSE_CODES_BASE && rc <= DNS_ERROR_RCODE_LAST)
00393      dns_windns &= ~WINDNS_CACHEPUT_A4;  /* don't do this again */
00394   return (rc == ERROR_SUCCESS);
00395 }
00396
00397 BOOL WinDnsCachePut_A6 (const char *name, const void *ip6)
00398 {
00399   if (!(dns_windns & WINDNS_CACHEPUT_A6))
00400      return (FALSE);
00401   ARGSUSED (name);
00402   ARGSUSED (ip6);
00403   return (FALSE);
00404 }
00405
00406 int __stdcall WSAStartup (WORD version_required, WSADATA *wsa_data)
00407 {
00408   int rc;
00409
00410   if (version_required > MAKEWORD(2,2))
00411      return (EINVAL);  /* we don't have WSAVERNOTSUPPORTED */
00412
00413   _watt_do_exit = 0;
00414   rc = watt_sock_init (0, 0);
00415
00416   wsa_data->wVersion     = version_required;
00417   wsa_data->wHighVersion = 2;
00418   wsa_data->iMaxSockets  = MAX_SOCKETS;
00419   wsa_data->iMaxUdpDg    = MAX_SOCKETS;
00420   wsa_data->lpVendorInfo = NULL;
00421   wsa_data->szSystemStatus[0] = '\0';
00422   strcpy (wsa_data->szDescription, "Watt-32 tcp/ip");
00423   return (rc);
00424 }
00425
00426 int __stdcall WSACleanup (void)
00427 {
00428   sock_exit();
00429   return (0);
00430 }
00431
00432 int __stdcall __WSAFDIsSet (int s, winsock_fd_set *fd)
00433 {
00434   UNFINISHED();
00435   ARGSUSED (s);
00436   ARGSUSED (fd);
00437   return (0);
00438 }
00439 #endif  /* WIN32 && HAVE_WINDNS_H */
00440
Generated on Wed Jan 25 15:42:40 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/WINPCAP.C Source File

SRC/WINPCAP.C

Go to the documentation of this file.
00001
00032 #include "wattcp.h"
00033
00034 #if defined(WIN32)
00035
00036 #include <windowsx.h>
00037 #include <process.h>
00038 #include <arpa/inet.h>
00039
00040 #include "strings.h"
00041 #include "misc.h"
00042 #include "timer.h"
00043 #include "sock_ini.h"
00044 #include "language.h"
00045 #include "pcconfig.h"
00046 #include "pcdbug.h"
00047 #include "pcstat.h"
00048 #include "pcpkt.h"
00049
00050 #include "winpcap.h"
00051 #include "NtddNdis.h"
00052 #include "Packet32.h"
00053
00054 #if (defined(_DLL) && !defined(_MT)) && !defined(__LCC__)
00055 #error This file must be compiled for threads
00056 #endif
00057
00058 #ifndef OID_GEN_PHYSICAL_MEDIUM
00059 #define OID_GEN_PHYSICAL_MEDIUM  0x00010202
00060 #endif
00061
00062 #ifndef OID_FDDI_LONG_PERMANENT_ADDRESS
00063 #define OID_FDDI_LONG_PERMANENT_ADDRESS  0x03010101
00064 #endif
00065
00066 #ifndef NDIS_FLAGS_SKIP_LOOPBACK_W2K
00067 #define NDIS_FLAGS_SKIP_LOOPBACK_W2K  0x400
00068 #endif
00069
00070 /* Rewritten from <NtDDNdis.h>
00071  */
00072 #define ND_PHY_Unspecified   0
00073 #define ND_PHY_WirelessLan   1
00074 #define ND_PHY_CableModem    2
00075 #define ND_PHY_PhoneLine     3
00076 #define ND_PHY_PowerLine     4
00077 #define ND_PHY_DSL           5
00078 #define ND_PHY_FibreChannel  6
00079 #define ND_PHY_1394          7
00080 #define ND_PHY_WirelessWan   8
00081
00082 WORD _pktdevclass = PDCLASS_UNKNOWN;
00083 WORD _pkt_ip_ofs  = 0;
00084 BOOL _pktserial   = FALSE;
00085 int  _pkt_errno   = 0;
00086 int  _pkt_rxmode  =  RXMODE_DEFAULT;
00087 int  _pkt_rxmode0 = -1;
00088 int  _pkt_forced_rxmode = -1;
00089 char _pktdrvrname   [MAX_VALUELEN+1] = "";
00090 char _pktdrvr_descr [MAX_VALUELEN+1] = "";
00091
00092 struct pkt_info *_pkt_inf = NULL;
00093
00094 /* Determines size of work buffers of NPF kernel and PacketReceivePacket().
00095  * It doesn't influence the size of thread queue yet.
00096  */
00097 static int pkt_num_rx_bufs = RX_BUFS;
00098
00099 /* NPF doesn't keep a count of transmitted packets and errors.
00100  * So we maintain these counters locally.
00101  */
00102 static DWORD num_tx_pkt    = 0UL;
00103 static DWORD num_tx_bytes  = 0UL;
00104 static DWORD num_tx_errors = 0UL;
00105 static DWORD num_rx_bytes  = 0UL;
00106 static DWORD pkt_drop_cnt  = 0UL;
00107 static int   pkt_txretries = 2;
00108 static int   thr_realtime  = 0;
00109 static BOOL  thr_stopped   = FALSE;
00110 static FILE *dump_file     = NULL;
00111 static char  dump_fname [MAX_PATHLEN] = "$(TEMP)\\winpcap_dump.txt";
00112
00113 static const struct search_list logical_media[] = {
00114      { -1,                   "Unknown" },
00115      { NdisMedium802_3,      "802.3" },
00116      { NdisMedium802_5,      "802.5" },
00117      { NdisMediumFddi,       "FDDI" },
00118      { NdisMediumWan,        "WAN" },
00119      { NdisMediumLocalTalk,  "LocalTalk" },
00120      { NdisMediumDix,        "DIX" },
00121      { NdisMediumArcnetRaw,  "ArcNet (raw)" },
00122      { NdisMediumArcnet878_2,"ArcNet (878.2)" },
00123      { NdisMediumAtm,        "ATM" },
00124      { NdisMediumWirelessWan,"WiFi" },
00125      { NdisMediumIrda,       "IrDA" },
00126      { NdisMediumNull,       "Null?!" },
00127      { NdisMediumCHDLC,      "CHDLC" },
00128      { NdisMediumPPPSerial,  "PPP-ser" }
00129     };
00130
00131 static const struct search_list phys_media[] = {
00132      { ND_PHY_WirelessLan,  "Wireless LAN" },
00133      { ND_PHY_CableModem,   "Cable"        },
00134      { ND_PHY_PhoneLine,    "Phone"        },
00135      { ND_PHY_PowerLine,    "PowerLine"    },
00136      { ND_PHY_DSL,          "DSL"          },
00137      { ND_PHY_FibreChannel, "Fibre"        },
00138      { ND_PHY_1394,         "IEEE1394"     },
00139      { ND_PHY_WirelessWan,  "Wireless WAN" }
00140    };
00141
00142 static BOOL get_perm_mac_address (void *mac);
00143 static BOOL get_interface_mtu (DWORD *mtu);
00144 static BOOL get_interface_type (WORD *link);
00145 static BOOL get_connected_status (BOOL *is_up);
00146 static void show_link_details (void);
00147 static void set_txmode (const char *value);
00148
00149 DWORD __stdcall pkt_recv_thread (void *arg);
00150
00154 static BOOL parse_config_pass_1 (void)
00155 {
00156   static const struct config_table pkt_init_cfg[] = {
00157                    { "PCAP.DEVICE",   ARG_STRCPY, (void*)&_pktdrvrname },
00158                    { "PCAP.DUMPFILE", ARG_STRCPY, (void*)&dump_fname },
00159                    { "PCAP.TXRETRIES",ARG_ATOB,   (void*)&pkt_txretries },
00160                    { "PCAP.TXMODE",   ARG_FUNC,   (void*)&set_txmode },
00161                    { "PCAP.RXMODE",   ARG_ATOX_W, (void*)&_pkt_forced_rxmode },
00162                    { "PCAP.RXBUFS",   ARG_ATOI,   (void*)&pkt_num_rx_bufs },
00163                    { "PCAP.HIGHPRIO", ARG_ATOI,   (void*)&thr_realtime },
00164                    { NULL,            0,          NULL }
00165                  };
00166   const struct config_table *cfg_save          = watt_init_cfg;
00167   void (*init_save) (const char*, const char*) = usr_init;
00168   int    rc;
00169
00170   watt_init_cfg = pkt_init_cfg;
00171   usr_init      = NULL;    /* only pkt_init_cfg[] gets parsed */
00172   rc = tcp_config (NULL);
00173   usr_init      = init_save;
00174   watt_init_cfg = cfg_save;
00175   return (rc > 0);
00176 }
00177
00182 static BOOL find_adapter (char *aname, size_t size)
00183 {
00184 #if defined(USE_DYN_PACKET)
00185   ARGSUSED (aname);
00186   ARGSUSED (size);
00187   return (TRUE);
00188 #else
00189   const ADAPTER_INFO *ai;
00190   int   i;
00191
00192   for (ai = PacketGetAdInfo(); ai; ai = ai->Next)
00193   {
00194     for (i = 0; i < ai->NNetworkAddresses; i++)
00195     {
00196       const npf_if_addr        *if_addr = ai->NetworkAddresses + i;
00197       const struct sockaddr_in *ip_addr = (const struct sockaddr_in*) &if_addr->IPAddress;
00198
00199       if (ip_addr->sin_family == AF_INET)
00200       {
00201         StrLcpy (aname, ai->Name, size);
00202         return (TRUE);
00203       }
00204     }
00205   }
00206   return (FALSE);
00207 #endif
00208 }
00209
00213 int pkt_eth_init (mac_address *mac_addr)
00214 {
00215   struct {
00216     PACKET_OID_DATA oidData;
00217     char            descr[512];
00218   } oid;
00219   const ADAPTER *adapter = NULL;
00220   DWORD thread_id;
00221   BOOL  is_up;
00222
00223   if (_watt_is_win9x)
00224   {
00225     (*_printf) (_LANG("Win-NT or later reqired.\n"));
00226     _pkt_errno = PDERR_GEN_FAIL;
00227     return (WERR_ILL_DOSX);
00228   }
00229
00230   if (!_watt_no_config || _watt_user_config_fn)
00231      parse_config_pass_1();
00232
00233   _pkt_inf = calloc (sizeof(*_pkt_inf), 1);
00234   if (!_pkt_inf)
00235   {
00236     (*_printf) (_LANG("Failed to allocate WinPcap DRIVER data.\n"));
00237     _pkt_errno = PDERR_GEN_FAIL;
00238     return (WERR_NO_MEM);
00239   }
00240
00241   if (debug_on >= 2 && dump_fname[0])
00242      dump_file = fopen_excl (ExpandVarStr(dump_fname), "w+t");
00243
00244   if (!PacketInitModule(TRUE, dump_file))
00245   {
00246     (*_printf) (_LANG("Failed to initialise WinPcap.\n"));
00247     pkt_release();
00248     _pkt_errno = PDERR_NO_DRIVER;
00249     return (WERR_PKT_ERROR);
00250   }
00251
00252   if (!_pktdrvrname[0] &&
00253       !find_adapter(_pktdrvrname,sizeof(_pktdrvrname)))
00254   {
00255     (*_printf) (_LANG("No WinPcap driver found.\n"));
00256     _pkt_errno = PDERR_NO_DRIVER;
00257     return (WERR_NO_DRIVER);
00258   }
00259
00260   TCP_CONSOLE_MSG (2, ("device %s\n", _pktdrvrname));
00261
00262   adapter = PacketOpenAdapter (_pktdrvrname);
00263   if (!adapter)
00264   {
00265     if (debug_on > 0)
00266        (*_printf) (_LANG("PacketOpenAdapter (\"%s\") failed; %s\n"),
00267                    _pktdrvrname, win_strerror(GetLastError()));
00268     pkt_release();
00269     return (WERR_NO_DRIVER);
00270   }
00271
00272   _pkt_inf->adapter = adapter;
00273 #if defined(USE_DYN_PACKET)
00274   _pkt_inf->adapter_info = NULL;
00275 #else
00276   _pkt_inf->adapter_info = PacketFindAdInfo (_pktdrvrname);
00277 #endif
00278
00279   /* Query the NIC driver for the adapter description
00280    */
00281   memset (&oid, 0, sizeof(oid));
00282   oid.oidData.Oid    = OID_GEN_VENDOR_DESCRIPTION;
00283   oid.oidData.Length = sizeof(oid.descr);
00284
00285   if (PacketRequest (adapter, FALSE, &oid.oidData))
00286      StrLcpy (_pktdrvr_descr, (char*)oid.oidData.Data, sizeof(_pktdrvr_descr));
00287   else
00288   {
00289     (*_printf) (_LANG("PacketRequest() failed; %s\n"),
00290                 win_strerror(GetLastError()));
00291     pkt_release();
00292     return (WERR_PKT_ERROR);
00293   }
00294
00295   if (!get_interface_type(&_pktdevclass))
00296   {
00297     pkt_release();
00298     return (WERR_PKT_ERROR);
00299   }
00300
00301   if (get_connected_status(&is_up) && !is_up)
00302      (*_printf) (_LANG("Warning: the adapter %s is down\n"), _pktdrvrname);
00303
00304   switch (_pktdevclass)
00305   {
00306     case PDCLASS_TOKEN:
00307          _pkt_ip_ofs = sizeof(tok_Header);
00308          break;
00309     case PDCLASS_ETHER:
00310          _pkt_ip_ofs = sizeof(eth_Header);
00311          break;
00312     case PDCLASS_FDDI:
00313          _pkt_ip_ofs = sizeof(fddi_Header);
00314          break;
00315     case PDCLASS_ARCNET:
00316          _pkt_ip_ofs = ARC_HDRLEN;
00317          break;
00318     default:
00319          pkt_release();
00320          (*_printf) (_LANG("WinPcap-ERROR: Unsupported driver class %dh\n"),
00321                      _pktdevclass);
00322          _pkt_errno = PDERR_NO_CLASS;
00323          return (WERR_PKT_ERROR);
00324   }
00325
00326   if (!pkt_get_addr(mac_addr))  /* get our MAC address */
00327   {
00328     pkt_release();
00329     return (WERR_PKT_ERROR);
00330   }
00331
00332   pktq_init (&_pkt_inf->pkt_queue,
00333              sizeof(_pkt_inf->rx_buf[0]),   /* RX_SIZE */
00334              DIM(_pkt_inf->rx_buf),         /* RX_BUFS */
00335              (char*)&_pkt_inf->rx_buf);
00336
00337   _pkt_inf->npf_buf_size = RX_SIZE * pkt_num_rx_bufs;
00338   _pkt_inf->npf_buf = malloc (_pkt_inf->npf_buf_size);
00339   if (!_pkt_inf->npf_buf)
00340   {
00341     (*_printf) (_LANG("Failed to allocate %d byte Rx buffer.\n"),
00342                 _pkt_inf->npf_buf_size);
00343     pkt_release();
00344     _pkt_errno = PDERR_GEN_FAIL;
00345     return (WERR_NO_MEM);
00346   }
00347
00348   PacketSetMode (adapter, PACKET_MODE_CAPT);
00349   PacketSetBuff (adapter, _pkt_inf->npf_buf_size);
00350   PacketSetMinToCopy (adapter, ETH_MIN);
00351
00352   /* PacketReceivePacket() blocks until something is received
00353    */
00354   PacketSetReadTimeout ((ADAPTER*)adapter, 0);
00355
00356   /* Set Rx-mode forced via config.
00357    */
00358   if (_pkt_forced_rxmode != -1)
00359   {
00360     _pkt_forced_rxmode &= 0xFFFF;     /* clear bits not set via ARG_ATOX_W */
00361     if (_pkt_forced_rxmode == 0 ||    /* check illegal bit-values */
00362         (_pkt_forced_rxmode & 0x10) ||
00363         (_pkt_forced_rxmode & 0x40) ||
00364         (_pkt_forced_rxmode > 0x80))
00365      {
00366        TCP_CONSOLE_MSG (0, ("Illegal Rx-mode (0x%02X) specified\n",
00367                         _pkt_forced_rxmode));
00368        _pkt_forced_rxmode = -1;
00369      }
00370   }
00371
00372   if (pkt_get_rcv_mode())
00373      _pkt_rxmode0 = _pkt_rxmode;
00374
00375   if (_pkt_forced_rxmode != -1)
00376        pkt_set_rcv_mode (_pkt_forced_rxmode);
00377   else pkt_set_rcv_mode (RXMODE_DEFAULT);
00378
00379 #if 1
00380   _pkt_inf->recv_thread = CreateThread (NULL, 2048, pkt_recv_thread,
00381                                         NULL, 0, &thread_id);
00382 #else
00383   _pkt_inf->recv_thread = _beginthreadex (NULL, 2048, pkt_recv_thread,
00384                                           NULL, 0, &thread_id);
00385 #endif
00386
00387   if (!_pkt_inf->recv_thread)
00388   {
00389     (*_printf) (_LANG("Failed to create receiver thread; %s\n"),
00390                 win_strerror(GetLastError()));
00391     pkt_release();
00392     _pkt_errno = PDERR_GEN_FAIL;
00393     return (WERR_PKT_ERROR);
00394   }
00395
00396   if (thr_realtime)
00397      SetThreadPriority (_pkt_inf->recv_thread,
00398                         THREAD_PRIORITY_TIME_CRITICAL);
00399
00400   TCP_CONSOLE_MSG (2, ("capture thread-id %lu\n", thread_id));
00401
00402 #if defined(USE_DEBUG)
00403   if (debug_on >= 2)
00404   {
00405     (*_printf) ("link-details:\n");
00406     show_link_details();
00407   }
00408 #endif
00409   return (0);
00410 }
00411
00412 int pkt_release (void)
00413 {
00414   ADAPTER *adapter;
00415   DWORD    status = 1;
00416
00417   if (!_pkt_inf || _watt_fatal_error)
00418      return (0);
00419
00420   adapter = (ADAPTER*) _pkt_inf->adapter;
00421
00422   TCP_CONSOLE_MSG (2, ("pkt_release(): adapter %08lX\n", (DWORD)adapter));
00423
00424   if (adapter && adapter != INVALID_HANDLE_VALUE)
00425   {
00426     /* Don't close the adapter before telling the thread about it.
00427      */
00428     if (_pkt_inf->recv_thread)
00429     {
00430       FILETIME ctime, etime, ktime, utime;
00431       DWORD    err = 0;
00432
00433       _pkt_inf->stop_thread = TRUE;
00434       SetEvent (adapter->ReadEvent);
00435       Sleep (50);
00436
00437       GetExitCodeThread (_pkt_inf->recv_thread, &status);
00438       if (status == STILL_ACTIVE)
00439            TCP_CONSOLE_MSG (2, ("pkt_release(): killing thread.\n"));
00440       else TCP_CONSOLE_MSG (2, ("pkt_release(): thread exit code %lu.\n",
00441                             status));
00442
00443       if (!GetThreadTimes (_pkt_inf->recv_thread, &ctime, &etime, &ktime, &utime))
00444          err = GetLastError();
00445       TerminateThread (_pkt_inf->recv_thread, 1);
00446       CloseHandle (_pkt_inf->recv_thread);
00447
00448       if (err)
00449          TCP_CONSOLE_MSG (2, ("  GetThreadTime() %s, ", win_strerror(err)));
00450       TCP_CONSOLE_MSG (2, ("  kernel time %.6fs, user time %.6fs\n",
00451                        filetime_sec(&ktime), filetime_sec(&utime)));
00452     }
00453
00454     PacketCloseAdapter (adapter);
00455
00456     _pkt_inf->adapter = NULL;
00457   }
00458
00459   DO_FREE (_pkt_inf->npf_buf);
00460   DO_FREE (_pkt_inf);
00461
00462   PacketInitModule (FALSE, dump_file);
00463   if (dump_file)
00464      fclose (dump_file);
00465   dump_file = NULL;
00466   return (int) status;
00467 }
00468
00469 /*
00470  * Return the MAC address.
00471  */
00472 int pkt_get_addr (mac_address *eth)
00473 {
00474   mac_address mac;
00475
00476   if (get_perm_mac_address(&mac))
00477   {
00478     memcpy (eth, &mac, sizeof(*eth));
00479     return (1);
00480   }
00481   TCP_CONSOLE_MSG (2, ("Failed to get our MAC address; %s\n",
00482                    win_strerror(GetLastError())));
00483   return (0);
00484 }
00485
00486 int pkt_set_addr (const void *eth)
00487 {
00488   ARGSUSED (eth);
00489   return (0);
00490 }
00491
00492 /*
00493  * Check 'my_ip' against the IPv4 address(es) Winsock is using for
00494  * this adapter.
00495  */
00496 BOOL pkt_check_address (DWORD my_ip)
00497 {
00498 #if !defined(USE_DYN_PACKET)
00499   const ADAPTER_INFO *ai;
00500   int   i;
00501
00502   if (!_pkt_inf)
00503      return (TRUE);
00504
00505   ai = (const ADAPTER_INFO*) _pkt_inf->adapter_info;
00506
00507   for (i = 0; i < ai->NNetworkAddresses; i++)
00508   {
00509     const npf_if_addr        *if_addr = ai->NetworkAddresses + i;
00510     const struct sockaddr_in *ip_addr = (const struct sockaddr_in*) &if_addr->IPAddress;
00511
00512     if (ip_addr->sin_addr.s_addr == htonl(my_ip))
00513        return (FALSE);
00514   }
00515 #else
00516   ARGSUSED (my_ip);
00517 #endif
00518   return (TRUE);  /* Okay, no possible conflict */
00519 }
00520
00521
00522 int pkt_buf_wipe (void)
00523 {
00524   if (_pkt_inf)
00525      pktq_clear (&_pkt_inf->pkt_queue);
00526   return (1);
00527 }
00528
00529 int pkt_waiting (void)
00530 {
00531   if (_pkt_inf)
00532      return pktq_queued (&_pkt_inf->pkt_queue);
00533   return (-1);
00534 }
00535
00536 void pkt_free_pkt (const void *pkt)
00537 {
00538   struct pkt_ringbuf *q;
00539   const  char *q_tail;
00540   int    delta;
00541
00542   if (!_pkt_inf || !pkt)
00543      return;
00544
00545   q = &_pkt_inf->pkt_queue;
00546   pkt_drop_cnt = q->num_drop;
00547
00548   q_tail = (const char*)pkt - _pkt_ip_ofs - RX_ELEMENT_HEAD_SIZE;
00549   delta  = q_tail - pktq_out_buf (q);
00550   if (delta)
00551   {
00552     TCP_CONSOLE_MSG (0, ("%s: freeing illegal packet 0x%p, delta %d.\n",
00553                      __FILE__, pkt, delta));
00554     pktq_clear (q);
00555   }
00556   else
00557     pktq_inc_out (q);
00558 }
00559
00563 static void set_txmode (const char *value)
00564 {
00565   ARGSUSED (value);
00566 }
00567
00580 DWORD __stdcall pkt_recv_thread (void *arg)
00581 {
00582   int rc = 0;
00583
00584   while (1)
00585   {
00586     const  ADAPTER *adapter;
00587     const  BYTE *pkt, *pkt_end;
00588     size_t cap_len, hdr_len;
00589     int    total_len, chunk;
00590     PACKET npf_pkt;
00591
00592     if (!_pkt_inf || _pkt_inf->stop_thread)  /* signals closure */
00593     {
00594       rc = 1;
00595       break;
00596     }
00597
00598     adapter  = (const ADAPTER*) _pkt_inf->adapter;
00599     npf_pkt.Length = _pkt_inf->npf_buf_size;
00600     npf_pkt.Buffer = _pkt_inf->npf_buf;
00601
00602     if (!PacketReceivePacket(adapter, &npf_pkt, TRUE))
00603     {
00604       rc = 2;
00605       break;
00606     }
00607     total_len = npf_pkt.ulBytesReceived;
00608
00609     ENTER_CRIT();
00610
00611     for (pkt = npf_pkt.Buffer, pkt_end = (BYTE*)npf_pkt.Buffer + total_len, chunk = 1;
00612          pkt < pkt_end;
00613          pkt += Packet_WORDALIGN(cap_len+hdr_len), chunk++)
00614     {
00615       struct pkt_ringbuf    *q;
00616       struct pkt_rx_element *head;
00617       struct bpf_hdr        *bp;
00618
00619       q  = &_pkt_inf->pkt_queue;
00620       bp = (struct bpf_hdr*) pkt;
00621
00622       cap_len = bp->bh_caplen;
00623       hdr_len = bp->bh_hdrlen;
00624
00625       num_rx_bytes += bp->bh_datalen;
00626
00627       TCP_CONSOLE_MSG (2, ("pkt_recv_thread(): total_len %d, "
00628                            "chunk %d, cap_len %d, in-idx %d\n",
00629                        total_len, chunk, cap_len, q->in_index));
00630
00631       if (cap_len > ETH_MAX)
00632       {
00633         _pkt_inf->error = "Large size";
00634         STAT (macstats.num_too_large++);
00635       }
00636       else
00637       if (pktq_in_index(q) == q->out_index)  /* queue is full, drop it */
00638          q->num_drop++;
00639       else
00640       {
00641         int pad_len, buf_max;
00642
00643         head = (struct pkt_rx_element*) pktq_in_buf (q);
00644         memcpy (head->rx_buf, pkt + hdr_len, cap_len);
00645         head->tstamp_put = bp->bh_tstamp;
00646         head->rx_length  = cap_len;
00647
00648         /* zero-pad up to ETH_MAX (don't destroy marker at end)
00649          */
00650         buf_max = q->buf_size - RX_ELEMENT_HEAD_SIZE - 4;
00651         pad_len = min (ETH_MAX, buf_max - cap_len);
00652         if (pad_len > 0)
00653            memset (&head->rx_buf[cap_len], 0, pad_len);
00654         pktq_inc_in (q);
00655       }
00656     }
00657     LEAVE_CRIT();
00658   }
00659
00660   TCP_CONSOLE_MSG (2, ("pkt_recv_thread(): rc %d\n", rc));
00661   fflush (stdout);
00662   ARGSUSED (arg);
00663   thr_stopped = TRUE;
00664   return (rc);
00665 }
00666
00667 /*
00668  * Poll the tail of queue
00669  */
00670 struct pkt_rx_element *pkt_poll_recv (void)
00671 {
00672   struct pkt_ringbuf    *q;
00673   struct pkt_rx_element *rc = NULL;
00674   const char  *out;
00675   BOOL  empty;
00676
00677   if (!_pkt_inf)
00678      return (NULL);
00679
00680   ENTER_CRIT();
00681   q = &_pkt_inf->pkt_queue;
00682   out = pktq_out_buf (q);
00683   empty = (q->in_index == q->out_index);
00684   LEAVE_CRIT();
00685
00686   if (!empty)
00687   {
00688     rc = (struct pkt_rx_element*) out;
00689     gettimeofday (&rc->tstamp_get, NULL);
00690   }
00691   return (rc);
00692 }
00693
00694 /*
00695  * Our WinPcap send function.
00696  * Not sure if partial writes are possible with NPF. Retry if rc != length.
00697  */
00698 int pkt_send (const void *tx, int length)
00699 {
00700   const ADAPTER *adapter;
00701   PACKET pkt;
00702   int    tx_cnt, rc = 0;
00703
00704   ASSERT_PKT_INF (0);
00705
00706   adapter = (const ADAPTER*) _pkt_inf->adapter;
00707
00708   PROFILE_START ("pkt_send");
00709
00710   for (tx_cnt = 1 + pkt_txretries; tx_cnt > 0; tx_cnt--)
00711   {
00712     pkt.Buffer = (void*) tx;
00713     pkt.Length = length;
00714     if (PacketSendPacket (adapter, &pkt, TRUE))
00715     {
00716       rc = length;
00717       break;
00718     }
00719     STAT (macstats.num_tx_retry++);
00720   }
00721
00722   if (rc == length)
00723   {
00724     num_tx_pkt++;
00725     num_tx_bytes += length;
00726   }
00727   else
00728   {
00729     num_tx_errors++;  /* local copy */
00730     STAT (macstats.num_tx_err++);
00731   }
00732   PROFILE_STOP();
00733   return (rc);
00734 }
00735
00736 /*
00737  * Sets the receive mode of the interface.
00738  */
00739 int pkt_set_rcv_mode (int mode)
00740 {
00741   struct {
00742     PACKET_OID_DATA oidData;
00743     DWORD           filter;
00744   } oid;
00745   BOOL  rc;
00746   const ADAPTER *adapter;
00747
00748   if (!_pkt_inf)
00749      return (0);
00750
00751   adapter = (const ADAPTER*) _pkt_inf->adapter;
00752
00753   memset (&oid, 0, sizeof(oid));
00754   oid.oidData.Oid    = OID_GEN_CURRENT_PACKET_FILTER;
00755   oid.oidData.Length = sizeof(oid.filter);
00756   *(DWORD*)oid.oidData.Data = mode;
00757   rc = PacketRequest (adapter, TRUE, &oid.oidData);
00758   if (rc)
00759        _pkt_rxmode = mode;
00760   else _pkt_errno = GetLastError();
00761
00762   TCP_CONSOLE_MSG (2, ("pkt_set_rcv_mode(); mode 0x%02X, rc %d; %s\n",
00763                    mode, rc, !rc ? win_strerror(GetLastError()) : "okay"));
00764   return (rc);
00765 }
00766
00767 /*
00768  * Gets the receive mode of the interface.
00769  *  \retval !0 Okay  - _pkt_errno = 0, _pkt_rxmode and retval is current mode.
00770  *  \retval 0  Error - _pkt_errno = GetLastError().
00771  */
00772 int pkt_get_rcv_mode (void)
00773 {
00774   struct {
00775     PACKET_OID_DATA oidData;
00776     DWORD           filter;
00777   } oid;
00778   DWORD mode;
00779   BOOL  rc;
00780   const ADAPTER *adapter;
00781
00782   if (!_pkt_inf)
00783      return (0);
00784
00785   adapter = (const ADAPTER*) _pkt_inf->adapter;
00786
00787   memset (&oid, 0, sizeof(oid));
00788   oid.oidData.Oid    = OID_GEN_CURRENT_PACKET_FILTER;
00789   oid.oidData.Length = sizeof(oid.filter);
00790   rc = PacketRequest (adapter, FALSE, &oid.oidData);
00791   mode = *(DWORD*)oid.oidData.Data;
00792   if (rc)
00793        _pkt_rxmode = mode;
00794   else _pkt_errno = GetLastError();
00795   return (rc);
00796 }
00797
00798 /*
00799  * Return traffic statisistics since started (stats) and
00800  * total since adapter was opened.
00801  *
00802  * \note 'stats' only count traffic we received and transmitted.
00803  */
00804 int pkt_get_stats (struct PktStats *stats, struct PktStats *total)
00805 {
00806   const ADAPTER  *adapter;
00807   struct bpf_stat b_stat;
00808   struct {
00809     PACKET_OID_DATA oidData;
00810     DWORD           value;
00811   } oid;
00812   DWORD count[4];
00813
00814   if (!_pkt_inf)
00815      return (0);
00816
00817   adapter = (const ADAPTER*) _pkt_inf->adapter;
00818
00819   if (!PacketGetStatsEx(adapter,&b_stat))
00820      return (0);
00821
00822   memset (total, 0, sizeof(*total));  /* we don't know yet */
00823   memset (&count, 0, sizeof(count));
00824
00825   /*
00826    * Query: OID_GEN_RCV_OK, OID_GEN_RCV_ERROR
00827    *        OID_GEN_XMIT_OK, OID_GEN_XMIT_ERROR
00828    */
00829   memset (&oid, 0, sizeof(oid));
00830   oid.oidData.Oid    = OID_GEN_RCV_OK;
00831   oid.oidData.Length = sizeof(oid.value);
00832   if (!PacketRequest (adapter, FALSE, &oid.oidData))
00833      goto no_total;
00834   count[0] = *(DWORD*) &oid.oidData.Data;
00835
00836   memset (&oid, 0, sizeof(oid));
00837   oid.oidData.Oid    = OID_GEN_XMIT_OK;
00838   oid.oidData.Length = sizeof(oid.value);
00839   if (!PacketRequest (adapter, FALSE, &oid.oidData))
00840      goto no_total;
00841   count[1] = *(DWORD*) &oid.oidData.Data;
00842
00843   memset (&oid, 0, sizeof(oid));
00844   oid.oidData.Oid    = OID_GEN_RCV_ERROR;
00845   oid.oidData.Length = sizeof(oid.value);
00846   if (!PacketRequest (adapter, FALSE, &oid.oidData))
00847      goto no_total;
00848   count[2] = *(DWORD*) &oid.oidData.Data;
00849
00850   memset (&oid, 0, sizeof(oid));
00851   oid.oidData.Oid    = OID_GEN_XMIT_ERROR;
00852   oid.oidData.Length = sizeof(oid.value);
00853   if (!PacketRequest (adapter, FALSE, &oid.oidData))
00854      goto no_total;
00855   count[3] = *(DWORD*) &oid.oidData.Data;
00856
00857 no_total:
00858   total->in_packets  = count[0];
00859   total->out_packets = count[1];
00860   total->in_errors   = count[2];
00861   total->out_errors  = count[3];
00862
00863   stats->in_packets  = b_stat.bs_recv;
00864   stats->in_bytes    = num_tx_bytes;
00865   stats->out_packets = num_tx_pkt;
00866   stats->out_bytes   = num_tx_bytes;
00867   stats->in_errors   = 0UL;
00868   stats->out_errors  = num_tx_errors;
00869   stats->lost        = b_stat.bs_drop + b_stat.ps_ifdrop;
00870   return (1);
00871 }
00872
00873 DWORD pkt_dropped (void)
00874 {
00875   if (_pkt_inf)
00876      return (_pkt_inf->pkt_queue.num_drop);
00877   return (pkt_drop_cnt);    /* return last known value */
00878 }
00879
00880 int pkt_get_mtu (void)
00881 {
00882   DWORD MTU;
00883
00884   if (get_interface_mtu(&MTU))
00885      return (MTU);
00886   return (0);
00887 }
00888
00889 const char *pkt_strerror (int code)
00890 {
00891   ARGSUSED (code);
00892   return (NULL);
00893 }
00894
00895 #if defined(USE_MULTICAST)
00896 /*
00897  * Don't think we need to support this since we can use promiscous mode
00898  */
00899 int pkt_get_multicast_list (mac_address *listbuf, int *len)
00900 {
00901   _pkt_errno = PDERR_NO_MULTICAST;
00902   *len = 0;
00903   ARGSUSED (listbuf);
00904   ARGSUSED (len);
00905   return (0);
00906 }
00907
00908 int pkt_set_multicast_list (const void *listbuf, int len)
00909 {
00910   _pkt_errno = PDERR_NO_MULTICAST;
00911   ARGSUSED (listbuf);
00912   ARGSUSED (len);
00913   return (0);
00914 }
00915 #endif
00916
00917
00918 /*
00919  * Low-level NDIS/Mini-driver functions.
00920  */
00921 static BOOL get_perm_mac_address (void *mac)
00922 {
00923   struct {
00924     PACKET_OID_DATA oidData;
00925     mac_address     mac;
00926   } oid;
00927   const ADAPTER *adapter;
00928
00929   if (!_pkt_inf)
00930      return (FALSE);
00931
00932   adapter = (const ADAPTER*) _pkt_inf->adapter;
00933   memset (&oid, 0, sizeof(oid));
00934
00935   switch (_pktdevclass)
00936   {
00937     case PDCLASS_ETHER:
00938          oid.oidData.Oid = OID_802_3_PERMANENT_ADDRESS;
00939          break;
00940     case PDCLASS_TOKEN:
00941          oid.oidData.Oid = OID_802_5_PERMANENT_ADDRESS;
00942          break;
00943     case PDCLASS_FDDI:
00944          oid.oidData.Oid = OID_FDDI_LONG_PERMANENT_ADDRESS;
00945          break;
00946     case PDCLASS_ARCNET:
00947          oid.oidData.Oid = OID_ARCNET_PERMANENT_ADDRESS;
00948          break;
00949 #if 0
00950     case NdisMediumWan:
00951          oid.oidData.Oid = OID_WAN_PERMANENT_ADDRESS;
00952          break;
00953     case NdisMediumWirelessWan:
00954          oid.oidData.Oid = OID_WW_GEN_PERMANENT_ADDRESS;
00955          break;
00956 #endif
00957     default:
00958          return (FALSE);
00959   }
00960   oid.oidData.Length = sizeof(oid.mac);
00961
00962   if (!PacketRequest(adapter, FALSE, &oid.oidData))
00963      return (FALSE);
00964   memcpy (mac, &oid.oidData.Data, sizeof(mac_address));
00965   return (TRUE);
00966 }
00967
00968 static BOOL get_interface_mtu (DWORD *mtu)
00969 {
00970   struct {
00971     PACKET_OID_DATA oidData;
00972     DWORD           mtu;
00973   } oid;
00974   const ADAPTER *adapter;
00975
00976   if (!_pkt_inf)
00977      return (FALSE);
00978
00979   adapter = (const ADAPTER*) _pkt_inf->adapter;
00980
00981   memset (&oid, 0, sizeof(oid));
00982   oid.oidData.Oid    = OID_GEN_MAXIMUM_TOTAL_SIZE;
00983   oid.oidData.Length = sizeof(oid.mtu);
00984
00985   if (!PacketRequest(adapter, FALSE, &oid.oidData))
00986      return (FALSE);
00987   *mtu = *(DWORD*) &oid.oidData.Data;
00988   return (TRUE);
00989 }
00990
00991 static BOOL get_interface_type (WORD *type)
00992 {
00993   struct {
00994     PACKET_OID_DATA oidData;
00995     DWORD           link;
00996   } oid;
00997   const ADAPTER *adapter;
00998
00999   if (!_pkt_inf)
01000      return (FALSE);
01001
01002   adapter = (const ADAPTER*) _pkt_inf->adapter;
01003
01004   memset (&oid, 0, sizeof(oid));
01005   oid.oidData.Oid    = OID_GEN_MEDIA_IN_USE;
01006   oid.oidData.Length = sizeof(oid.link);
01007
01008   if (!PacketRequest(adapter, FALSE, &oid.oidData))
01009      return (FALSE);
01010
01011   *type = *(WORD*) &oid.oidData.Data;
01012   return (TRUE);
01013 }
01014
01015 #if defined(USE_DEBUG)
01016 static BOOL get_interface_speed (DWORD *speed)
01017 {
01018   struct {
01019     PACKET_OID_DATA oidData;
01020     DWORD           speed;
01021   } oid;
01022   const ADAPTER *adapter;
01023
01024   if (!_pkt_inf)
01025      return (FALSE);
01026
01027   adapter = (const ADAPTER*) _pkt_inf->adapter;
01028
01029   memset (&oid, 0, sizeof(oid));
01030   oid.oidData.Oid    = OID_GEN_LINK_SPEED;
01031   oid.oidData.Length = sizeof(oid.speed);
01032
01033   if (!PacketRequest(adapter, FALSE, &oid.oidData))
01034      return (FALSE);
01035
01036   *speed = (*(DWORD*)&oid.oidData.Data) / 10000;
01037   return (TRUE);
01038 }
01039
01040 static BOOL get_real_media (int *media)
01041 {
01042   struct {
01043     PACKET_OID_DATA oidData;
01044     DWORD           media;
01045   } oid;
01046   const ADAPTER *adapter;
01047
01048   if (!_pkt_inf)
01049      return (FALSE);
01050
01051   adapter = (const ADAPTER*) _pkt_inf->adapter;
01052   memset (&oid, 0, sizeof(oid));
01053   oid.oidData.Oid    = OID_GEN_PHYSICAL_MEDIUM;
01054   oid.oidData.Length = sizeof(oid.media);
01055
01056   if (!PacketRequest(adapter, FALSE, &oid.oidData))
01057      return (FALSE);
01058   *media = *(int*) &oid.oidData.Data;
01059   return (TRUE);
01060 }
01061 #endif
01062
01063 static BOOL get_connected_status (BOOL *is_up)
01064 {
01065   struct {
01066     PACKET_OID_DATA oidData;
01067     DWORD           connected;
01068   } oid;
01069   const ADAPTER *adapter;
01070
01071   if (!_pkt_inf)
01072      return (FALSE);
01073
01074   adapter = (const ADAPTER*) _pkt_inf->adapter;
01075
01076   memset (&oid, 0, sizeof(oid));
01077   oid.oidData.Oid    = OID_GEN_MEDIA_CONNECT_STATUS;
01078   oid.oidData.Length = sizeof(oid.connected);
01079
01080   if (!PacketRequest(adapter, FALSE, &oid.oidData))
01081      return (FALSE);
01082   *is_up = (*(DWORD*) &oid.oidData.Data == NdisMediaStateConnected);
01083   return (TRUE);
01084 }
01085
01086 #ifdef NOT_USED
01087 /*
01088  * NDIS has the annoying feature (?) of looping packets we send in
01089  * NDIS_PACKET_TYPE_ALL_LOCAL mode (the default?). Disable it, but
01090  * doesn't seem to have any effect yet. Maybe need to use a BPF filter?
01091  *
01092  * No need when using RXMODE_DEFAULT (9).
01093  */
01094 static BOOL ndis_set_loopback (BOOL enable)
01095 {
01096   struct {
01097     PACKET_OID_DATA oidData;
01098     DWORD  options;
01099   } oid;
01100   const ADAPTER *adapter;
01101   BOOL  rc;
01102   DWORD options;
01103   DWORD gen_oid = OID_GEN_MAC_OPTIONS;
01104   DWORD opt_bit = NDIS_MAC_OPTION_NO_LOOPBACK;
01105
01106   if (!_pkt_inf)
01107      return (FALSE);
01108
01109   adapter = (const ADAPTER*) _pkt_inf->adapter;
01110   memset (&oid, 0, sizeof(oid));
01111   oid.oidData.Oid    = gen_oid;
01112   oid.oidData.Length = sizeof(oid.options);
01113
01114   /* Get current MAC/protocol options
01115    */
01116   rc = PacketRequest (adapter, FALSE, &oid.oidData);
01117   options = *(DWORD*) &oid.oidData.Data;
01118
01119  TCP_CONSOLE_MSG (2, ("ndis_set_loopback(); rc %d, options 0x%02lX; %s\n",
01120                   rc, options, !rc ? win_strerror(GetLastError()) : "okay"));
01121   if (enable)
01122        options &= ~opt_bit;
01123   else options |= opt_bit;
01124
01125   /* Set it back
01126    */
01127   memset (&oid, 0, sizeof(oid));
01128   oid.oidData.Oid    = gen_oid;
01129   oid.oidData.Length = sizeof(oid.options);
01130   *(DWORD*) &oid.oidData.Data = options;
01131   rc = PacketRequest (adapter, TRUE, &oid.oidData);
01132
01133  TCP_CONSOLE_MSG (2, ("ndis_set_loopback(); rc %d; %s\n",
01134                   rc, !rc ? win_strerror(GetLastError()) : "okay"));
01135   return (rc);
01136 }
01137 #endif /* NOT_USED */
01138
01139
01140 /*
01141  * Return NDIS version as MSB.LSB.
01142  */
01143 int pkt_get_api_ver (DWORD *ver)
01144 {
01145   struct {
01146     PACKET_OID_DATA oidData;
01147     DWORD           version;
01148   } oid;
01149   BOOL  rc;
01150   const ADAPTER *adapter;
01151
01152   if (!_pkt_inf)
01153      return (0);
01154
01155   adapter = (const ADAPTER*) _pkt_inf->adapter;
01156   memset (&oid, 0, sizeof(oid));
01157   oid.oidData.Length = sizeof(oid.version);
01158   oid.oidData.Oid    = OID_GEN_DRIVER_VERSION;
01159
01160   rc = PacketRequest (adapter, FALSE, &oid.oidData);
01161   if (rc)
01162     *ver = *(WORD*) &oid.oidData.Data;  /* only 16-bit in version */
01163   return (rc);
01164 }
01165
01166 /*
01167  * Returns NPF.SYS version as major.minor.0.build (8 bits each).
01168  */
01169 int pkt_get_drvr_ver (DWORD *ver)
01170 {
01171   int major, minor, unused, build;
01172
01173   if (sscanf(PacketGetDriverVersion(), "%d,%d,%d,%d",
01174              &major, &minor, &unused, &build) != 4)
01175      return (0);
01176   *ver = ((major << 24) + (minor << 16) + build);
01177   return (1);
01178 }
01179
01180 /*
01181  * Show some adapter details.
01182  * The IP-address, netmask etc. are what Winsock uses. We ignore
01183  * them and use what WATTCP.CFG specifies.
01184  */
01185 static void show_link_details (void)
01186 {
01187 #if defined(USE_DEBUG)
01188   const ADAPTER_INFO *ai;
01189   int   i, real_media;
01190   BOOL  is_up;
01191   DWORD ver, MTU, speed;
01192   mac_address mac;
01193
01194   if (!_pkt_inf)
01195      return;
01196
01197   ai = (const ADAPTER_INFO*) _pkt_inf->adapter_info;
01198   if (!ai)
01199   {
01200     (*_printf) ("  not available\n");
01201     return;
01202   }
01203
01204   (*_printf) ("  %d network address%s:\n",
01205               ai->NNetworkAddresses, ai->NNetworkAddresses > 1 ? "es" : "");
01206   for (i = 0; i < ai->NNetworkAddresses; i++)
01207   {
01208     const npf_if_addr        *if_addr = ai->NetworkAddresses + i;
01209     const struct sockaddr_in *ip_addr = (const struct sockaddr_in*) &if_addr->IPAddress;
01210     const struct sockaddr_in *netmask = (const struct sockaddr_in*) &if_addr->SubnetMask;
01211     const struct sockaddr_in *brdcast = (const struct sockaddr_in*) &if_addr->Broadcast;
01212
01213     (*_printf) ("  IP-addr %s", inet_ntoa(ip_addr->sin_addr));
01214     (*_printf) (", netmask %s", inet_ntoa(netmask->sin_addr));
01215     (*_printf) (", broadcast %s\n", inet_ntoa(brdcast->sin_addr));
01216   }
01217   if (ai->NNetworkAddresses <= 0)
01218      (*_printf) ("\n");
01219
01220   if (get_perm_mac_address(&mac))
01221      (*_printf) ("  MAC-addr %02X:%02X:%02X:%02X:%02X:%02X, ",
01222                  mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
01223
01224   if (get_interface_mtu(&MTU))
01225      (*_printf) ("MTU %lu, ", MTU);
01226
01227   (*_printf) ("link-type %s, ",
01228               list_lookup(_pktdevclass, logical_media, DIM(logical_media)));
01229
01230   if (get_real_media(&real_media))
01231      (*_printf) (" over %s, ", list_lookup(real_media, phys_media, DIM(phys_media)));
01232
01233   if (get_connected_status(&is_up))
01234      (*_printf) ("%s, ", is_up ? "UP" : "DOWN");
01235
01236   if (get_interface_speed(&speed))
01237      (*_printf) ("%luMb/s, ", speed);
01238
01239   if (pkt_get_api_ver(&ver))
01240      (*_printf) ("NDIS %d.%d", hiBYTE(ver), loBYTE(ver));
01241   (*_printf) ("\n");
01242 #endif
01243 }
01244 #endif  /* WIN32 */
01245
Generated on Wed Jan 25 15:42:40 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/WINPCAP.H Source File

SRC/WINPCAP.H

Go to the documentation of this file.
00001
00005 #ifndef _w32_WINPCAP_H
00006 #define _w32_WINPCAP_H
00007
00008 #if !defined(_w32_PCPKT_H)
00009 #error Include this file inside or after pcpkt.h only.
00010 #endif
00011
00017 #define PDERR_GEN_FAIL      -1
00018 #define PDERR_NO_DRIVER     -2
00019 #define PDERR_NO_CLASS      -3
00020 #define PDERR_NO_MULTICAST  -4
00021 #define PDERR_NO_SPACE      -5
00022
00025 #define PDCLASS_ETHER     0
00026 #define PDCLASS_TOKEN     1
00027 #define PDCLASS_FDDI      3
00028 #define PDCLASS_ARCNET    6
00029 #define PDCLASS_SLIP      0xFF01
00030 #define PDCLASS_AX25      0xFF02
00031 #define PDCLASS_TOKEN_RIF 0xFF03
00032 #define PDCLASS_PPP       0xFF04
00033 #define PDCLASS_UNKNOWN   0xFFFF
00034
00035 enum ReceiveModes {
00036      RXMODE_OFF        = 0x00,
00037      RXMODE_DIRECT     = 0x01,
00038      RXMODE_MULTICAST1 = 0x02,
00039      RXMODE_MULTICAST2 = 0x04,
00040      RXMODE_BROADCAST  = 0x08,
00041      RXMODE_PROMISCOUS = 0x20,
00042      RXMODE_ALL_LOCAL  = 0x80
00043      /* we have no use for the other NDIS_PACKET_TYPE defs */
00044    };
00045
00046 /* NPF defaults to mode 0 after openening adapter.
00047  */
00048 #define RXMODE_DEFAULT  (RXMODE_DIRECT | RXMODE_BROADCAST)
00049
00050 W32_FUNC int  pkt_eth_init      (mac_address *eth);
00051 W32_FUNC int  pkt_release       (void);
00052 W32_FUNC int  pkt_reset_handle  (void *handle);
00053 W32_FUNC int  pkt_send          (const void *tx, int length);
00054 W32_FUNC int  pkt_buf_wipe      (void);
00055 W32_FUNC void pkt_free_pkt      (const void *pkt);
00056 W32_FUNC int  pkt_waiting       (void);
00057 W32_FUNC int  pkt_set_addr      (const void *eth);
00058 W32_FUNC int  pkt_get_addr      (mac_address *eth);
00059 W32_FUNC int  pkt_get_mtu       (void);
00060 W32_FUNC int  pkt_get_drvr_ver  (DWORD *ver);
00061 W32_FUNC int  pkt_get_api_ver   (DWORD *ver);
00062 W32_FUNC int  pkt_set_rcv_mode  (int mode);
00063 W32_FUNC int  pkt_get_rcv_mode  (void);
00064 W32_FUNC BOOL pkt_check_address (DWORD my_ip);
00065
00066 extern struct pkt_rx_element *pkt_poll_recv (void);
00067
00068 #if defined(USE_MULTICAST)
00069   extern int pkt_get_multicast_list (mac_address *listbuf, int *len);
00070   extern int pkt_set_multicast_list (const void *listbuf, int len);
00071 #endif
00072
00073 W32_FUNC int pkt_get_stats (struct PktStats *stats, struct PktStats *total);
00074
00079 struct pkt_info {
00080        const void   *adapter;            /* opaque ADAPTER object */
00081        const void   *adapter_info;       /* opaque ADAPTER_INFO object */
00082        void         *npf_buf;            /* buffer for ReadFile() */
00083        int           npf_buf_size;       /* size of above buffer */
00084        HANDLE        recv_thread;        /* thread for capturing */
00085        WORD          pkt_ip_ofs;         /* store length of MAC-header */
00086        WORD          pkt_type_ofs;       /* offset to MAC-type */
00087        volatile BOOL stop_thread;        /* signal thread to stop */
00088        volatile BOOL thread_stopped;     /* did it stop gracefully? */
00089        const char   *error;              /* Last error (NULL if none) */
00090        struct pkt_ringbuf    pkt_queue;  /* Ring-struct for enqueueing */
00091        struct pkt_rx_element rx_buf [RX_BUFS]; /* the receive buffer */
00092      };
00093
00094 W32_DATA char _pktdrvr_descr[];
00095
00096 W32_DATA struct pkt_info *_pkt_inf;
00097
00098 #endif
00099
Generated on Wed Jan 25 15:42:40 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/X32VM.C Source File

SRC/X32VM.C

Go to the documentation of this file.
00001
00011 #include <stdio.h>
00012 #include <stdlib.h>
00013 #include <string.h>
00014
00015 #include "wattcp.h"
00016 #include "printk.h"
00017 #include "strings.h"
00018 #include "misc.h"
00019 #include "cpumodel.h"
00020 #include "x32vm.h"
00021
00022 #if (DOSX & X32VM)   /* rest of file */
00023
00024 #define MAX_WRAPPERS        32
00025 #define MARKER              0xDEADBEEF
00026 #define SEG_OFS_TO_LIN(s,o) ((DWORD)_x386_zero_base_ptr +  \
00027                              (DWORD)(o) + ((DWORD)(s) << 4))
00028
00029 typedef struct RMCB_record {
00030         SWI_REGS   rm_reg;
00031         REALPTR    dos_real;
00032         REALPTR    dos_para_addr;
00033         UINT       stack_size;
00034         UINT      *stack_bottom;
00035         UINT      *stack_top;
00036         pmodeHook  callback;
00037         DWORD      marker;
00038       } RMCB_record;
00039
00040 typedef enum  {
00041         RETF = 0xCB,   /* far return */
00042         IRET = 0xCF    /* interrupt return */
00043       } ReturnType;
00044
00045 static char   num_wrappers = 0;
00046 static DWORD  exc_app_start = 4096;
00047 static struct RMCB_record rmcb [MAX_WRAPPERS];
00048
00049 #if defined(DMC386)
00050
00051 static void __far PmodeGlue (int taskIndex);
00052 static void PmGlueEnd  (void);
00053
00054 void _dx_rmiv_get (int int_no, REALPTR *handler)
00055 {
00056   __asm {
00057     mov eax, 2503h
00058     mov ecx, int_no
00059     int 21h
00060     mov eax, handler
00061     mov [eax], ebx
00062   }
00063 }
00064
00065 void _dx_rmiv_set (int int_no, REALPTR handler)
00066 {
00067   __asm {
00068     push ebx
00069     mov eax, 2505h
00070     mov ebx, handler
00071     mov ecx, int_no
00072     int 21h
00073     pop ebx
00074   }
00075 }
00076
00077 void _dx_pmiv_get  (int int_no, FARPTR *handler)
00078 {
00079   __asm {
00080     push es
00081     push ebx
00082     mov eax, 2502h
00083     mov ecx, int_no
00084     int 21h
00085     mov eax, handler
00086     mov [eax], ebx
00087     mov [eax+4], es
00088     pop ebx
00089     pop es
00090   }
00091 }
00092
00093 void _dx_apmiv_set (int int_no, FARPTR handler)
00094 {
00095   __asm {
00096     push ds
00097     mov edx, dword ptr handler[0]
00098     mov ax, word ptr handler[2]
00099     mov ds, ax
00100     mov eax, 2506h
00101     mov ecx, int_no
00102     int 21h
00103     pop ds
00104   }
00105 }
00106
00107 void _dx_real_int (int int_no, SWI_REGS *regs)
00108 {
00109   RMI_BLK rmi;
00110
00111   __asm {
00112     push ebx
00113     push esi
00114     push edi
00115     mov eax, int_no
00116     mov rmi.inum, ax              /* rmi.inum = int_no */
00117
00118     mov eax, regs
00119     mov cx, word ptr [eax].r_ds
00120     mov rmi.ds_reg, cx            /* rmi.ds_reg = regs->r_ds */
00121
00122     mov cx, word ptr [eax].r_es
00123     mov rmi.es_reg, cx            /* rmi.es_reg = regs->r_es */
00124
00125     mov ecx, [eax].r_ax
00126     mov rmi.eax_reg, ecx          /* rmi.eax_reg = regs->r_ax */
00127
00128     mov ecx, [eax].r_dx
00129     mov rmi.edx_reg, ecx          /* rmi.edx_reg = regs->r_dx */
00130
00131     mov ebx, [eax].r_bx
00132     mov ecx, [eax].r_cx
00133     mov edi, [eax].r_di
00134     mov esi, [eax].r_si
00135     mov eax, 2511h
00136     lea edx, rmi
00137     push ebp
00138     int 21h                       /* X32VM function 2511h */
00139     pop ebp
00140
00141     push eax
00142     mov eax, [regs]
00143     pushfd
00144     pop [eax].r_flags
00145     mov [eax].r_bx, ebx
00146     mov [eax].r_cx, ecx
00147     mov [eax].r_di, edi
00148     mov [eax].r_si, esi
00149     pop [eax].r_ax
00150     pop edi
00151     pop esi
00152     pop ebx
00153   }
00154   regs->r_ds = rmi.ds_reg;
00155   regs->r_es = rmi.es_reg;
00156   regs->r_dx = rmi.edx_reg;
00157 }
00158
00159 /*
00160  * !! Doesn't work yet (only needed in pcintr.c which isn't tested).
00161  */
00162 int _dx_call_real (REALPTR proc, RMC_BLK *rm_reg, DWORD count, ...)
00163 {
00164   __asm {
00165     push esi
00166     push edi
00167     push ebx
00168     mov  eax, 250Eh
00169     mov  ebx, proc
00170     mov  ecx, count
00171     int  21h
00172     pop  ebx
00173     pop  edi
00174     pop  esi
00175     jc fail
00176   }
00177   ARGSUSED (rm_reg);
00178   return (1);
00179 fail:
00180   return (0);
00181 }
00182
00183 void _dx_rmlink_get (REALPTR *cback, REALPTR *rm_cbuf,
00184                      DWORD *rm_cbuf_size, void _far **pm_cbuf)
00185 {
00186   __asm {
00187     push es
00188     push esi
00189     push ebx
00190     mov ax, 250Dh
00191     int 21h
00192     mov esi, [cback]
00193     mov [esi], eax
00194     mov esi, [rm_cbuf]
00195     mov [esi], ebx
00196     mov esi, [rm_cbuf_size]
00197     mov [esi], ecx
00198     mov ebx, [pm_cbuf]
00199     mov [ebx], edx
00200     mov [ebx+4], es
00201     pop ebx
00202     pop esi
00203     pop es
00204   }
00205 }
00206
00207 /*
00208  * A simplified version of Pharlap's 2537h function.
00209  *  - Allocate conventional memory above DOS data buffer.
00210  */
00211 int _dx_real_above (int para_count, WORD *para, WORD *largest)
00212 {
00213   REALPTR rp = _x32_real_alloc (16*para_count);
00214
00215   if (largest)
00216      *largest = 0;
00217   if (!rp)
00218      return (-1);
00219   *para = RP_SEG (rp);
00220   return (0);
00221 }
00222
00223 int _dx_real_free (WORD seg)
00224 {
00225   _x32_real_free (seg << 16);
00226   return (0);
00227 }
00228
00229 /*
00230  * A simplified version of Pharlap's 25C0h function.
00231  *  - Allocate conventional memory.
00232  */
00233 int _dx_real_alloc (int para_count, WORD *para, WORD *largest)
00234 {
00235   WORD seg = _x32_real_alloc (16*para_count);
00236
00237   if (!seg)
00238      return (-1);
00239   *para = seg;
00240   *largest = 0;
00241   return (0);
00242 }
00243
00244 #elif defined(WATCOM386)
00245
00246 extern void __far PmodeGlue (int task_index);
00247 extern void PmGlueEnd  (void);
00248
00250 #endif
00251
00252 int _dx_lock_pgs (const void _far *addr, int len)
00253 {
00254   return _x386_memlock ((void _far*)addr, len);
00255 }
00256
00257 int _dx_lock_pgsn (const void *addr, int len) /* addr must not be on stack */
00258 {
00259   return _x386_memlock (MK_FP(MY_DS(),addr), len);
00260 }
00261
00262 int _dx_ulock_pgsn (const void *addr, int len)
00263 {
00264   return _x386_memunlock (MK_FP(MY_DS(),addr), len);
00265 }
00266
00267 void ReadRealMem (void *buf, REALPTR rp, unsigned len)
00268 {
00269   const BYTE *src = (const BYTE*) SEG_OFS_TO_LIN (RP_SEG(rp), RP_OFF(rp));
00270   memcpy (buf, src, len);
00271 }
00272
00273 void WriteRealMem (REALPTR rp, const void *src, int len)
00274 {
00275   BYTE *dest = (BYTE*) SEG_OFS_TO_LIN (RP_SEG(rp), RP_OFF(rp));
00276   memcpy (dest, src, len);
00277 }
00278
00279 void FillRealMem (REALPTR rp, char val, int len)
00280 {
00281   BYTE *dest = (BYTE*) SEG_OFS_TO_LIN (RP_SEG(rp), RP_OFF(rp));
00282   memset (dest, val, len);
00283 }
00284
00285 void PokeRealWord (REALPTR rp, WORD val)
00286 {
00287   WORD *dest = (WORD*) SEG_OFS_TO_LIN (RP_SEG(rp), RP_OFF(rp));
00288   *dest = val;
00289 }
00290
00291 #ifdef __SW_3R
00292 #error !? Cannot use this with reg-calls.
00293 #endif
00294
00295 void stack_rewind (DWORD start, DWORD base)
00296 {
00297   int    loop    = 10;            /* print max 10 stack frames  */
00298   DWORD  eip     = start;
00299   DWORD *context = (DWORD*) base; /* EBP increases as we rewind */
00300   DWORD  limit   = get_cs_limit();
00301
00302   _printk ("Stack trace:\r\n");
00303
00304   while (context >= (DWORD*)base && ((DWORD)context & 3) == 0 && --loop)
00305   {
00306     DWORD *next;
00307
00308     if ((DWORD)context >= limit - 4 || eip >= limit ||
00309         (DWORD)context <= exc_app_start || eip <= exc_app_start)
00310        break;
00311
00312     _printk ("  %08X ", eip);
00313
00314     next = (DWORD*)*context;          /* get ESP stack value from context */
00315
00316     /* Compute number of args to display
00317      */
00318     if (next == NULL ||               /* we're rewound back to CRT */
00319         next <= (DWORD*)exc_app_start)
00320        _printk ("( *** )");
00321
00322     else
00323     {
00324       DWORD *argv;
00325       DWORD  argc = next - context - 2;
00326
00327       argc = (argc > 5) ? 5 : argc;
00328       _printk ("(");
00329
00330       argv = context + 2; /* Args start after saved EBP and return address */
00331       while (argc--)
00332       {
00333         if (argc == 0)
00334              _printk ("%04X)\r\n", *argv++);
00335         else _printk ("%04X ",     *argv++);
00336       }
00337     }
00338     eip     = *(context+1);  /* get next return address */
00339     context = next;
00340   }
00341   _printk ("\r\n");
00342 }
00343
00344
00345 /*
00346  * Take a seg-x:ofs REALPTR and return a normalized seg-y:0 REALPTR
00347  */
00348 static REALPTR normalize (REALPTR rp)
00349 {
00350   WORD seg = RP_SEG (rp);
00351   WORD ofs = RP_OFF (rp);
00352   seg += (ofs >> 4);
00353   if (ofs & 0xF)
00354      seg++;
00355   RP_SET (rp, 0, seg);
00356   return (rp);
00357 }
00358
00359 static REALPTR _dx_alloc_rmode_wrapper (pmodeHook pmHook,
00360                                         int len, int stack_size,
00361                                         ReturnType returnType)
00362 {
00363   #define DOFS  0x22  /* offset of data section (tiny model)   */
00364   #define DSIZE 12    /* sizeof data section at wrapper end    */
00365
00366   static BYTE rm_wrapper[] =
00367   {
00368     0x06,                     /* 00    push es                         */
00369     0x1E,                     /* 01    push ds                         */
00370     0x0E,                     /* 02    push cs                         */
00371     0x1F,                     /* 03    pop  ds               ; DS = CS */
00372     0x66,0x60,                /* 04    pushad                          */
00373     0x66,0xFF,0x36,DOFS+8,0,  /* 06    push dword ptr task_ptr         */
00374     0x66,0x6A,0,              /* 0B    push dword ptr 0      ; use default selectors */
00375     0x6A,0,                   /* 0E    push word ptr 0       ;                    */
00376     0x66,0xFF,0x36,DOFS,0,    /* 10    push dword ptr prot_glue                   */
00377     0xFF,0x1E,DOFS+4,0,       /* 15    call r2p_addr                              */
00378     0x83,0xC4,14,             /* 19    add  sp,14            ; discard used stack */
00379     0x66,0x61,                /* 1C    popad          */
00380     0x1F,                     /* 1E    pop  ds        */
00381     0x07,                     /* 1F    pop  es        */
00382     0xCB,                     /* 20    retf           */
00383     0x90,                     /* 21    nop            */
00384     0,0,0,0,                  /* 22+0  prot_glue dd ? */
00385     0,0,0,0,                  /* 22+4  r2p_addr  dd ? */
00386     0,0,0,0                   /* 22+8  task_ptr  dd ? */
00387   };
00388
00389   BYTE _far *fp_wrapper;
00390   UINT      *stack, i;
00391   REALPTR    dos_real;        /* allocated DOS memory */
00392   REALPTR    r2p_addr;        /* address of real to pmode switch */
00393   REALPTR    dos_tb_real;     /* rmode-address of transfer buffer */
00394   void _far *dos_tb_addr;     /* ditto for pmode */
00395   DWORD      dos_tb_size;     /* size of transfer buffer */
00396
00397   WATT_ASSERT (sizeof(rm_wrapper) == DOFS+DSIZE);
00398
00399   if (!pmHook || num_wrappers == MAX_WRAPPERS)
00400      return (0);
00401
00402   stack_size += sizeof(UINT) + 3;   /* add one for marker and round up */
00403   stack_size &= ~3;
00404   stack = malloc (stack_size);
00405   if (!stack)
00406      return (0);
00407
00408   len += sizeof(rm_wrapper) + 16;
00409   dos_real = _x32_real_alloc (len);
00410   if (!dos_real)
00411   {
00412     free (stack);
00413     return (0);
00414   }
00415
00416   _dx_rmlink_get (&r2p_addr, &dos_tb_real, &dos_tb_size, &dos_tb_addr);
00417
00418   for (i = 0; i < MAX_WRAPPERS; i++)
00419       if (!rmcb[i].dos_real)
00420          break;
00421
00422   *(DWORD*) (rm_wrapper+DOFS+0) = (DWORD)&PmodeGlue;  /* pmode helper */
00423   *(DWORD*) (rm_wrapper+DOFS+4) = r2p_addr;           /* rm->pm addr */
00424   *(DWORD*) (rm_wrapper+DOFS+8) = (DWORD)(rmcb + i);  /* task_ptr */
00425   rm_wrapper [0x20] = returnType;                     /* RETF or IRET */
00426
00427   /* lock pages used by callback
00428    */
00429   fp_wrapper = MK_FP (_x32_zero_base_selector, RP_SEG(dos_real) << 4);
00430   _dx_lock_pgs  (fp_wrapper, len);
00431   _dx_lock_pgsn ((void*)&PmodeGlue, (UINT)&PmGlueEnd - (UINT)&PmodeGlue);
00432   _dx_lock_pgsn ((void*)stack, stack_size);
00433
00434   rmcb [i].dos_real      = dos_real;
00435   rmcb [i].callback      = pmHook;
00436   rmcb [i].stack_bottom  = stack;
00437   rmcb [i].stack_size    = stack_size;
00438   rmcb [i].stack_top     = stack + stack_size/sizeof(UINT) - sizeof(UINT);
00439   rmcb [i].stack_top[1]  = MARKER;
00440   rmcb [i].marker        = MARKER;
00441   rmcb [i].dos_para_addr = normalize (dos_real);
00442   WriteRealMem (rmcb[i].dos_para_addr, &rm_wrapper, sizeof(rm_wrapper));
00443
00444 #if 0
00445   printf ("dos_real %08lX, r2p-addr %08lX, stack %08X\n",
00446           dos_real, r2p_addr, stack);
00447 #endif
00448
00449   num_wrappers++;
00450   return (rmcb[i].dos_para_addr);
00451 }
00452
00453 void _dx_free_rmode_wrapper (REALPTR dos_addr)
00454 {
00455   int i;
00456
00457   for (i = 0; i < MAX_WRAPPERS; i++)
00458   {
00459     struct RMCB_record *tr = rmcb + i;
00460
00461     if (!rmcb[i].dos_real || rmcb[i].dos_para_addr != dos_addr)
00462        continue;
00463
00464     if (tr->marker == MARKER)
00465        _x32_real_free (tr->dos_real);
00466
00467     if (tr->stack_top[1] == MARKER)
00468        free (tr->stack_bottom);
00469     memset (tr, 0, sizeof(*tr));
00470   }
00471 }
00472
00473 REALPTR _dx_alloc_rmode_wrapper_retf (pmodeHook pmHook, rmodeHook rmHook,
00474                                       int len, int stack_size)
00475 {
00476   ARGSUSED (rmHook);
00477   return _dx_alloc_rmode_wrapper (pmHook, len, stack_size, RETF);
00478 }
00479
00480 REALPTR _dx_alloc_rmode_wrapper_iret (pmodeHook pmHook, int stack_size)
00481 {
00482   return _dx_alloc_rmode_wrapper (pmHook, 0, stack_size, IRET);
00483 }
00484
00485 #if defined(DMC386)
00486
00487 static void __far PmodeGlue (struct RMCB_record *task_ptr)
00488 {
00489 /*
00490  * We need an assembly language "glue" routine on the protected mode side
00491  * to deal with several things:
00492  *   1.  It gets called with a FAR procedure call.
00493  *   2.  Copy all real-mode registers into the 'rm_reg' structure of the
00494  *       correct task-index.
00495  *   3.  Switch back to a stack in the data segment.
00496  *   4.  Call the HLL prot-mode callback with '&rm_reg' on stack.
00497  *   5.  Switch back to the stack DOSX has allocated for us.
00498  *   6.  Copy 'rm_reg' back onto the stack.
00499  *
00500  * Doesn't store ESP/EBP/FS/GS to SWI_REGS (not needed in Watt-32)
00501  */
00502
00503   __asm {
00504        mov ebx, task_ptr
00505        pushfd
00506        push gs
00507        push fs
00508
00509 /*
00510  * fill the 'rm_reg' struct based on the "pushad" instruction and the
00511  * "push ds/es" of the wrapper. Registers that haven't changed are
00512  * stored as-is.
00513  *
00514  * in wrapper:   PUSH ES                  */   #define REG_ES  [ebp+50]
00515 /*               PUSH DS                  */   #define REG_DS  [ebp+48]
00516 /*   (PUSHAD)    PUSH EAX                 */   #define REG_EAX [ebp+44]
00517 /*               PUSH ECX                 */   #define REG_ECX [ebp+40]
00518 /*               PUSH EDX                 */   #define REG_EDX [ebp+36]
00519 /*               PUSH EBX                 */   #define REG_EBX [ebp+32]
00520 /*               PUSH ESP                 */   #define REG_ESP [ebp+28]
00521 /*               PUSH EBP                 */   #define REG_EBP [ebp+24]
00522 /*               PUSH ESI                 */   #define REG_ESI [ebp+20]
00523 /*               PUSH EDI                 */   #define REG_EDI [ebp+16]
00524 /*                                        */
00525 /*               PUSH dword ptr task_ptr  */
00526 /*               PUSH dword ptr 0         */
00527 /*               PUSH word  ptr 0         */
00528 /*               PUSH dword ptr prot_glue */
00529
00530        mov [ebx].r_ax, eax
00531        mov [ebx].r_cx, ecx
00532        mov [ebx].r_dx, edx
00533        mov [ebx].r_si, esi
00534        mov [ebx].r_di, edi
00535
00536 #if 0  /* test */
00537        movzx eax, word ptr REG_DS
00538        push  eax
00539        call  dhex4int        /* print DS */
00540        add   esp, 4
00541
00542        movzx eax, word ptr REG_ES
00543        push  eax
00544        call  dhex4int        /* print ES */
00545        add   esp, 4
00546
00547        mov   ax, ss
00548        movzx eax, ax
00549        push  eax
00550        call  dhex4int        /* print SS */
00551        add   esp, 4
00552 #endif
00553
00554        pushfd
00555        pop eax
00556        mov [ebx].r_flags, eax
00557
00558        mov eax, REG_EBX
00559        mov [ebx].r_bx, eax
00560
00561        mov eax, REG_DS
00562        mov [ebx].r_ds, ax
00563
00564        mov eax, REG_ES
00565        mov [ebx].r_es, ax
00566
00567        mov  eax, [ebx].stack_bottom
00568        push _x386_stacklow
00569        mov  _x386_stacklow, eax  /* set new stack-low value */
00570
00571        mov  dx, ss
00572        mov  esi, esp             /* DX:ESI = current SS:ESP */
00573        mov  ax, ds
00574        mov  ss, ax
00575        mov  esp, [ebx].stack_top /* new SS:ESP = DS:top-of-task-stack */
00576
00577        push edx                  /* save old stack pointer on top */
00578        push esi                  /* of new stack */
00579
00580        push ebx                  /* because rm_reg is first in the structure */
00581        cld                       /* C code need direction flag off */
00582        call [ebx].callback       /* call the C handler function */
00583        lss  esp, [esp+4]         /* switch back to original stack */
00584        pop  _x386_stacklow
00585
00586 /* fill stack with the rm_reg struct based on the "popad" instruction
00587  * and the "pop ds/es" of the wrapper.
00588  */
00589        mov ax, [ebx].r_es
00590        mov REG_ES, ax
00591
00592        mov ax, [ebx].r_ds
00593        mov REG_DS, ax
00594
00595        mov eax, [ebx].r_ax
00596        mov REG_EAX, eax
00597
00598        mov eax, [ebx].r_cx
00599        mov REG_ECX, eax
00600
00601        mov eax, [ebx].r_dx
00602        mov REG_EDX, eax
00603
00604        mov eax, [ebx].r_bx
00605        mov REG_EBX, eax
00606
00607        mov eax, [ebx].r_si
00608        mov REG_ESI, eax
00609
00610        mov eax, [ebx].r_di
00611        mov REG_EDI, eax
00612
00613        pop fs
00614        pop gs
00615        popfd
00616   }
00617 }
00618
00619 static void PmGlueEnd (void)  /* end of area to lock */
00620 {
00621 }
00622 #endif  /* DMC386 */
00623 #endif  /* DOSX & X32VM */
00624
Generated on Wed Jan 25 15:42:40 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: SRC/X32VM.H Source File

SRC/X32VM.H

Go to the documentation of this file.
00001
00003 #ifndef _w32_X32VM_H
00004 #define _w32_X32VM_H
00005
00006 #if (DOSX & X32VM)   /* FlashTek's X32 extender */
00007
00008 #undef  REALPTR
00009 #define REALPTR             DWORD  /* segment in upper 16 bits */
00010 #define RP_SET(rp,ofs,seg)  (rp = ((DWORD)(seg) << 16) + (ofs))
00011 #define RP_OFF(rp)          (WORD)((DWORD)(rp) & 0xFFFF)
00012 #define RP_SEG(rp)          (WORD)((DWORD)(rp) >> 16)
00013
00014 #include <sys/packon.h>
00015
00016 typedef struct SWI_REGS {
00017         DWORD  r_ax;
00018         DWORD  r_bx;
00019         DWORD  r_cx;
00020         DWORD  r_dx;
00021         DWORD  r_si;
00022         DWORD  r_di;
00023         WORD   r_ds;
00024         WORD   r_es;
00025         WORD   r_fs;
00026         WORD   r_gs;
00027         DWORD  r_flags;
00028       } SWI_REGS;
00029
00030 typedef struct RMC_BLK {
00031         WORD   ds;
00032         WORD   es;
00033         WORD   fs;
00034         WORD   gs;
00035         DWORD  eax;
00036         DWORD  ebx;
00037         DWORD  ecx;
00038         DWORD  edx;
00039       } RMC_BLK;
00040
00041 typedef struct {
00042         WORD  inum;
00043         WORD  ds_reg, es_reg;
00044         WORD  fs_reg, gs_reg;
00045         DWORD eax_reg, edx_reg;
00046       } RMI_BLK;
00047
00048 typedef void (*pmodeHook) (SWI_REGS *);
00049 typedef void (*rmodeHook) (void);
00050
00051 #include <sys/packoff.h>
00052
00053 #define _dx_rmiv_get    NAMESPACE (_dx_rmiv_get)
00054 #define _dx_rmiv_set    NAMESPACE (_dx_rmiv_set)
00055 #define _dx_real_int    NAMESPACE (_dx_real_int)
00056 #define _dx_real_free   NAMESPACE (_dx_real_free)
00057 #define _dx_real_above  NAMESPACE (_dx_real_above)
00058 #define _dx_real_alloc  NAMESPACE (_dx_real_alloc)
00059 #define _dx_call_real   NAMESPACE (_dx_call_real)
00060 #define _dx_lock_pgs    NAMESPACE (_dx_lock_pgs)
00061 #define _dx_lock_pgsn   NAMESPACE (_dx_lock_pgsn)
00062 #define _dx_ulock_pgsn  NAMESPACE (_dx_ulock_pgsn)
00063 #define _dx_rmlink_get  NAMESPACE (_dx_rmlink_get)
00064
00065 #define ReadRealMem     NAMESPACE (ReadRealMem)
00066 #define WriteRealMem    NAMESPACE (WriteRealMem)
00067 #define PokeRealWord    NAMESPACE (PokeRealWord)
00068 #define PeekRealWord    NAMESPACE (PeekRealWord)
00069 #define PeekRealDWord   NAMESPACE (PeekRealDWord)
00070 #define stack_rewind    NAMESPACE (stack_rewind)
00071
00072 #define _dx_alloc_rmode_wrapper_retf NAMESPACE (_dx_alloc_rmode_wrapper_retf)
00073 #define _dx_alloc_rmode_wrapper_iret NAMESPACE (_dx_alloc_rmode_wrapper_iret)
00074 #define _dx_free_rmode_wrapper       NAMESPACE (_dx_free_rmode_wrapper)
00075
00076 extern void _dx_rmiv_get  (int int_no, REALPTR *handler);
00077 extern void _dx_rmiv_set  (int int_no, REALPTR handler);
00078 extern void _dx_pmiv_get  (int int_no, FARPTR *handler);
00079 extern void _dx_apmiv_set (int int_no, FARPTR handler);
00080 extern void _dx_real_int  (int int_no, SWI_REGS *regs);
00081 extern int  _dx_real_free (WORD segment);
00082 extern int  _dx_real_above(int paras, WORD *para, WORD *largest);
00083 extern int  _dx_real_alloc(int paras, WORD *para, WORD *largest);
00084 extern int  _dx_call_real (REALPTR proc, RMC_BLK *rm_reg, DWORD count, ...);
00085
00086 extern int  _dx_lock_pgs   (const void _far *addr, int len);
00087 extern int  _dx_lock_pgsn  (const void *addr, int len);
00088 extern int  _dx_ulock_pgsn (const void *addr, int len);
00089
00090 extern void _dx_rmlink_get (REALPTR *cback, REALPTR *rm_cbuf,
00091                             DWORD *rm_cbuf_size, void _far **pm_cbuf);
00092
00093 extern REALPTR _dx_alloc_rmode_wrapper_retf (pmodeHook pmHook,
00094                                              rmodeHook rmHook,
00095                                              int len, int stack_size);
00096
00097 extern REALPTR _dx_alloc_rmode_wrapper_iret (pmodeHook pmHook,
00098                                              int stack_size);
00099
00100 extern void    _dx_free_rmode_wrapper (REALPTR dosAddr);
00101
00102 extern void  ReadRealMem  (void *buf, REALPTR rp, unsigned len);
00103 extern void  WriteRealMem (REALPTR rp, const void *src, int size);
00104 extern void  PokeRealWord (REALPTR rp, WORD val);
00105 extern WORD  PeekRealWord (REALPTR rp);
00106 extern DWORD PeekRealDWord(REALPTR rp);
00107 extern void  stack_rewind (DWORD start, DWORD base);
00108
00109 extern UINT cdecl _x386_stacklow;  /* in FlashTek's x32.lib */
00110
00111 #endif   /* DOSX & X32VM */
00112 #endif   /* _w32_X32VM_H */
00113
Generated on Wed Jan 25 15:42:40 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: _hostent Struct Reference

_hostent Struct Reference

#include <GET_XBY.H>

Detailed Description

Internal hostent structure.

Definition at line 56 of file GET_XBY.H.

Data Fields

char * | h_name
char * | h_aliases [MAX_HOST_ALIASES+1]
int | h_num_addr
DWORD | h_address [MAX_ADDRESSES+1]
DWORD | h_real_ttl
time_t | h_timeout
_hostent * | h_next

Generated on Wed Jan 25 15:42:44 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: _hostent6 Struct Reference

_hostent6 Struct Reference

#include <GET_XBY.H>

Detailed Description

Internal hostent6 structure.

Definition at line 69 of file GET_XBY.H.

Data Fields

char * | h_name
char * | h_aliases [MAX_HOST_ALIASES+1]
int | h_num_addr
ip6_address | h_address [MAX_ADDRESSES+1]
DWORD | h_real_ttl
time_t | h_timeout
_hostent6 * | h_next

Generated on Wed Jan 25 15:42:44 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: _netent Struct Reference

_netent Struct Reference

#include <GET_XBY.H>

Detailed Description

Internal netent structure.

Definition at line 82 of file GET_XBY.H.

Data Fields

char * | n_name
char * | n_aliases [MAX_NETENT_ALIASES+1]
int | n_addrtype
DWORD | n_net
_netent * | n_next

Generated on Wed Jan 25 15:42:44 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: _protoent Struct Reference

_protoent Struct Reference

#include <GET_XBY.H>

Detailed Description

Internal protoent structure.

Definition at line 93 of file GET_XBY.H.

Data Fields

char * | p_name
char * | p_aliases [MAX_PROTO_ALIASES+1]
int | p_proto
_protoent * | p_next

Generated on Wed Jan 25 15:42:44 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: _raw6_Socket Struct Reference

_raw6_Socket Struct Reference

#include <WATTCP.H>

Detailed Description

Raw IPv6 socket definition. Only used in BSD-socket API.

Definition at line 686 of file WATTCP.H.

Data Fields

_raw6_Socket * | next
WORD | ip_type
BOOL | used
DWORD | seq_num
in6_Header | ip6
BYTE | rx_data [MAX_IP6_DATA]

Generated on Wed Jan 25 15:42:44 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: _raw_Socket Struct Reference

_raw_Socket Struct Reference

#include <WATTCP.H>

Detailed Description

Raw IPv4 socket definition. Only used in BSD-socket API.

Definition at line 673 of file WATTCP.H.

Data Fields

_raw_Socket * | next
WORD ip_type
same ofs as for udp/tcp Socket
BOOL | used
used flag; packet not read yet
DWORD seq_num
counter for finding oldest pkt
in_Header | ip
BYTE | rx_data [MAX_FRAG_SIZE]
room for 1 jumbo IP packet

Generated on Wed Jan 25 15:42:44 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: _servent Struct Reference

_servent Struct Reference

#include <GET_XBY.H>

Detailed Description

Internal servent structure.

Definition at line 103 of file GET_XBY.H.

Data Fields

char * | s_name
char * | s_aliases [MAX_SERV_ALIASES+1]
int | s_port
char * | s_proto
_servent * | s_next

Generated on Wed Jan 25 15:42:44 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: _tcp_Socket Struct Reference

_tcp_Socket Struct Reference

#include <WATTCP.H>

Detailed Description

TCP Socket definition (fields common to _udp_Socket must come first).

Definition at line 592 of file WATTCP.H.

Data Fields

_tcp_Socket * next
link to next tcp-socket
UDP_TCP_COMMON
BYTE | rx_buf [tcp_MaxBufSize+1]
received data buffer
ip6_address my6addr
our IPv6 address
ip6_address his6addr
peer's IPv6 address
UINT state
tcp connection state
DWORD recv_next
SEQ number we expect to receive.
DWORD send_next
SEQ we send but not ACK-ed by peer.
long | send_una
unacked send data, must be signed
DWORD | last_acknum [2]
for pcdbug.c; to follow SEQ/ACK
DWORD | last_seqnum [2]
increments
DWORD timeout
timer for retrans etc
BYTE unhappy
flag, indicates retransmitting segt's
BYTE recent
1 if recently transmitted
WORD flags
TCP flags used in next Tx.
UINT window
other guy's window
UINT adv_win
our last advertised window
BYTE cwindow
Congestion window.
BYTE wwindow
Van Jacobson's algorithm.
WORD | fill_4
DWORD vj_sa
VJ's alg, standard average (SRTT).
DWORD vj_sd
VJ's alg, standard deviation (RTTVAR).
DWORD vj_last
last transmit time
UINT rto
retransmission timeout
BYTE karn_count
count of packets
BYTE tos
TOS from IP-header.
WORD | fill_5
DWORD rtt_time
Round Trip Time value.
DWORD rtt_lasttran
RTT at last transmission.
DWORD ts_sent
last TimeStamp value sent
DWORD ts_recent
last TimeStamp value received
DWORD ts_echo
last TimeStamp echo received
UINT max_seg
MSS for this connection.
DWORD | missed_seq [2]
S.
char * | secret
Secret for MD5 finger-print.
DWORD inactive_to
inactive timer (no Rx data)
DWORD datatimer
inactive timer (no Tx data)
BYTE tx_wscale
BYTE | rx_wscale
UINT tx_queuelen
optional Tx queue length
const BYTE * | tx_queue
UINT tx_datalen
number of bytes of data to send
UINT max_tx_data
Last index for tx_data[].
BYTE * tx_data
Tx data buffer (default tx_buf[]).
BYTE | tx_buf [tcp_MaxTxBufSize+1]
data for transmission
DWORD safetysig
magic marker
DWORD safetytcp
extra magic marker

Field Documentation

DWORD _tcp_Socket::missed_seq[2]

S.

Lawson - handle one dropped segment.

Todo:
Make a prober re-assembly queue. missed_seq[0] is left edge of missing segment. missed_seq[1] is right edge (in peer's absolute SEQ space)
Definition at line 645 of file WATTCP.H.

BYTE _tcp_Socket::tx_wscale

Todo:
window scales shifts, Tx/Rx
Definition at line 655 of file WATTCP.H.

Generated on Wed Jan 25 15:42:44 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: _udp_Socket Struct Reference

_udp_Socket Struct Reference

#include <WATTCP.H>

Detailed Description

UDP socket definition.

Definition at line 575 of file WATTCP.H.

Data Fields

_udp_Socket * | next
UDP_TCP_COMMON
BYTE | rx_buf [udp_MaxBufSize+1]
received data buffer
ip6_address my6addr
my ip6-address
ip6_address his6addr
peer's ip-6 address
DWORD safetysig
magic marker

Generated on Wed Jan 25 15:42:44 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: ADAPTER Struct Reference

ADAPTER Struct Reference

#include <Packet32.h>

Detailed Description

Describes an opened network adapter.

Definition at line 170 of file Packet32.h.

Data Fields

HANDLE | hFile
HANDLE | ReadEvent
UINT | ReadTimeOut
char | Name [ADAPTER_NAME_LENGTH]

Field Documentation

char ADAPTER::Name[ADAPTER_NAME_LENGTH]

Todo:
: remove this
Definition at line 174 of file Packet32.h.

Generated on Wed Jan 25 15:42:44 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: ADAPTER_INFO Struct Reference

ADAPTER_INFO Struct Reference

#include <Packet32.h>

Detailed Description

Contains comprehensive information about a network adapter.

This structure is filled with all the accessory information that the user can need about an adapter installed on his system.

Definition at line 159 of file Packet32.h.

Data Fields

ADAPTER_INFO * | Next
char | Name [ADAPTER_NAME_LENGTH+1]
char | Description [ADAPTER_DESC_LENGTH+1]
int | NNetworkAddresses
npf_if_addr | NetworkAddresses [MAX_NETWORK_ADDRESSES]

Generated on Wed Jan 25 15:42:44 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: arcnet_Header Struct Reference

arcnet_Header Struct Reference

#include <PCSED.H>

Detailed Description

The ARCNET header.

Definition at line 169 of file PCSED.H.

Data Fields

BYTE | source
BYTE | destination
BYTE | type
BYTE | flags
WORD | sequence
BYTE | type2
BYTE | flags2
WORD | sequence2

Generated on Wed Jan 25 15:42:44 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: arcnet_Packet Struct Reference

arcnet_Packet Struct Reference

#include <PCSED.H>

Detailed Description

The ARCNET header with data.

Definition at line 190 of file PCSED.H.

Data Fields

arcnet_Header | head
BYTE | data [ARCNET_MAX_DATA]

Generated on Wed Jan 25 15:42:44 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: arp_entry Struct Reference

arp_entry Struct Reference

#include <PCARP.H>

Detailed Description

ARP cache table.

Definition at line 23 of file PCARP.H.

Data Fields

DWORD ip
IP address of ARP entry.
eth_address hardware
MAC address of ARP entry.
DWORD expiry
'pending timeout' or 'dynamic expiry'
DWORD retransmit_to
used only for re-requesting MAC while 'pending'
WORD flags
ARP flags, see below.

Generated on Wed Jan 25 15:42:44 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: arp_Header Struct Reference

arp_Header Struct Reference

#include <WATTCP.H>

Detailed Description

ARP/RARP header.

Definition at line 488 of file WATTCP.H.

Data Fields

WORD | hwType
WORD | protType
BYTE hwAddrLen
MAC addr.
BYTE protoAddrLen
IP addr.
WORD | opcode
eth_address | srcEthAddr
DWORD | srcIPAddr
eth_address | dstEthAddr
DWORD | dstIPAddr

Field Documentation

BYTE arp_Header::hwAddrLen

MAC addr.

length (6) Definition at line 491 of file WATTCP.H.

BYTE arp_Header::protoAddrLen

IP addr.

length (4) Definition at line 492 of file WATTCP.H.

Generated on Wed Jan 25 15:42:44 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: bootp Struct Reference

bootp Struct Reference

#include <PCBOOTP.H>

Detailed Description

Structure for send and receive.

Definition at line 63 of file PCBOOTP.H.

Data Fields

BYTE | bp_op
BYTE | bp_htype
BYTE | bp_hlen
BYTE | bp_hops
DWORD | bp_xid
WORD | bp_secs
WORD | bp_spare
DWORD | bp_ciaddr
DWORD | bp_yiaddr
DWORD | bp_siaddr
DWORD | bp_giaddr
BYTE | bp_chaddr [16]
BYTE | bp_sname [64]
BYTE | bp_file [128]
BYTE | bp_vend [64]

Generated on Wed Jan 25 15:42:44 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: bootp_vend Struct Reference

bootp_vend Struct Reference

#include <PCBOOTP.H>

Detailed Description

"vendor" data permitted for Stanford boot clients.

Definition at line 107 of file PCBOOTP.H.

Data Fields

BYTE | v_magic [4]
DWORD | v_flags
BYTE | v_unused [56]

Generated on Wed Jan 25 15:42:44 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: bpf_hdr Struct Reference

bpf_hdr Struct Reference

#include <Packet32.h>

Detailed Description

Berkeley Packet Filter header.

This structure defines the header associated with every packet delivered to the application.

Definition at line 210 of file Packet32.h.

Data Fields

timeval | bh_tstamp
DWORD | bh_caplen
DWORD | bh_datalen
WORD | bh_hdrlen
timeval | bh_tstamp
u_int32_t | bh_caplen
u_int32_t | bh_datalen
u_int16_t | bh_hdrlen

Generated on Wed Jan 25 15:42:44 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: cmd_block Struct Reference

cmd_block Struct Reference

Detailed Description

Run a COMMAND.COM/4DOS external/internal command.

Definition at line 1366 of file MISC.C.

Data Fields

BYTE | len
char | buf [256]

Generated on Wed Jan 25 15:42:44 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: dhcp Struct Reference

dhcp Struct Reference

#include <PCDHCP.H>

Detailed Description

Largest DHCP in/out packet.

Definition at line 128 of file PCDHCP.H.

Data Fields

BYTE | dh_op
BYTE | dh_htype
BYTE | dh_hlen
BYTE | dh_hops
DWORD | dh_xid
WORD | dh_secs
WORD | dh_flags
DWORD | dh_ciaddr
DWORD | dh_yiaddr
DWORD | dh_siaddr
DWORD | dh_giaddr
BYTE | dh_chaddr [16]
BYTE | dh_sname [64]
BYTE | dh_file [128]
BYTE | dh_opt [312]

Generated on Wed Jan 25 15:42:44 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: DNS_Hdr Struct Reference

DNS_Hdr Struct Reference

Detailed Description

Debug of DNS (udp) records.

Author:
Mike Borella <mike_borella@mw.3com.com>
Changed for WatTCP and pcdbug.c by G.Vanem 1998 <giva@bgnett.no>

Todo:
parse the SRV resource record (RFC 2052)

Definition at line 2640 of file PCDBUG.C.

Data Fields

WORD | dns_id
WORD | dns_fl_qr: 1
WORD | dns_fl_opcode: 4
WORD | dns_fl_aa: 1
WORD | dns_fl_tc: 1
WORD | dns_fl_rd: 1
WORD | dns_fl_ra: 1
WORD | dns_fl_unused: 1
WORD | dns_fl_ad: 1
WORD | dns_fl_cd: 1
WORD | dns_fl_rcode: 4
WORD | dns_num_q
WORD | dns_num_ans
WORD | dns_num_auth
WORD | dns_num_add

Generated on Wed Jan 25 15:42:44 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: eth_Header Struct Reference

eth_Header Struct Reference

#include <PCSED.H>

Detailed Description

The DIX Ethernet header.

Definition at line 26 of file PCSED.H.

Data Fields

eth_address | destination
eth_address | source
WORD | type

Generated on Wed Jan 25 15:42:44 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: eth_Packet Struct Reference

eth_Packet Struct Reference

#include <PCSED.H>

Detailed Description

The Ethernet header with data.

Definition at line 36 of file PCSED.H.

Data Fields

eth_Header | head
BYTE | data [ETH_MAX_DATA]

Generated on Wed Jan 25 15:42:44 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: fddi_Header Struct Reference

fddi_Header Struct Reference

#include <PCSED.H>

Detailed Description

The FDDI header.

Definition at line 138 of file PCSED.H.

Data Fields

BYTE | frameCtrl
eth_address | destination
eth_address | source
BYTE | DSAP
BYTE | SSAP
BYTE | ctrl
BYTE | org [3]
WORD | type

Generated on Wed Jan 25 15:42:44 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: fddi_Packet Struct Reference

fddi_Packet Struct Reference

#include <PCSED.H>

Detailed Description

The FDDI header with data.

Definition at line 153 of file PCSED.H.

Data Fields

fddi_Header | head
BYTE | data [FDDI_MAX_DATA]

Generated on Wed Jan 25 15:42:44 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: gate_entry Struct Reference

gate_entry Struct Reference

#include <PCARP.H>

Detailed Description

Gateway table.

Definition at line 11 of file PCARP.H.

Data Fields

DWORD gate_ip
The IP address of gateway.
DWORD subnet
The subnet mask of gateway.
DWORD | mask
BOOL | is_dead
BOOL | echo_pending
DWORD | chk_timer

Generated on Wed Jan 25 15:42:44 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: ICMP_ip Struct Reference

ICMP_ip Struct Reference

Detailed Description

, ICMP_PARAMPROB etc.)

Definition at line 32 of file PCICMP.H.

Data Fields

BYTE | type
BYTE | code
WORD | checksum
DWORD | ipaddr
in_Header | ip

Generated on Wed Jan 25 15:42:44 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: ICMP_needfrag Struct Reference

ICMP_needfrag Struct Reference

Detailed Description

type ICMP_UNREACH, code ICMP_UNREACH_NEEDFRAG)

Definition at line 102 of file PCICMP.H.

Data Fields

BYTE | type
BYTE | code
WORD | checksum
WORD | unused
WORD | next_mtu

Generated on Wed Jan 25 15:42:44 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: ICMP_unused Struct Reference

ICMP_unused Struct Reference

Detailed Description

etc.)

Definition at line 10 of file PCICMP.H.

Data Fields

BYTE | type
BYTE | code
WORD | checksum
DWORD | unused
in_Header | ip
BYTE | spares [8]

Generated on Wed Jan 25 15:42:44 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: IGMP_packet Struct Reference

IGMP_packet Struct Reference

#include <WATTCP.H>

Detailed Description

Internet Group Management Protocol packet.

Definition at line 466 of file WATTCP.H.

Data Fields

int | version: 4
int | type: 4
BYTE | mbz
WORD | checksum
DWORD | address

Generated on Wed Jan 25 15:42:44 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: in6_Header Struct Reference

in6_Header Struct Reference

#include <WATTCP.H>

Detailed Description

IPv6 header.

Definition at line 358 of file WATTCP.H.

Data Fields

BYTE | ver: 4
BYTE | pri: 4
BYTE | flow_lbl [3]
WORD | len
BYTE | next_hdr
BYTE | hop_limit
ip6_address | source
ip6_address | destination

Generated on Wed Jan 25 15:42:44 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: in_Header Struct Reference

in_Header Struct Reference

#include <WATTCP.H>

Detailed Description

The Internet (ip) Header.

Definition at line 313 of file WATTCP.H.

Data Fields

BYTE | ver: 4
BYTE | hdrlen: 4
int | hdrlen: 4
int | ver: 4
BYTE | tos
WORD | length
WORD | identification
WORD | frag_ofs
BYTE | ttl
BYTE | proto
WORD | checksum
DWORD | source
DWORD | destination

Generated on Wed Jan 25 15:42:44 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: ip_Packet Struct Reference

ip_Packet Struct Reference

#include <WATTCP.H>

Detailed Description

IPv4 packet including header and data.

Definition at line 378 of file WATTCP.H.

Data Fields

in_Header | head
BYTE | data [MAX_IP4_DATA]

Generated on Wed Jan 25 15:42:44 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: link_Packet Union Reference

link_Packet Union Reference

#include <PCSED.H>

Detailed Description

The union of all above MAC-headers.

Definition at line 200 of file PCSED.H.

Data Fields

eth_Packet | eth
tok_Packet | tok
fddi_Packet | fddi
arcnet_Packet | arc
ip_Packet | ip
vlan_Packet | vlan

Generated on Wed Jan 25 15:42:44 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: llc_Header Struct Reference

llc_Header Struct Reference

#include <PCSED.H>

Detailed Description

LLC header format.

Definition at line 105 of file PCSED.H.

Data Fields

BYTE | DSAP
BYTE | SSAP
union {
BYTE u_ctl
WORD is_ctl
struct {
BYTE snap_ui
BYTE snap_pi [5]
} snap
struct {
BYTE snap_ui
BYTE snap_orgcode [3]
BYTE snap_ethertype [2]
} snap_ether
} ctl

Generated on Wed Jan 25 15:42:44 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: macstat Struct Reference

macstat Struct Reference

#include <PCSTAT.H>

Detailed Description

MAC-layer statistics.

Definition at line 44 of file PCSTAT.H.

Data Fields

DWORD | non_ip_recv
DWORD | non_ip_sent
DWORD | num_tx_err
DWORD | num_tx_retry
DWORD | num_tx_timeout
DWORD | num_unk_type
DWORD | num_llc_frames
DWORD | num_wrong_handle
DWORD | num_bad_sync
DWORD | num_too_large
DWORD | num_too_small
DWORD | num_mac_loop
DWORD | num_ip_recurse
struct {
DWORD request_recv
DWORD request_sent
DWORD reply_recv
DWORD reply_sent
} arp
struct {
DWORD request_recv
DWORD request_sent
DWORD reply_recv
DWORD reply_sent
} rarp

Generated on Wed Jan 25 15:42:44 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: MultiCast Struct Reference

MultiCast Struct Reference

#include <PCMULTI.H>

Detailed Description

Multicast internal structure.

Definition at line 20 of file PCMULTI.H.

Data Fields

DWORD ip
IP address of group.
eth_address ethaddr
Ethernet address of group.
BYTE processes
number of interested processes
DWORD reply_timer
IGMP query reply timer.
BOOL active
is this an active entry

Generated on Wed Jan 25 15:42:44 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: npf_if_addr Struct Reference

npf_if_addr Struct Reference

#include <Packet32.h>

Detailed Description

Addresses of a network adapter.

This structure is used by the PacketGetNetInfoEx() function to return the IP addresses associated with an adapter.

Definition at line 140 of file Packet32.h.

Data Fields

sockaddr_storage | IPAddress
sockaddr_storage | SubnetMask
sockaddr_storage | Broadcast

Generated on Wed Jan 25 15:42:44 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: on_exit Struct Reference

on_exit Struct Reference

Detailed Description

Register an on-exit function.

Insert the 'func' so functions with lowest order are run first. All functions must have different orders.

Definition at line 450 of file MISC.C.

Data Fields

void(* | func )(void)
const char * | name
int | order

Generated on Wed Jan 25 15:42:44 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: PACKET Struct Reference

PACKET Struct Reference

#include <Packet32.h>

Detailed Description

Structure for PacketReceivePacket + PacketSendPacket.

Definition at line 182 of file Packet32.h.

Data Fields

HANDLE | hEvent
OVERLAPPED | OverLapped
void * | Buffer
UINT | Length
DWORD | ulBytesReceived
BOOLEAN | bIoComplete

Generated on Wed Jan 25 15:42:44 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: PACKET_OID_DATA Struct Reference

PACKET_OID_DATA Struct Reference

#include <Packet32.h>

Detailed Description

Structure containing an OID request.

It is used by the PacketRequest() function to send an OID to the interface card driver. It can be used, for example, to retrieve the status of the error counters on the adapter, its MAC address, the list of the multicast groups defined on it, and so on.

Definition at line 199 of file Packet32.h.

Data Fields

DWORD | Oid
DWORD | Length
BYTE | Data [1]

Generated on Wed Jan 25 15:42:44 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: ping_cache Struct Reference

ping_cache Struct Reference

Detailed Description

Our little ping-cache.

Definition at line 30 of file PCPING.C.

Data Fields

DWORD | host
DWORD | time
DWORD | number

Generated on Wed Jan 25 15:42:44 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: ping_pkt Struct Reference

ping_pkt Struct Reference

#include <PCICMP.H>

Detailed Description

The ping packet.

Definition at line 127 of file PCICMP.H.

Data Fields

in_Header | in
ICMP_echo | icmp

Generated on Wed Jan 25 15:42:44 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: pkt_info Struct Reference

pkt_info Struct Reference

#include <WINPCAP.H>

Detailed Description

Placeholder for vital data accessed by capture thread.

Definition at line 261 of file PCPKT.H.

Data Fields

WORD | rm_sel
WORD | rm_seg
WORD | rm_ofs
WORD | dos_ds
WORD | use_near_ptr
WORD | handle
WORD | is_serial
WORD | pkt_ip_ofs
WORD | pkt_type_ofs
pkt_ringbuf | pkt_queue
pkt_rx_element | rx_buf [RX_BUFS]
const void * | adapter
const void * | adapter_info
void * | npf_buf
int | npf_buf_size
HANDLE | recv_thread
volatile BOOL | stop_thread
volatile BOOL | thread_stopped
const char * | error
pkt_ringbuf | pkt_queue
pkt_rx_element | rx_buf [RX_BUFS]

Generated on Wed Jan 25 15:42:44 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: pkt_ringbuf Struct Reference

pkt_ringbuf Struct Reference

#include <PCQUEUE.H>

Detailed Description

FIFO style ring-buffer.

Definition at line 81 of file PCQUEUE.H.

Data Fields

volatile WORD | in_index
WORD | out_index
WORD | buf_size
WORD | num_buf
volatile DWORD | num_drop
DWORD | buf_start
WORD | dos_ofs

Generated on Wed Jan 25 15:42:44 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: pppoestat Struct Reference

pppoestat Struct Reference

#include <PCSTAT.H>

Detailed Description

PPP-over-Ethernet statistics.

Definition at line 80 of file PCSTAT.H.

Data Fields

DWORD | num_disc_sent
DWORD | num_disc_recv
DWORD | num_sess_sent
DWORD | num_sess_recv

Generated on Wed Jan 25 15:42:44 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: route_entry Struct Reference

route_entry Struct Reference

Detailed Description

ROUTE (& REDIRECT) HANDLING.

Route table.

Definition at line 657 of file PCARP.C.

Data Fields

DWORD | host_ip
DWORD | gate_ip

Generated on Wed Jan 25 15:42:44 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: sock_type Union Reference

sock_type Union Reference

#include <WATTCP.H>

Detailed Description

sock_type used for socket I/O.

Definition at line 699 of file WATTCP.H.

Data Fields

_udp_Socket | udp
_tcp_Socket | tcp
_raw_Socket | raw
_raw6_Socket | raw6

Generated on Wed Jan 25 15:42:44 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: tcp_Header Struct Reference

tcp_Header Struct Reference

#include <WATTCP.H>

Detailed Description

The TCP header.

Definition at line 400 of file WATTCP.H.

Data Fields

WORD | srcPort
WORD | dstPort
DWORD | seqnum
DWORD | acknum
BYTE | offset: 4
BYTE | unused: 4
int | unused: 4
int | offset: 4
BYTE | flags
WORD | window
WORD | checksum
WORD | urgent

Generated on Wed Jan 25 15:42:44 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: tcp_PseudoHeader Struct Reference

tcp_PseudoHeader Struct Reference

#include <WATTCP.H>

Detailed Description

The TCP/UDP Pseudo Header (IPv4).

Definition at line 439 of file WATTCP.H.

Data Fields

DWORD | src
DWORD | dst
BYTE | mbz
BYTE | protocol
WORD | length
WORD | checksum

Generated on Wed Jan 25 15:42:44 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: tcp_PseudoHeader6 Struct Reference

tcp_PseudoHeader6 Struct Reference

#include <WATTCP.H>

Detailed Description

The TCP/UDP Pseudo Header (IPv6).

Definition at line 453 of file WATTCP.H.

Data Fields

ip6_address | src
ip6_address | dst
WORD | length
BYTE | zero [3]
BYTE | next_hdr

Generated on Wed Jan 25 15:42:44 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: tcp_rtt Struct Reference

tcp_rtt Struct Reference

#include <PCTCP.H>

Detailed Description

A simple RTT cache based on Phil Karn's KA9Q.

Definition at line 258 of file PCTCP.H.

Data Fields

DWORD ip
IP-address of this entry.
UINT rto
Round-trip timeout for this entry.
UINT MTU
Path-MTU discovered for this entry.

Generated on Wed Jan 25 15:42:44 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: tok_Header Struct Reference

tok_Header Struct Reference

#include <PCSED.H>

Detailed Description

Token-Ring header, refer RFC-1042, pg. 8.

Definition at line 68 of file PCSED.H.

Data Fields

BYTE | accessCtrl
BYTE | frameCtrl
mac_address | destination
mac_address | source
BYTE | DSAP
BYTE | SSAP
BYTE | ctrl
BYTE | org [3]
WORD | type

Generated on Wed Jan 25 15:42:44 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: tok_Packet Struct Reference

tok_Packet Struct Reference

#include <PCSED.H>

Detailed Description

Token-Ring header with data.

Definition at line 96 of file PCSED.H.

Data Fields

tok_Header | head
BYTE | data [TOK_MAX_DATA]

Generated on Wed Jan 25 15:42:44 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: udp_Header Struct Reference

udp_Header Struct Reference

#include <WATTCP.H>

Detailed Description

The UDP header.

Definition at line 388 of file WATTCP.H.

Data Fields

WORD | srcPort
WORD | dstPort
WORD | length
WORD | checksum

Generated on Wed Jan 25 15:42:44 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: vlan_Header Struct Reference

vlan_Header Struct Reference

#include <PCSED.H>

Detailed Description

The 802.1Q VLAN header.

Definition at line 46 of file PCSED.H.

Data Fields

eth_address | destination
eth_address | source
WORD | proto
WORD | tci
WORD | encap_proto

Generated on Wed Jan 25 15:42:44 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: vlan_Packet Struct Reference

vlan_Packet Struct Reference

#include <PCSED.H>

Detailed Description

The 802.1Q VLAN header with data.

Definition at line 58 of file PCSED.H.

Data Fields

vlan_Header | head
BYTE | data [VLAN_MAX_DATA]

Generated on Wed Jan 25 15:42:44 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: watt_sockaddr Struct Reference

watt_sockaddr Struct Reference

#include <WATTCP.H>

Detailed Description

Deprecated:
Old style sockaddr

Definition at line 710 of file WATTCP.H.

Data Fields

WORD | s_type
WORD | s_port
DWORD | s_ip
BYTE | s_spares [6]
unused in TCP realm

Generated on Wed Jan 25 15:42:44 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: Data Fields

Here is a list of all documented struct and union fields with links to the struct/union documentation for each field:

- a -

  • active : MultiCast
  • adv_win : _tcp_Socket

- c -

  • cwindow : _tcp_Socket

- d -

  • datatimer : _tcp_Socket

- e -

  • ethaddr : MultiCast
  • expiry : arp_entry

- f -

  • flags : _tcp_Socket, arp_entry

- g -

  • gate_ip : gate_entry

- h -

  • hardware : arp_entry
  • his6addr : _tcp_Socket, _udp_Socket
  • hwAddrLen : arp_Header

- i -

  • inactive_to : _tcp_Socket
  • ip : tcp_rtt, MultiCast, arp_entry
  • ip_type : _raw_Socket

- k -

  • karn_count : _tcp_Socket

- l -

  • last_acknum : _tcp_Socket
  • last_seqnum : _tcp_Socket

- m -

  • max_seg : _tcp_Socket
  • max_tx_data : _tcp_Socket
  • missed_seq : _tcp_Socket
  • MTU : tcp_rtt
  • my6addr : _tcp_Socket, _udp_Socket

- n -

  • Name : ADAPTER
  • next : _tcp_Socket

- p -

  • processes : MultiCast
  • protoAddrLen : arp_Header

- r -

  • recent : _tcp_Socket
  • recv_next : _tcp_Socket
  • reply_timer : MultiCast
  • retransmit_to : arp_entry
  • rto : _tcp_Socket, tcp_rtt
  • rtt_lasttran : _tcp_Socket
  • rtt_time : _tcp_Socket
  • rx_buf : _tcp_Socket, _udp_Socket
  • rx_data : _raw_Socket

- s -

  • s_spares : watt_sockaddr
  • safetysig : _tcp_Socket, _udp_Socket
  • safetytcp : _tcp_Socket
  • secret : _tcp_Socket
  • send_next : _tcp_Socket
  • send_una : _tcp_Socket
  • seq_num : _raw_Socket
  • state : _tcp_Socket
  • subnet : gate_entry

- t -

  • timeout : _tcp_Socket
  • tos : _tcp_Socket
  • ts_echo : _tcp_Socket
  • ts_recent : _tcp_Socket
  • ts_sent : _tcp_Socket
  • tx_buf : _tcp_Socket
  • tx_data : _tcp_Socket
  • tx_datalen : _tcp_Socket
  • tx_queuelen : _tcp_Socket
  • tx_wscale : _tcp_Socket

- u -

  • unhappy : _tcp_Socket
  • used : _raw_Socket

- v -

  • vj_last : _tcp_Socket
  • vj_sa : _tcp_Socket
  • vj_sd : _tcp_Socket

- w -

  • window : _tcp_Socket
  • wwindow : _tcp_Socket
Generated on Wed Jan 25 15:42:44 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: Data Fields - Variables

- a -

  • active : MultiCast
  • adv_win : _tcp_Socket

- c -

  • cwindow : _tcp_Socket

- d -

  • datatimer : _tcp_Socket

- e -

  • ethaddr : MultiCast
  • expiry : arp_entry

- f -

  • flags : _tcp_Socket, arp_entry

- g -

  • gate_ip : gate_entry

- h -

  • hardware : arp_entry
  • his6addr : _tcp_Socket, _udp_Socket
  • hwAddrLen : arp_Header

- i -

  • inactive_to : _tcp_Socket
  • ip : tcp_rtt, MultiCast, arp_entry
  • ip_type : _raw_Socket

- k -

  • karn_count : _tcp_Socket

- l -

  • last_acknum : _tcp_Socket
  • last_seqnum : _tcp_Socket

- m -

  • max_seg : _tcp_Socket
  • max_tx_data : _tcp_Socket
  • missed_seq : _tcp_Socket
  • MTU : tcp_rtt
  • my6addr : _tcp_Socket, _udp_Socket

- n -

  • Name : ADAPTER
  • next : _tcp_Socket

- p -

  • processes : MultiCast
  • protoAddrLen : arp_Header

- r -

  • recent : _tcp_Socket
  • recv_next : _tcp_Socket
  • reply_timer : MultiCast
  • retransmit_to : arp_entry
  • rto : _tcp_Socket, tcp_rtt
  • rtt_lasttran : _tcp_Socket
  • rtt_time : _tcp_Socket
  • rx_buf : _tcp_Socket, _udp_Socket
  • rx_data : _raw_Socket

- s -

  • s_spares : watt_sockaddr
  • safetysig : _tcp_Socket, _udp_Socket
  • safetytcp : _tcp_Socket
  • secret : _tcp_Socket
  • send_next : _tcp_Socket
  • send_una : _tcp_Socket
  • seq_num : _raw_Socket
  • state : _tcp_Socket
  • subnet : gate_entry

- t -

  • timeout : _tcp_Socket
  • tos : _tcp_Socket
  • ts_echo : _tcp_Socket
  • ts_recent : _tcp_Socket
  • ts_sent : _tcp_Socket
  • tx_buf : _tcp_Socket
  • tx_data : _tcp_Socket
  • tx_datalen : _tcp_Socket
  • tx_queuelen : _tcp_Socket
  • tx_wscale : _tcp_Socket

- u -

  • unhappy : _tcp_Socket
  • used : _raw_Socket

- v -

  • vj_last : _tcp_Socket
  • vj_sa : _tcp_Socket
  • vj_sd : _tcp_Socket

- w -

  • window : _tcp_Socket
  • wwindow : _tcp_Socket
Generated on Wed Jan 25 15:42:44 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: Globals

Here is a list of all documented functions, variables, defines, enums, and typedefs with links to the documentation:

- _ -

  • __get_sock_from_s() : TCP.H, SOCKET.H, SOCKET.C
  • _arp_add_cache() : PCARP.H, PCARP.C
  • _arp_add_gateway() : PCARP.H, PCARP.C
  • _arp_check_gateways() : PCARP.H, PCARP.C
  • _arp_check_own_ip() : PCARP.H, PCARP.C
  • _arp_debug_dump() : PCARP.H, PCARP.C
  • _arp_delete_cache() : PCARP.H, PCARP.C
  • _arp_handler() : PCARP.H, PCARP.C
  • _arp_have_default_gw() : PCARP.H, PCARP.C
  • _arp_init() : PCARP.H, PCARP.C
  • _arp_kill_gateways() : PCARP.H, PCARP.C
  • _arp_list_cache() : PCARP.H, PCARP.C
  • _arp_list_gateways() : PCARP.H, PCARP.C
  • _arp_register() : TCP.H, PCARP.H, PCARP.C
  • _arp_reply() : PCARP.H, PCARP.C
  • _arp_resolve() : TCP.H, PCARP.H, PCARP.C
  • _bootp_on : SOCK_INI.C
  • _bsd_socket_hook() : PCTCP.C
  • _chk_ping() : TCP.H, PCPING.H, PCPING.C, PCICMP.H
  • _default_tos : IP4_OUT.H, IP4_OUT.C
  • _default_ttl : IP4_OUT.H, IP4_OUT.C
  • _dhcp6_on : SOCK_INI.C
  • _dhcp_on : SOCK_INI.C
  • _do_mask_req : SOCK_INI.C
  • _dx_real_alloc() : X32VM.H, X32VM.C
  • _eth_addr : PCSED.C
  • _eth_arrived() : TCP.H, PCSED.H, PCSED.C
  • _eth_brdcast : PCSED.C
  • _eth_formatpacket() : TCP.H, PCSED.H, PCSED.C
  • _eth_free() : TCP.H, PCSED.H, PCSED.C
  • _eth_get_hwtype() : TCP.H, PCSED.H, PCSED.C
  • _eth_init() : TCP.H, PCSED.H, PCSED.C
  • _eth_is_init : PCSED.H, PCSED.C
  • _eth_join_mcast_group() : PCSED.H, PCSED.C
  • _eth_last : PCSED.H, PCSED.C
  • _eth_leave_mcast_group() : PCSED.H, PCSED.C
  • _eth_loop_addr : PCSED.C
  • _eth_mac_dst() : PCSED.H, PCSED.C
  • _eth_mac_hdr() : PCSED.H, PCSED.C
  • _eth_mac_len : PCSED.H, PCSED.C
  • _eth_mac_src() : PCSED.H, PCSED.C
  • _eth_mac_typ() : PCSED.H, PCSED.C
  • _eth_real_addr : PCSED.C
  • _eth_recv_hook : PCSED.C
  • _eth_release() : TCP.H, PCSED.H, PCSED.C
  • _eth_send() : TCP.H, PCSED.H, PCSED.C
  • _eth_set_addr() : TCP.H, PCSED.H, PCSED.C
  • _get_ip4_id() : IP4_OUT.H, IP4_OUT.C
  • _get_machine_name() : BSDNAME.H, BSDNAME.C
  • _get_this_ip4_id() : IP4_OUT.H, IP4_OUT.C
  • _gethostid() : TCP.H, BSDNAME.H, BSDNAME.C
  • _gethostid6() : BSDNAME.H, BSDNAME.C
  • _getpeername() : BSDNAME.H, BSDNAME.C
  • _getsockname() : BSDNAME.H, BSDNAME.C
  • _inet6_addr() : NETADDR.H, NETADDR.C
  • _inet6_ntoa() : NETADDR.H, NETADDR.C
  • _inet_addr() : TCP.H, NETADDR.H, NETADDR.C
  • _inet_atoeth() : NETADDR.H, NETADDR.C
  • _inet_ntoa() : TCP.H, NETADDR.H, NETADDR.C
  • _ip4_dont_frag : IP4_OUT.H, IP4_OUT.C
  • _ip4_handler() : IP4_IN.H, IP4_IN.C
  • _ip4_id_increment : IP4_OUT.H, IP4_OUT.C
  • _ip4_output() : IP4_OUT.H, IP4_OUT.C
  • _ip4_send_fragments() : IP4_OUT.H, IP4_OUT.C
  • _ip6_checksum() : CHKSUM.H, CHKSUM.C
  • _ip6_output() : IP6_OUT.H, IP6_OUT.C
  • _ip6_tcp_checksum() : CHKSUM.H, CHKSUM.C
  • _ip6_udp_checksum() : CHKSUM.H, CHKSUM.C
  • _ip_recursion : PCSED.H, PCSED.C
  • _ping() : PCPING.H, PCPING.C
  • _pkt_errno : PCPKT.H, PCPKT.C
  • _pkt_forced_rxmode : WINPCAP.C, PCPKT.H
  • _pkt_inf : WINPCAP.H, WINPCAP.C, PCPKT.H, PCPKT.C
  • _pkt_ip_ofs : PCPKT.H, PCPKT.C
  • _pkt_rxmode : WINPCAP.C, PCPKT.H, PCPKT.C
  • _pkt_rxmode0 : WINPCAP.C, PCPKT.H, PCPKT.C
  • _pkt_type_ofs : PCPKT.C
  • _pktdevclass : PCPKT.H, PCPKT.C
  • _pktdevlevel : PCPKT.H, PCPKT.C
  • _pktdrvrname : PCPKT.H
  • _pktserial : PCPKT.H, PCPKT.C
  • _printk_file : PRINTK.H, PRINTK.C
  • _printk_safe : PRINTK.H, PRINTK.C
  • _rarp_handler() : PCRARP.C
  • _rarp_on : SOCK_INI.C
  • _sarp_debug_dump() : PCSARP.C
  • _sethostid() : TCP.H, BSDNAME.H, BSDNAME.C
  • _sethostid6() : BSDNAME.H, BSDNAME.C
  • _sock_append() : SOCKET.H, ACCEPT.C
  • _sock_calloc() : SOCKET.H, SOCKET.C
  • _sock_chk_sockaddr() : SOCKET.H, SOCKET.C
  • _sock_crit_start() : SOCKET.H, SOCKET.C
  • _sock_crit_stop() : SOCKET.H, SOCKET.C
  • _sock_del_fd() : SOCKET.H, SOCKET.C
  • _sock_dos_fd() : SOCKET.H, SOCKET.C
  • _sock_free_rcv_buf() : SOCKET.H, SOCKET.C
  • _sock_half_open() : SOCKET.H, SOCKET.C
  • _sock_set_rcv_buf() : SOCKET.H, SOCKET.C
  • _socklist_find() : SOCKET.H, SOCKET.C
  • _TCP6_listen() : SOCKET.H, SOCKET.C
  • _TCP6_open() : SOCKET.H, SOCKET.C
  • _tcp_abort() : PCTCP.H, PCTCP.C
  • _tcp_allsocs : PCTCP.H, PCTCP.C
  • _tcp_cancel() : PCTCP.H, PCTCP.C
  • _tcp_close() : PCTCP.H, PCTCP.C
  • _tcp_handler() : PCTCP.H, PCTCP.C
  • _tcp_keepalive() : PCTCP.H, PCTCP.C
  • _TCP_open() : SOCKET.H, SOCKET.C
  • _tcp_send() : PCTCP.H, PCTCP.C
  • _tcp_send_reset() : PCTCP.H, PCTCP.C
  • _tcp_sendsoon() : PCTCP.H, PCTCP.C
  • _tcp_unthread() : PCTCP.H, PCTCP.C
  • _UDP6_listen() : SOCKET.H, SOCKET.C
  • _UDP6_open() : SOCKET.H, SOCKET.C
  • _udp_allsocs : PCTCP.H, PCTCP.C
  • _udp_cancel() : PCTCP.H, PCTCP.C
  • _udp_handler() : PCTCP.H, PCTCP.C
  • _UDP_open() : SOCKET.H, SOCKET.C
  • _w32_intel() : SWAP.H, MISC.C
  • _w32_intel16() : SWAP.H, MISC.C
  • _w32_intr() : MISC.C
  • _watt_assert_buf : MISC.C
  • _watt_cbroke : PC_CBRK.C
  • _watt_do_exit : SOCK_INI.C
  • _watt_dosFp : TARGET.H, MISC.C
  • _watt_fatal_error : MISC.C
  • _watt_handle_cbreak : PC_CBRK.C
  • _watt_is_init : SOCK_INI.C
  • _watt_no_config : SOCK_INI.C
  • _watt_os_ver : MISC.C
  • _watt_user_config() : TCP.H, SOCK_INI.C, PCCONFIG.H

- a -

  • Abort() : LANGUAGE.L
  • accept() : SOCKET.H, ACCEPT.C
  • add_ping() : PCPING.H, PCPING.C
  • addr_mask_id : PCICMP.C
  • addwattcpd() : PCTCP.H, PCTCP.C
  • afd_list_init() : GET_AI.C
  • arcnet_address : WATTCP.H
  • arcnet_mac_format() : PCSED.C
  • ARG_ATOB : PCCONFIG.H
  • ARG_ATOI : PCCONFIG.H
  • ARG_ATOIP : PCCONFIG.H
  • ARG_ATOW : PCCONFIG.H
  • ARG_ATOX_B : PCCONFIG.H
  • ARG_ATOX_D : PCCONFIG.H
  • ARG_ATOX_W : PCCONFIG.H
  • ARG_FUNC : PCCONFIG.H
  • ARG_RESOLVE : PCCONFIG.H
  • ARG_STRCPY : PCCONFIG.H
  • ARG_STRDUP : PCCONFIG.H
  • arp_add_server() : PCDHCP.C
  • arp_check_timeouts() : PCARP.C
  • arp_daemon() : PCARP.C
  • arp_lookup() : PCARP.H, PCARP.C
  • arp_lookup_fixed() : PCARP.H, PCARP.C
  • arp_lookup_pending() : PCARP.H, PCARP.C
  • arp_move_entry() : PCARP.C
  • arp_send() : PCARP.C
  • arp_send_request() : PCARP.C
  • arp_start_lookup() : PCARP.H, PCARP.C
  • assert_fail() : MISC.H, MISC.C
  • aton() : TCP.H, NETADDR.H, NETADDR.C
  • aton_dotless() : NETADDR.H, NETADDR.C
  • atox() : STRINGS.H, STRINGS.C
  • ax25_address : WATTCP.H

- b -

  • bind() : SOCKET.H, BIND.C
  • block_icmp : PCTCP.C
  • block_ip : PCTCP.C
  • block_tcp : PCTCP.C
  • block_udp : PCTCP.C
  • BOOTP_do_boot() : PCBOOTP.H, PCBOOTP.C
  • build_pad() : PPPOE.C
  • BYTE : WATTCP.H

- c -

  • called_from_resolve : UDP_DOM.H, UDP_DOM.C
  • capa : VERSION.C
  • change_ip_addr() : PCDHCP.C
  • check_errno_version() : SOCKET.C
  • check_intr_num() : PCPKT.C
  • chk_timeout() : TCP.H, TIMER.H, TIMER.C
  • chkip_method() : DYNIP.C
  • client_error() : UDP_DOM.C
  • clocks_per_usec : TIMER.C
  • CloseHostFile() : GETHOST.C, GET_XBY.H
  • cmp_timers() : TCP.H, TIMER.H, TIMER.C
  • compare() : PCPING.C
  • config_tab_types : PCCONFIG.H
  • crtdbg_report() : MISC.C
  • cstate_dseg : PCPKT.C

- d -

  • daemon_timer : PCTCP.C
  • dbg_mode_all : PCDBUG.H, PCDBUG.C
  • dbug_exit() : PCDBUG.C
  • defaultdomain : UDP_DOM.C
  • delwattcpd() : PCTCP.H, PCTCP.C
  • DHCP_arp_check() : PCDHCP.C
  • DHCP_cfg_hook() : PCDHCP.C
  • DHCP_discover() : PCDHCP.C
  • DHCP_do_boot() : PCDHCP.H, PCDHCP.C
  • DHCP_exit() : PCDHCP.C
  • dhcp_fsm() : PCDHCP.C
  • DHCP_get_server() : PCDHCP.H, PCDHCP.C
  • DHCP_init() : PCDHCP.H, PCDHCP.C
  • DHCP_is_ack() : PCDHCP.C
  • DHCP_is_nack() : PCDHCP.C
  • DHCP_offer() : PCDHCP.C
  • dhcp_open() : PCDHCP.C
  • dhcp_options_add() : PCDHCP.C
  • DHCP_read_config() : PCDHCP.H, PCDHCP.C
  • DHCP_release() : PCDHCP.H, PCDHCP.C
  • DHCP_release_decline() : PCDHCP.C
  • DHCP_request() : PCDHCP.C
  • dhcp_set_config_func() : TCP.H, PCDHCP.H, PCDHCP.C
  • dhcp_set_timers() : PCDHCP.C
  • DHCP_state_BOUND() : PCDHCP.C
  • DHCP_state_INIT() : PCDHCP.C
  • DHCP_state_REBINDING() : PCDHCP.C
  • DHCP_state_REBOOTING() : PCDHCP.C
  • DHCP_state_RENEWING() : PCDHCP.C
  • DHCP_state_REQUESTING() : PCDHCP.C
  • DHCP_state_SELECTING() : PCDHCP.C
  • do_exit() : SOCK_INI.C
  • do_include_file() : PCCONFIG.C
  • do_keepalive() : SOCKET.C
  • dom_strerror() : TCP.H, UDP_DOM.H, UDP_DOM.C
  • DWORD : WATTCP.H
  • dword_str() : MISC.H, MISC.C
  • dyndns_params() : DYNIP.C
  • dynip_config() : DYNIP.C
  • dynip_exit() : DYNIP.C

- e -

  • echo_discard_daemon() : ECHO.C
  • echo_discard_exit() : ECHO.C
  • echo_discard_init() : ECHO.H, ECHO.C
  • echo_discard_start() : ECHO.H, ECHO.C
  • erase_config() : PCDHCP.C
  • error() : LANGUAGE.L
  • eth_address : WATTCP.H
  • eth_ifnet() : IOCTL.C
  • eth_mac_format() : PCSED.C
  • eth_mac_xmit() : PCSED.C
  • eval_timers() : PCDHCP.C
  • exc_app_start : WDPMI.C
  • exc_select() : SELECT.C
  • except_handler() : SOCK_INI.C
  • exit_localport() : PORTS.C
  • ExpandVarStr() : PCCONFIG.H, PCCONFIG.C
  • extract_cname() : UDP_DOM.C

- f -

  • fcntlsocket() : SOCKET.H, FCNTL.C
  • fddi_address : WATTCP.H
  • fddi_mac_format() : PCSED.C
  • find_adapter() : WINPCAP.C
  • find_free_raw_sock() : SOCKET.C
  • fix_llc_head() : PCSED.C
  • fopen_excl() : MISC.H, MISC.C
  • fortify_report() : MISC.C

- g -

  • get_argv0() : PCCONFIG.H, PCCONFIG.C
  • get_cpu_speed() : TIMER.H, TIMER.C
  • get_day_num() : MISC.H, MISC.C
  • get_header() : DYNIP.C
  • get_pkt_type_eth() : SOCKET.C
  • get_rmode_data() : PCPKT.C
  • get_sol_opt() : SOCKOPT.C
  • get_timediff() : TCP.H, TIMER.H, TIMER.C
  • get_url() : DYNIP.C
  • getdomainname() : SOCKET.H, BSDNAME.C
  • gethostbyaddr6_internal() : GETHOST6.C
  • gethostbyaddr_internal() : GETHOST.C
  • gethostbyname_internal() : GETHOST.C
  • gethostent() : NETDB.H, GETHOST.C
  • gethostid() : SOCKET.H, BSDNAME.C
  • GetHostsFile() : GETHOST.C, GET_XBY.H

- h -

  • has_8254 : TIMER.C
  • has_rdtsc : TIMER.C
  • hires_timer() : TCP.H, TIMER.H, TIMER.C
  • hostname : PCTCP.C

- i -

  • icmp4_dump() : PCDBUG.C
  • icmp_bogus() : PCICMP.C
  • icmp_check() : PCICMP.C
  • icmp_doredirect() : PCICMP.H, PCICMP.C
  • icmp_handler() : PCICMP.H, PCICMP.C
  • icmp_id : PCARP.C
  • icmp_loopback() : LOOPBACK.C
  • icmp_redirect() : PCICMP.C
  • icmp_send() : PCICMP.C
  • icmp_send_timexceed() : PCICMP.H, PCICMP.C
  • icmp_send_unreach() : PCICMP.H, PCICMP.C
  • icmp_upcall : WATTCP.H
  • iconv_init() : IDNA.H
  • iconv_strerror() : IDNA.H
  • IDNA_convert_from_ACE() : IDNA.H
  • IDNA_convert_to_ACE() : IDNA.H
  • iface_ioctrl() : IOCTL.C
  • in_checksum() : TCP.H, CHKSUM.H, CHKSUM.C
  • inet_lnaof() : INET.H, NETADDR.C
  • inet_makeaddr() : INET.H, NETADDR.C
  • inet_netof() : INET.H, NETADDR.C
  • inet_ntop() : INET.H, PRESADDR.C
  • inet_ntop4() : PRESADDR.C
  • inet_ntop6() : PRESADDR.C
  • inet_pton() : INET.H, PRESADDR.C
  • inet_pton4() : PRESADDR.C
  • inet_pton6() : PRESADDR.C
  • init_frag() : IP4_FRAG.C
  • init_localport() : PORTS.C, PCTCP.H
  • init_misc() : TCP.H, MISC.H, MISC.C
  • init_sockets() : SOCKET.C
  • init_timers() : TIMER.H, TIMER.C
  • init_userSuppliedTimerTick() : TCP.H, TIMER.H, TIMER.C
  • int64 : WATTCP.H
  • inuse : SOCKET.C
  • ip4_transmit() : TRANSMIT.C
  • ip6_address : WATTCP.H
  • ip6_transmit() : TRANSMIT.C
  • is_known_host() : PCSARP.C
  • is_on_LAN() : PCARP.C
  • is_secure_host() : PCSARP.C
  • is_watt32_func() : HIGHC.C
  • isaddr() : TCP.H, NETADDR.H, NETADDR.C
  • isaddr_dotless() : NETADDR.H, NETADDR.C

- k -

  • keyword_not_found() : PCCONFIG.C

- l -

  • LAN_lookup() : PCARP.C
  • LAN_lookup_pending() : PCARP.C
  • LAN_start_lookup() : PCARP.C
  • list_lookup() : MISC.H, MISC.C
  • lookup_domain() : UDP_DOM.C

- m -

  • MAC_address() : MISC.H, MISC.C
  • mac_tx_format : PCSED.C
  • main() : ECHO.C
  • make_boot_header() : PCDHCP.C
  • MatchIp6Dest() : PCDBUG.C
  • MAX_DAEMONS : PCTCP.C
  • mcast_set : SOCKET.C
  • mtu_blackhole : PCTCP.H, PCTCP.C
  • mtu_discover : PCTCP.H, PCTCP.C
  • my_ip_addr : PCTCP.C

- n -

  • netdb_init() : PCCONFIG.H, PCCONFIG.C
  • new_int_8() : TIMER.C
  • next_domain() : UDP_DOM.C
  • null_mac_format() : PCSED.C

- o -

  • old_break : SOCK_INI.C
  • other_raw_socks() : SOCKET.C
  • other_tcp_listeners() : SOCKET.C

- p -

  • pack_domain() : UDP_DOM.C
  • parse_config_pass_1() : WINPCAP.C, PCPKT.C
  • parse_config_table() : TCP.H, PCCONFIG.H, PCCONFIG.C
  • parse_dyndns_response() : DYNIP.C
  • parse_myip_address() : DYNIP.C
  • period() : PCDHCP.C
  • pkt16_drvr_init() : PCPKT.C
  • pkt_api_entry() : PCPKT.C
  • pkt_buf_wipe() : WINPCAP.H, WINPCAP.C, PCPKT.H, PCPKT.C
  • pkt_dropped() : WINPCAP.C, PCPKT.H, PCPKT.C
  • pkt_drvr_info() : PCPKT.C
  • pkt_enqueue() : PCPKT.C
  • pkt_eth_init() : WINPCAP.H, WINPCAP.C, PCPKT.H, PCPKT.C
  • pkt_free_pkt() : WINPCAP.H, WINPCAP.C, PCPKT.H, PCPKT.C
  • pkt_get_addr() : WINPCAP.H, WINPCAP.C, PCPKT.H, PCPKT.C
  • pkt_get_api_ver() : WINPCAP.H, WINPCAP.C, PCPKT.H, PCPKT.C
  • pkt_get_drvr_ver() : WINPCAP.H, WINPCAP.C, PCPKT.H, PCPKT.C
  • pkt_get_mac_len() : PCPKT.C
  • pkt_get_mtu() : WINPCAP.H, WINPCAP.C, PCPKT.H, PCPKT.C
  • pkt_get_multicast_list() : WINPCAP.H, WINPCAP.C, PCPKT.H, PCPKT.C
  • pkt_get_params() : PCPKT.H, PCPKT.C
  • pkt_get_rcv_mode() : WINPCAP.H, WINPCAP.C, PCPKT.H, PCPKT.C
  • pkt_get_stats() : WINPCAP.H, WINPCAP.C, PCPKT.H, PCPKT.C
  • pkt_get_vector() : PCPKT.H, PCPKT.C
  • pkt_recv_thread() : WINPCAP.C
  • pkt_release() : WINPCAP.H, WINPCAP.C, PCPKT.H, PCPKT.C
  • pkt_release_handle() : PCPKT.H, PCPKT.C
  • pkt_reset_handle() : PCPKT.H, PCPKT.C
  • pkt_send() : WINPCAP.H, WINPCAP.C, PCPKT.H, PCPKT.C
  • pkt_set_access() : PCPKT.C
  • pkt_set_addr() : WINPCAP.H, WINPCAP.C, PCPKT.H, PCPKT.C
  • pkt_set_multicast_list() : WINPCAP.H, WINPCAP.C, PCPKT.H, PCPKT.C
  • pkt_set_rcv_mode() : WINPCAP.H, WINPCAP.C, PCPKT.H, PCPKT.C
  • pkt_strerror() : WINPCAP.C, PCPKT.H, PCPKT.C
  • pkt_tx_buf() : PCPKT.H, PCPKT.C
  • pkt_waiting() : WINPCAP.H, WINPCAP.C, PCPKT.H, PCPKT.C
  • PmGlueEnd() : X32VM.C
  • poll_recv_queue() : PCSED.C
  • ppp_input() : PPP.H, PPP.C
  • pppoe_discovery() : PPPOE.C
  • pppoe_exit() : PPPOE.H, PPPOE.C
  • pppoe_handler() : PPPOE.H, PPPOE.C
  • pppoe_init() : PPPOE.H, PPPOE.C
  • pppoe_is_up() : PPPOE.H, PPPOE.C
  • pppoe_mac_format() : PPPOE.H, PPPOE.C
  • pppoe_send_disc() : PPPOE.C
  • pppoe_send_sess() : PPPOE.H, PPPOE.C
  • pppoe_start() : PPPOE.H, PPPOE.C
  • pppoe_wait() : PPPOE.C
  • prev_cfg_hook : PCARP.C
  • ProtoHandler : WATTCP.H
  • put_hardware_opt() : PCDHCP.C
  • put_request_list() : PCDHCP.C

- q -

  • query_init() : UDP_DOM.C
  • query_init_ip4() : UDP_REV.C
  • query_init_ip6() : UDP_REV.C

- r -

  • Random() : TCP.H, MISC.H, MISC.C
  • RandomWait() : MISC.H, MISC.C
  • raw6_rx_buf() : SOCKOPT.C
  • raw6_tx_buf() : SOCKOPT.C
  • raw_read() : PCTCP.C
  • raw_rx_buf() : SOCKOPT.C
  • raw_tx_buf() : SOCKOPT.C
  • read_response() : UDP_REV.C, UDP_DOM.C
  • ReceiveModes : WINPCAP.H, PCPKT.H
  • release_real_mem() : PCPKT.C
  • ReopenHostFile() : GETHOST.C
  • res_mkquery() : RESOLV.H, RES_MKQU.C
  • resolve() : TCP.H, UDP_DOM.H, UDP_DOM.C
  • resolve_ip() : OLDSTUFF.C
  • reverse_lookup() : UDP_REV.C
  • reverse_lookup_myip() : UDP_REV.C, UDP_DOM.H
  • rip() : TCP.H, STRINGS.H, STRINGS.C
  • rmcb : X32VM.C
  • route_check_timeouts() : PCARP.C
  • route_lookup() : PCARP.C
  • route_lookup_pending() : PCARP.C
  • route_start_lookup() : PCARP.C
  • rtt_cache : PCTCP.C
  • run_daemons() : PCTCP.C
  • rundown_add() : MISC.H, MISC.C
  • rundown_dump() : MISC.H, MISC.C
  • rundown_run() : MISC.H, MISC.C
  • RXMODE_ALL_LOCAL : WINPCAP.H
  • RXMODE_BROADCAST : WINPCAP.H, PCPKT.H
  • RXMODE_DIRECT : WINPCAP.H, PCPKT.H
  • RXMODE_MULTICAST1 : WINPCAP.H, PCPKT.H
  • RXMODE_MULTICAST2 : WINPCAP.H, PCPKT.H
  • RXMODE_OFF : WINPCAP.H, PCPKT.H
  • RXMODE_PROMISCOUS : WINPCAP.H, PCPKT.H

- s -

  • sarp_init() : PCSARP.H, PCSARP.C
  • sarp_parse() : PCSARP.C
  • sarp_receive() : PCSARP.C
  • sel_min_block : SELECT.C
  • select_s() : TCP.H, SOCKET.H, SELECT.C
  • send_loopback() : PCSED.C
  • send_query() : UDP_DOM.C
  • server_error() : UDP_DOM.C
  • set_cbreak() : PC_CBRK.C, MISC.H
  • set_eaddr() : PCCONFIG.C
  • set_ethip() : PCCONFIG.C
  • set_my_ip() : PCDHCP.C
  • set_proto() : SOCKET.C
  • set_request_list() : PCDHCP.C
  • set_timediff() : TCP.H, TIMER.H, TIMER.C
  • set_timeout() : TCP.H, TIMER.H, TIMER.C
  • set_ttimeout() : OLDSTUFF.C
  • set_txmode() : WINPCAP.C
  • set_user_class() : PCDHCP.C
  • set_utc_offset() : GETTOD.H, GETTOD.C
  • set_value() : PCCONFIG.C
  • set_vend_class() : PCDHCP.C
  • setdomainname() : SOCKET.H, BSDNAME.C
  • sethostid() : BSDNAME.C
  • sethostname() : SOCKET.H, BSDNAME.C
  • setup_pkt_inf() : PCPKT.C
  • setup_sig_handlers() : SOCK_INI.C
  • shutdown() : SOCKET.H, SHUTDOWN.C
  • sig_handler_watt() : PC_CBRK.C, MISC.H
  • sign_opt : PCTCP.C
  • sin_mask : PCTCP.C
  • sk_list_del() : SOCKET.C
  • sk_scope : BSDDBUG.C
  • sock_abort() : PCTCP.H, PCTCP.C
  • sock_close() : PCTCP.H, PCTCP.C
  • sock_daemon() : SOCKET.C
  • sock_dataready() : SOCK_IO.C, PCTCP.H
  • sock_enqueue() : PCTCP.H, PCTCP.C
  • sock_exit() : TCP.H, SOCK_INI.H, SOCK_INI.C
  • sock_fastread() : PCTCP.H, PCTCP.C
  • sock_fastwrite() : PCTCP.H, PCTCP.C
  • sock_find_fd() : SOCKET.C
  • sock_find_tcp() : SOCKET.C
  • sock_find_udp() : SOCKET.C
  • sock_flush() : PCTCP.H, PCTCP.C
  • sock_flushnext() : PCTCP.H, PCTCP.C
  • sock_fortify_exit() : SOCKET.C
  • sock_getcw() : SOCK_IO.C
  • sock_getsw() : SOCK_IO.C
  • sock_init_called : SOCK_INI.C
  • sock_noflush() : PCTCP.H, PCTCP.C
  • sock_packet_add() : SOCKET.C
  • sock_packet_receive() : SOCKET.H, SOCKET.C
  • sock_putcw() : SOCK_IO.C
  • sock_puts() : SOCK_IO.C, PCTCP.H
  • sock_putsw() : SOCK_IO.C
  • sock_raw4_recv() : SOCKET.C
  • sock_raw_add() : SOCKET.C
  • sock_raw_del() : SOCKET.C
  • sock_read() : PCTCP.H, PCTCP.C
  • sock_reduce_mss() : PCTCP.C
  • sock_sig_exit() : TCP.H, SOCK_INI.H, SOCK_INI.C
  • sock_sturdy() : OLDSTUFF.C
  • sock_write() : PCTCP.H, PCTCP.C
  • sock_yield() : PCTCP.C
  • socket() : SOCKET.H, SOCKET.C
  • socket_op_demux() : SOCKET.C
  • socketpair() : SOCKET.C
  • socklist_add() : SOCKET.C
  • split_ip6() : SPLIT.C
  • start_day : TIMER.C
  • start_time : TIMER.C
  • state_name() : PCDHCP.C
  • std_negotiation() : PPP.C
  • std_write_config() : PCDHCP.C
  • store_alt_address() : UDP_DOM.C
  • stream_cancel() : SOCKET.C
  • StrLcpy() : STRINGS.H, STRINGS.C
  • strltrim() : STRINGS.H, STRINGS.C
  • strntrimcpy() : STRINGS.H, STRINGS.C
  • strreplace() : STRINGS.H, STRINGS.C
  • strrtrim() : STRINGS.H, STRINGS.C
  • survive_bootp : SOCK_INI.C
  • survive_dhcp : SOCK_INI.C
  • survive_eth : SOCK_INI.C
  • survive_rarp : SOCK_INI.C

- t -

  • tcp_cbreak() : TCP.H, PC_CBRK.C, MISC.H
  • tcp_cbrk() : OLDSTUFF.C
  • tcp_checksum() : PCTCP.C
  • tcp_CLOSE_TO : PCTCP.C
  • tcp_do_boot() : SOCK_INI.C
  • tcp_established() : PCTCP.H, PCTCP.C
  • tcp_findseq() : PCTCP.C
  • tcp_init() : SOCK_INI.C
  • tcp_inject_config() : TCP.H, PCCONFIG.H, PCCONFIG.C
  • tcp_inject_config_direct() : PCCONFIG.C
  • tcp_is_init : SOCK_INI.C
  • tcp_keep_idle : PCTCP.C
  • tcp_keep_intvl : PCTCP.C
  • tcp_listen() : PCTCP.H, PCTCP.C
  • tcp_max_idle : PCTCP.C
  • tcp_MAX_VJSA : PCTCP.C
  • tcp_MAX_VJSD : PCTCP.C
  • tcp_nagle : PCTCP.H, PCTCP.C
  • tcp_no_arp() : PCTCP.C
  • tcp_open() : PCTCP.H, PCTCP.C
  • tcp_OPEN_TO : PCTCP.C
  • tcp_opt_maxsegment() : PCTCP.C
  • tcp_opt_padding() : PCTCP.C
  • tcp_opt_timestamp() : PCTCP.C
  • tcp_opt_ts : PCTCP.H, PCTCP.C
  • tcp_options() : PCTCP.C
  • tcp_post_init() : SOCK_INI.C
  • tcp_process_data() : TCP_FSM.C
  • tcp_process_options() : TCP_FSM.C
  • tcp_read() : PCTCP.C
  • tcp_reassemble() : TCP_FSM.C
  • tcp_receive() : RECEIVE.C
  • tcp_recv_win : PCTCP.C
  • tcp_RETRAN_TIME : PCTCP.C
  • tcp_Retransmitter() : PCTCP.H, PCTCP.C
  • tcp_RST_TIME : PCTCP.C
  • tcp_RTO_ADD : PCTCP.C
  • tcp_RTO_BASE : PCTCP.C
  • tcp_RTO_SCALE : PCTCP.C
  • tcp_rtt_win() : PCTCP.C
  • tcp_set_debug_state() : TCP.H, PCCONFIG.H, PCCONFIG.C
  • tcp_set_window() : TCP_FSM.C
  • tcp_shutdown() : SOCK_INI.C
  • tcp_sock_daemon() : SOCKET.C
  • tcp_sockreset() : PCTCP.C
  • tcp_synsent_state() : TCP_FSM.C
  • tcp_tick() : TCP.H, PCTCP.H, PCTCP.C
  • tcp_transmit() : TRANSMIT.C
  • tcp_upd_win() : PCTCP.C
  • tcp_write() : PCTCP.C
  • tftp_exit() : TFTP.C
  • tftp_init() : TFTP.H, TFTP.C
  • tok_address : WATTCP.H
  • tok_ifnet() : IOCTL.C
  • tok_mac_format() : PCSED.C
  • transient_cfg : PCDHCP.C

- u -

  • udp_checksum() : PCTCP.C
  • udp_close() : PCTCP.C
  • udp_demux() : PCTCP.C
  • udp_handler() : ECHO.C
  • udp_listen() : PCTCP.H, PCTCP.C
  • udp_loopback() : LOOPBACK.C
  • udp_open() : PCTCP.H, PCTCP.C
  • udp_read() : PCTCP.C
  • udp_receive() : RECEIVE.C
  • udp_SetTTL() : PCTCP.H, PCTCP.C
  • udp_sock_daemon() : SOCKET.C
  • udp_write() : PCTCP.C
  • UINT : WATTCP.H
  • uint64 : WATTCP.H
  • unpack_domain() : UDP_DOM.C
  • update_in_stat() : PCSTAT.H, PCSTAT.C
  • update_out_stat() : PCSTAT.H, PCSTAT.C
  • url_free() : DYNIP.C
  • url_parse() : DYNIP.C
  • use_except : SOCK_INI.C
  • use_rdtsc : TIMER.C
  • UserHandler : WATTCP.H
  • userName : PPPOE.C
  • userTimerTick() : TCP.H, TIMER.H, TIMER.C
  • using_int8 : TIMER.C
  • usr_post_init : PCCONFIG.C

- v -

  • vendor_version() : SOCKET.C

- w -

  • Wait() : MISC.H, MISC.C
  • waterm_ioctrl() : IOCTL.C
  • watt_kbhit() : TCP.H, MISC.H, MISC.C
  • watt_sock_init() : TCP.H, SOCK_INI.H, SOCK_INI.C
  • win32_dos_box : MISC.C
  • WORD : WATTCP.H
  • write_config() : PCDHCP.C
Generated on Wed Jan 25 15:42:44 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: Globals - Enumerations

  • config_tab_types : PCCONFIG.H
  • ReceiveModes : WINPCAP.H, PCPKT.H
Generated on Wed Jan 25 15:42:44 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: Globals - Enumeration values

  • ARG_ATOB : PCCONFIG.H
  • ARG_ATOI : PCCONFIG.H
  • ARG_ATOIP : PCCONFIG.H
  • ARG_ATOW : PCCONFIG.H
  • ARG_ATOX_B : PCCONFIG.H
  • ARG_ATOX_D : PCCONFIG.H
  • ARG_ATOX_W : PCCONFIG.H
  • ARG_FUNC : PCCONFIG.H
  • ARG_RESOLVE : PCCONFIG.H
  • ARG_STRCPY : PCCONFIG.H
  • ARG_STRDUP : PCCONFIG.H
  • RXMODE_ALL_LOCAL : WINPCAP.H
  • RXMODE_BROADCAST : WINPCAP.H, PCPKT.H
  • RXMODE_DIRECT : WINPCAP.H, PCPKT.H
  • RXMODE_MULTICAST1 : WINPCAP.H, PCPKT.H
  • RXMODE_MULTICAST2 : WINPCAP.H, PCPKT.H
  • RXMODE_OFF : WINPCAP.H, PCPKT.H
  • RXMODE_PROMISCOUS : WINPCAP.H, PCPKT.H
Generated on Wed Jan 25 15:42:44 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: Globals - Functions

- _ -

  • __get_sock_from_s() : TCP.H, SOCKET.H, SOCKET.C
  • _arp_add_cache() : PCARP.H, PCARP.C
  • _arp_add_gateway() : PCARP.H, PCARP.C
  • _arp_check_gateways() : PCARP.H, PCARP.C
  • _arp_check_own_ip() : PCARP.H, PCARP.C
  • _arp_debug_dump() : PCARP.H, PCARP.C
  • _arp_delete_cache() : PCARP.H, PCARP.C
  • _arp_handler() : PCARP.H, PCARP.C
  • _arp_have_default_gw() : PCARP.H, PCARP.C
  • _arp_init() : PCARP.H, PCARP.C
  • _arp_kill_gateways() : PCARP.H, PCARP.C
  • _arp_list_cache() : PCARP.H, PCARP.C
  • _arp_list_gateways() : PCARP.H, PCARP.C
  • _arp_register() : TCP.H, PCARP.H, PCARP.C
  • _arp_reply() : PCARP.H, PCARP.C
  • _arp_resolve() : TCP.H, PCARP.H, PCARP.C
  • _bsd_socket_hook() : PCTCP.C
  • _chk_ping() : TCP.H, PCPING.H, PCPING.C, PCICMP.H
  • _dx_real_alloc() : X32VM.H, X32VM.C
  • _eth_arrived() : TCP.H, PCSED.H, PCSED.C
  • _eth_formatpacket() : TCP.H, PCSED.H, PCSED.C
  • _eth_free() : TCP.H, PCSED.H, PCSED.C
  • _eth_get_hwtype() : TCP.H, PCSED.H, PCSED.C
  • _eth_init() : TCP.H, PCSED.H, PCSED.C
  • _eth_join_mcast_group() : PCSED.H, PCSED.C
  • _eth_leave_mcast_group() : PCSED.H, PCSED.C
  • _eth_mac_dst() : PCSED.H, PCSED.C
  • _eth_mac_hdr() : PCSED.H, PCSED.C
  • _eth_mac_src() : PCSED.H, PCSED.C
  • _eth_mac_typ() : PCSED.H, PCSED.C
  • _eth_release() : TCP.H, PCSED.H, PCSED.C
  • _eth_send() : TCP.H, PCSED.H, PCSED.C
  • _eth_set_addr() : TCP.H, PCSED.H, PCSED.C
  • _get_ip4_id() : IP4_OUT.H, IP4_OUT.C
  • _get_machine_name() : BSDNAME.H, BSDNAME.C
  • _get_this_ip4_id() : IP4_OUT.H, IP4_OUT.C
  • _gethostid() : TCP.H, BSDNAME.H, BSDNAME.C
  • _gethostid6() : BSDNAME.H, BSDNAME.C
  • _getpeername() : BSDNAME.H, BSDNAME.C
  • _getsockname() : BSDNAME.H, BSDNAME.C
  • _inet6_addr() : NETADDR.H, NETADDR.C
  • _inet6_ntoa() : NETADDR.H, NETADDR.C
  • _inet_addr() : TCP.H, NETADDR.H, NETADDR.C
  • _inet_atoeth() : NETADDR.H, NETADDR.C
  • _inet_ntoa() : TCP.H, NETADDR.H, NETADDR.C
  • _ip4_handler() : IP4_IN.H, IP4_IN.C
  • _ip4_output() : IP4_OUT.H, IP4_OUT.C
  • _ip4_send_fragments() : IP4_OUT.H, IP4_OUT.C
  • _ip6_checksum() : CHKSUM.H, CHKSUM.C
  • _ip6_output() : IP6_OUT.H, IP6_OUT.C
  • _ip6_tcp_checksum() : CHKSUM.H, CHKSUM.C
  • _ip6_udp_checksum() : CHKSUM.H, CHKSUM.C
  • _ping() : PCPING.H, PCPING.C
  • _rarp_handler() : PCRARP.C
  • _sarp_debug_dump() : PCSARP.C
  • _sethostid() : TCP.H, BSDNAME.H, BSDNAME.C
  • _sethostid6() : BSDNAME.H, BSDNAME.C
  • _sock_append() : SOCKET.H, ACCEPT.C
  • _sock_calloc() : SOCKET.H, SOCKET.C
  • _sock_chk_sockaddr() : SOCKET.H, SOCKET.C
  • _sock_crit_start() : SOCKET.H, SOCKET.C
  • _sock_crit_stop() : SOCKET.H, SOCKET.C
  • _sock_del_fd() : SOCKET.H, SOCKET.C
  • _sock_dos_fd() : SOCKET.H, SOCKET.C
  • _sock_free_rcv_buf() : SOCKET.H, SOCKET.C
  • _sock_half_open() : SOCKET.H, SOCKET.C
  • _sock_set_rcv_buf() : SOCKET.H, SOCKET.C
  • _socklist_find() : SOCKET.H, SOCKET.C
  • _TCP6_listen() : SOCKET.H, SOCKET.C
  • _TCP6_open() : SOCKET.H, SOCKET.C
  • _tcp_abort() : PCTCP.H, PCTCP.C
  • _tcp_cancel() : PCTCP.H, PCTCP.C
  • _tcp_close() : PCTCP.H, PCTCP.C
  • _tcp_handler() : PCTCP.H, PCTCP.C
  • _tcp_keepalive() : PCTCP.H, PCTCP.C
  • _TCP_open() : SOCKET.H, SOCKET.C
  • _tcp_send() : PCTCP.H, PCTCP.C
  • _tcp_send_reset() : PCTCP.H, PCTCP.C
  • _tcp_sendsoon() : PCTCP.H, PCTCP.C
  • _tcp_unthread() : PCTCP.H, PCTCP.C
  • _UDP6_listen() : SOCKET.H, SOCKET.C
  • _UDP6_open() : SOCKET.H, SOCKET.C
  • _udp_cancel() : PCTCP.H, PCTCP.C
  • _udp_handler() : PCTCP.H, PCTCP.C
  • _UDP_open() : SOCKET.H, SOCKET.C
  • _w32_intel() : SWAP.H, MISC.C
  • _w32_intel16() : SWAP.H, MISC.C
  • _w32_intr() : MISC.C
  • _watt_user_config() : TCP.H, SOCK_INI.C, PCCONFIG.H

- a -

  • Abort() : LANGUAGE.L
  • accept() : SOCKET.H, ACCEPT.C
  • add_ping() : PCPING.H, PCPING.C
  • addwattcpd() : PCTCP.H, PCTCP.C
  • afd_list_init() : GET_AI.C
  • arcnet_mac_format() : PCSED.C
  • arp_add_server() : PCDHCP.C
  • arp_check_timeouts() : PCARP.C
  • arp_daemon() : PCARP.C
  • arp_lookup() : PCARP.H, PCARP.C
  • arp_lookup_fixed() : PCARP.H, PCARP.C
  • arp_lookup_pending() : PCARP.H, PCARP.C
  • arp_move_entry() : PCARP.C
  • arp_send() : PCARP.C
  • arp_send_request() : PCARP.C
  • arp_start_lookup() : PCARP.H, PCARP.C
  • assert_fail() : MISC.H, MISC.C
  • aton() : TCP.H, NETADDR.H, NETADDR.C
  • aton_dotless() : NETADDR.H, NETADDR.C
  • atox() : STRINGS.H, STRINGS.C

- b -

  • bind() : SOCKET.H, BIND.C
  • BOOTP_do_boot() : PCBOOTP.H, PCBOOTP.C
  • build_pad() : PPPOE.C

- c -

  • change_ip_addr() : PCDHCP.C
  • check_errno_version() : SOCKET.C
  • check_intr_num() : PCPKT.C
  • chk_timeout() : TCP.H, TIMER.H, TIMER.C
  • chkip_method() : DYNIP.C
  • client_error() : UDP_DOM.C
  • CloseHostFile() : GETHOST.C, GET_XBY.H
  • cmp_timers() : TCP.H, TIMER.H, TIMER.C
  • compare() : PCPING.C
  • crtdbg_report() : MISC.C

- d -

  • dbug_exit() : PCDBUG.C
  • delwattcpd() : PCTCP.H, PCTCP.C
  • DHCP_arp_check() : PCDHCP.C
  • DHCP_cfg_hook() : PCDHCP.C
  • DHCP_discover() : PCDHCP.C
  • DHCP_do_boot() : PCDHCP.H, PCDHCP.C
  • DHCP_exit() : PCDHCP.C
  • dhcp_fsm() : PCDHCP.C
  • DHCP_get_server() : PCDHCP.H, PCDHCP.C
  • DHCP_init() : PCDHCP.H, PCDHCP.C
  • DHCP_is_ack() : PCDHCP.C
  • DHCP_is_nack() : PCDHCP.C
  • DHCP_offer() : PCDHCP.C
  • dhcp_open() : PCDHCP.C
  • dhcp_options_add() : PCDHCP.C
  • DHCP_read_config() : PCDHCP.H, PCDHCP.C
  • DHCP_release() : PCDHCP.H, PCDHCP.C
  • DHCP_release_decline() : PCDHCP.C
  • DHCP_request() : PCDHCP.C
  • dhcp_set_config_func() : TCP.H, PCDHCP.H, PCDHCP.C
  • dhcp_set_timers() : PCDHCP.C
  • DHCP_state_BOUND() : PCDHCP.C
  • DHCP_state_INIT() : PCDHCP.C
  • DHCP_state_REBINDING() : PCDHCP.C
  • DHCP_state_REBOOTING() : PCDHCP.C
  • DHCP_state_RENEWING() : PCDHCP.C
  • DHCP_state_REQUESTING() : PCDHCP.C
  • DHCP_state_SELECTING() : PCDHCP.C
  • do_exit() : SOCK_INI.C
  • do_include_file() : PCCONFIG.C
  • do_keepalive() : SOCKET.C
  • dom_strerror() : TCP.H, UDP_DOM.H, UDP_DOM.C
  • dword_str() : MISC.H, MISC.C
  • dyndns_params() : DYNIP.C
  • dynip_config() : DYNIP.C
  • dynip_exit() : DYNIP.C

- e -

  • echo_discard_daemon() : ECHO.C
  • echo_discard_exit() : ECHO.C
  • echo_discard_init() : ECHO.H, ECHO.C
  • echo_discard_start() : ECHO.H, ECHO.C
  • erase_config() : PCDHCP.C
  • error() : LANGUAGE.L
  • eth_ifnet() : IOCTL.C
  • eth_mac_format() : PCSED.C
  • eth_mac_xmit() : PCSED.C
  • eval_timers() : PCDHCP.C
  • exc_select() : SELECT.C
  • except_handler() : SOCK_INI.C
  • exit_localport() : PORTS.C
  • ExpandVarStr() : PCCONFIG.H, PCCONFIG.C
  • extract_cname() : UDP_DOM.C

- f -

  • fcntlsocket() : SOCKET.H, FCNTL.C
  • fddi_mac_format() : PCSED.C
  • find_adapter() : WINPCAP.C
  • find_free_raw_sock() : SOCKET.C
  • fix_llc_head() : PCSED.C
  • fopen_excl() : MISC.H, MISC.C
  • fortify_report() : MISC.C

- g -

  • get_argv0() : PCCONFIG.H, PCCONFIG.C
  • get_cpu_speed() : TIMER.H, TIMER.C
  • get_day_num() : MISC.H, MISC.C
  • get_header() : DYNIP.C
  • get_pkt_type_eth() : SOCKET.C
  • get_rmode_data() : PCPKT.C
  • get_sol_opt() : SOCKOPT.C
  • get_timediff() : TCP.H, TIMER.H, TIMER.C
  • get_url() : DYNIP.C
  • getdomainname() : SOCKET.H, BSDNAME.C
  • gethostbyaddr6_internal() : GETHOST6.C
  • gethostbyaddr_internal() : GETHOST.C
  • gethostbyname_internal() : GETHOST.C
  • gethostent() : NETDB.H, GETHOST.C
  • gethostid() : SOCKET.H, BSDNAME.C
  • GetHostsFile() : GETHOST.C, GET_XBY.H

- h -

  • hires_timer() : TCP.H, TIMER.H, TIMER.C

- i -

  • icmp4_dump() : PCDBUG.C
  • icmp_bogus() : PCICMP.C
  • icmp_check() : PCICMP.C
  • icmp_doredirect() : PCICMP.H, PCICMP.C
  • icmp_handler() : PCICMP.H, PCICMP.C
  • icmp_loopback() : LOOPBACK.C
  • icmp_redirect() : PCICMP.C
  • icmp_send() : PCICMP.C
  • icmp_send_timexceed() : PCICMP.H, PCICMP.C
  • icmp_send_unreach() : PCICMP.H, PCICMP.C
  • iconv_init() : IDNA.H
  • iconv_strerror() : IDNA.H
  • IDNA_convert_from_ACE() : IDNA.H
  • IDNA_convert_to_ACE() : IDNA.H
  • iface_ioctrl() : IOCTL.C
  • in_checksum() : TCP.H, CHKSUM.H, CHKSUM.C
  • inet_lnaof() : INET.H, NETADDR.C
  • inet_makeaddr() : INET.H, NETADDR.C
  • inet_netof() : INET.H, NETADDR.C
  • inet_ntop() : INET.H, PRESADDR.C
  • inet_ntop4() : PRESADDR.C
  • inet_ntop6() : PRESADDR.C
  • inet_pton() : INET.H, PRESADDR.C
  • inet_pton4() : PRESADDR.C
  • inet_pton6() : PRESADDR.C
  • init_frag() : IP4_FRAG.C
  • init_localport() : PORTS.C, PCTCP.H
  • init_misc() : TCP.H, MISC.H, MISC.C
  • init_sockets() : SOCKET.C
  • init_timers() : TIMER.H, TIMER.C
  • init_userSuppliedTimerTick() : TCP.H, TIMER.H, TIMER.C
  • ip4_transmit() : TRANSMIT.C
  • ip6_transmit() : TRANSMIT.C
  • is_known_host() : PCSARP.C
  • is_on_LAN() : PCARP.C
  • is_secure_host() : PCSARP.C
  • is_watt32_func() : HIGHC.C
  • isaddr() : TCP.H, NETADDR.H, NETADDR.C
  • isaddr_dotless() : NETADDR.H, NETADDR.C

- k -

  • keyword_not_found() : PCCONFIG.C

- l -

  • LAN_lookup() : PCARP.C
  • LAN_lookup_pending() : PCARP.C
  • LAN_start_lookup() : PCARP.C
  • list_lookup() : MISC.H, MISC.C
  • lookup_domain() : UDP_DOM.C

- m -

  • MAC_address() : MISC.H, MISC.C
  • main() : ECHO.C
  • make_boot_header() : PCDHCP.C
  • MatchIp6Dest() : PCDBUG.C

- n -

  • netdb_init() : PCCONFIG.H, PCCONFIG.C
  • new_int_8() : TIMER.C
  • next_domain() : UDP_DOM.C
  • null_mac_format() : PCSED.C

- o -

  • other_raw_socks() : SOCKET.C
  • other_tcp_listeners() : SOCKET.C

- p -

  • pack_domain() : UDP_DOM.C
  • parse_config_pass_1() : WINPCAP.C, PCPKT.C
  • parse_config_table() : TCP.H, PCCONFIG.H, PCCONFIG.C
  • parse_dyndns_response() : DYNIP.C
  • parse_myip_address() : DYNIP.C
  • period() : PCDHCP.C
  • pkt16_drvr_init() : PCPKT.C
  • pkt_api_entry() : PCPKT.C
  • pkt_buf_wipe() : WINPCAP.H, WINPCAP.C, PCPKT.H, PCPKT.C
  • pkt_dropped() : WINPCAP.C, PCPKT.H, PCPKT.C
  • pkt_drvr_info() : PCPKT.C
  • pkt_enqueue() : PCPKT.C
  • pkt_eth_init() : WINPCAP.H, WINPCAP.C, PCPKT.H, PCPKT.C
  • pkt_free_pkt() : WINPCAP.H, WINPCAP.C, PCPKT.H, PCPKT.C
  • pkt_get_addr() : WINPCAP.H, WINPCAP.C, PCPKT.H, PCPKT.C
  • pkt_get_api_ver() : WINPCAP.H, WINPCAP.C, PCPKT.H, PCPKT.C
  • pkt_get_drvr_ver() : WINPCAP.H, WINPCAP.C, PCPKT.H, PCPKT.C
  • pkt_get_mac_len() : PCPKT.C
  • pkt_get_mtu() : WINPCAP.H, WINPCAP.C, PCPKT.H, PCPKT.C
  • pkt_get_multicast_list() : WINPCAP.H, WINPCAP.C, PCPKT.H, PCPKT.C
  • pkt_get_params() : PCPKT.H, PCPKT.C
  • pkt_get_rcv_mode() : WINPCAP.H, WINPCAP.C, PCPKT.H, PCPKT.C
  • pkt_get_stats() : WINPCAP.H, WINPCAP.C, PCPKT.H, PCPKT.C
  • pkt_get_vector() : PCPKT.H, PCPKT.C
  • pkt_recv_thread() : WINPCAP.C
  • pkt_release() : WINPCAP.H, WINPCAP.C, PCPKT.H, PCPKT.C
  • pkt_release_handle() : PCPKT.H, PCPKT.C
  • pkt_reset_handle() : PCPKT.H, PCPKT.C
  • pkt_send() : WINPCAP.H, WINPCAP.C, PCPKT.H, PCPKT.C
  • pkt_set_access() : PCPKT.C
  • pkt_set_addr() : WINPCAP.H, WINPCAP.C, PCPKT.H, PCPKT.C
  • pkt_set_multicast_list() : WINPCAP.H, WINPCAP.C, PCPKT.H, PCPKT.C
  • pkt_set_rcv_mode() : WINPCAP.H, WINPCAP.C, PCPKT.H, PCPKT.C
  • pkt_strerror() : WINPCAP.C, PCPKT.H, PCPKT.C
  • pkt_tx_buf() : PCPKT.H, PCPKT.C
  • pkt_waiting() : WINPCAP.H, WINPCAP.C, PCPKT.H, PCPKT.C
  • PmGlueEnd() : X32VM.C
  • poll_recv_queue() : PCSED.C
  • ppp_input() : PPP.H, PPP.C
  • pppoe_discovery() : PPPOE.C
  • pppoe_exit() : PPPOE.H, PPPOE.C
  • pppoe_handler() : PPPOE.H, PPPOE.C
  • pppoe_init() : PPPOE.H, PPPOE.C
  • pppoe_is_up() : PPPOE.H, PPPOE.C
  • pppoe_mac_format() : PPPOE.H, PPPOE.C
  • pppoe_send_disc() : PPPOE.C
  • pppoe_send_sess() : PPPOE.H, PPPOE.C
  • pppoe_start() : PPPOE.H, PPPOE.C
  • pppoe_wait() : PPPOE.C
  • put_hardware_opt() : PCDHCP.C
  • put_request_list() : PCDHCP.C

- q -

  • query_init() : UDP_DOM.C
  • query_init_ip4() : UDP_REV.C
  • query_init_ip6() : UDP_REV.C

- r -

  • Random() : TCP.H, MISC.H, MISC.C
  • RandomWait() : MISC.H, MISC.C
  • raw6_rx_buf() : SOCKOPT.C
  • raw6_tx_buf() : SOCKOPT.C
  • raw_read() : PCTCP.C
  • raw_rx_buf() : SOCKOPT.C
  • raw_tx_buf() : SOCKOPT.C
  • read_response() : UDP_REV.C, UDP_DOM.C
  • release_real_mem() : PCPKT.C
  • ReopenHostFile() : GETHOST.C
  • res_mkquery() : RESOLV.H, RES_MKQU.C
  • resolve() : TCP.H, UDP_DOM.H, UDP_DOM.C
  • resolve_ip() : OLDSTUFF.C
  • reverse_lookup() : UDP_REV.C
  • reverse_lookup_myip() : UDP_REV.C, UDP_DOM.H
  • rip() : TCP.H, STRINGS.H, STRINGS.C
  • route_check_timeouts() : PCARP.C
  • route_lookup() : PCARP.C
  • route_lookup_pending() : PCARP.C
  • route_start_lookup() : PCARP.C
  • run_daemons() : PCTCP.C
  • rundown_add() : MISC.H, MISC.C
  • rundown_dump() : MISC.H, MISC.C
  • rundown_run() : MISC.H, MISC.C

- s -

  • sarp_init() : PCSARP.H, PCSARP.C
  • sarp_parse() : PCSARP.C
  • sarp_receive() : PCSARP.C
  • select_s() : TCP.H, SOCKET.H, SELECT.C
  • send_loopback() : PCSED.C
  • send_query() : UDP_DOM.C
  • server_error() : UDP_DOM.C
  • set_cbreak() : PC_CBRK.C, MISC.H
  • set_eaddr() : PCCONFIG.C
  • set_ethip() : PCCONFIG.C
  • set_my_ip() : PCDHCP.C
  • set_proto() : SOCKET.C
  • set_request_list() : PCDHCP.C
  • set_timediff() : TCP.H, TIMER.H, TIMER.C
  • set_timeout() : TCP.H, TIMER.H, TIMER.C
  • set_ttimeout() : OLDSTUFF.C
  • set_txmode() : WINPCAP.C
  • set_user_class() : PCDHCP.C
  • set_utc_offset() : GETTOD.H, GETTOD.C
  • set_value() : PCCONFIG.C
  • set_vend_class() : PCDHCP.C
  • setdomainname() : SOCKET.H, BSDNAME.C
  • sethostid() : BSDNAME.C
  • sethostname() : SOCKET.H, BSDNAME.C
  • setup_pkt_inf() : PCPKT.C
  • setup_sig_handlers() : SOCK_INI.C
  • shutdown() : SOCKET.H, SHUTDOWN.C
  • sig_handler_watt() : PC_CBRK.C, MISC.H
  • sk_list_del() : SOCKET.C
  • sock_abort() : PCTCP.H, PCTCP.C
  • sock_close() : PCTCP.H, PCTCP.C
  • sock_daemon() : SOCKET.C
  • sock_dataready() : SOCK_IO.C, PCTCP.H
  • sock_enqueue() : PCTCP.H, PCTCP.C
  • sock_exit() : TCP.H, SOCK_INI.H, SOCK_INI.C
  • sock_fastread() : PCTCP.H, PCTCP.C
  • sock_fastwrite() : PCTCP.H, PCTCP.C
  • sock_find_fd() : SOCKET.C
  • sock_find_tcp() : SOCKET.C
  • sock_find_udp() : SOCKET.C
  • sock_flush() : PCTCP.H, PCTCP.C
  • sock_flushnext() : PCTCP.H, PCTCP.C
  • sock_fortify_exit() : SOCKET.C
  • sock_getcw() : SOCK_IO.C
  • sock_getsw() : SOCK_IO.C
  • sock_noflush() : PCTCP.H, PCTCP.C
  • sock_packet_add() : SOCKET.C
  • sock_packet_receive() : SOCKET.H, SOCKET.C
  • sock_putcw() : SOCK_IO.C
  • sock_puts() : SOCK_IO.C, PCTCP.H
  • sock_putsw() : SOCK_IO.C
  • sock_raw4_recv() : SOCKET.C
  • sock_raw_add() : SOCKET.C
  • sock_raw_del() : SOCKET.C
  • sock_read() : PCTCP.H, PCTCP.C
  • sock_reduce_mss() : PCTCP.C
  • sock_sig_exit() : TCP.H, SOCK_INI.H, SOCK_INI.C
  • sock_sturdy() : OLDSTUFF.C
  • sock_write() : PCTCP.H, PCTCP.C
  • sock_yield() : PCTCP.C
  • socket() : SOCKET.H, SOCKET.C
  • socket_op_demux() : SOCKET.C
  • socketpair() : SOCKET.C
  • socklist_add() : SOCKET.C
  • split_ip6() : SPLIT.C
  • state_name() : PCDHCP.C
  • std_negotiation() : PPP.C
  • std_write_config() : PCDHCP.C
  • store_alt_address() : UDP_DOM.C
  • stream_cancel() : SOCKET.C
  • StrLcpy() : STRINGS.H, STRINGS.C
  • strltrim() : STRINGS.H, STRINGS.C
  • strntrimcpy() : STRINGS.H, STRINGS.C
  • strreplace() : STRINGS.H, STRINGS.C
  • strrtrim() : STRINGS.H, STRINGS.C

- t -

  • tcp_cbreak() : TCP.H, PC_CBRK.C, MISC.H
  • tcp_cbrk() : OLDSTUFF.C
  • tcp_checksum() : PCTCP.C
  • tcp_do_boot() : SOCK_INI.C
  • tcp_established() : PCTCP.H, PCTCP.C
  • tcp_findseq() : PCTCP.C
  • tcp_init() : SOCK_INI.C
  • tcp_inject_config() : TCP.H, PCCONFIG.H, PCCONFIG.C
  • tcp_inject_config_direct() : PCCONFIG.C
  • tcp_listen() : PCTCP.H, PCTCP.C
  • tcp_no_arp() : PCTCP.C
  • tcp_open() : PCTCP.H, PCTCP.C
  • tcp_opt_maxsegment() : PCTCP.C
  • tcp_opt_padding() : PCTCP.C
  • tcp_opt_timestamp() : PCTCP.C
  • tcp_options() : PCTCP.C
  • tcp_post_init() : SOCK_INI.C
  • tcp_process_data() : TCP_FSM.C
  • tcp_process_options() : TCP_FSM.C
  • tcp_read() : PCTCP.C
  • tcp_reassemble() : TCP_FSM.C
  • tcp_receive() : RECEIVE.C
  • tcp_Retransmitter() : PCTCP.H, PCTCP.C
  • tcp_rtt_win() : PCTCP.C
  • tcp_set_debug_state() : TCP.H, PCCONFIG.H, PCCONFIG.C
  • tcp_set_window() : TCP_FSM.C
  • tcp_shutdown() : SOCK_INI.C
  • tcp_sock_daemon() : SOCKET.C
  • tcp_sockreset() : PCTCP.C
  • tcp_synsent_state() : TCP_FSM.C
  • tcp_tick() : TCP.H, PCTCP.H, PCTCP.C
  • tcp_transmit() : TRANSMIT.C
  • tcp_upd_win() : PCTCP.C
  • tcp_write() : PCTCP.C
  • tftp_exit() : TFTP.C
  • tftp_init() : TFTP.H, TFTP.C
  • tok_ifnet() : IOCTL.C
  • tok_mac_format() : PCSED.C

- u -

  • udp_checksum() : PCTCP.C
  • udp_close() : PCTCP.C
  • udp_demux() : PCTCP.C
  • udp_handler() : ECHO.C
  • udp_listen() : PCTCP.H, PCTCP.C
  • udp_loopback() : LOOPBACK.C
  • udp_open() : PCTCP.H, PCTCP.C
  • udp_read() : PCTCP.C
  • udp_receive() : RECEIVE.C
  • udp_SetTTL() : PCTCP.H, PCTCP.C
  • udp_sock_daemon() : SOCKET.C
  • udp_write() : PCTCP.C
  • unpack_domain() : UDP_DOM.C
  • update_in_stat() : PCSTAT.H, PCSTAT.C
  • update_out_stat() : PCSTAT.H, PCSTAT.C
  • url_free() : DYNIP.C
  • url_parse() : DYNIP.C
  • userTimerTick() : TCP.H, TIMER.H, TIMER.C

- v -

  • vendor_version() : SOCKET.C

- w -

  • Wait() : MISC.H, MISC.C
  • waterm_ioctrl() : IOCTL.C
  • watt_kbhit() : TCP.H, MISC.H, MISC.C
  • watt_sock_init() : TCP.H, SOCK_INI.H, SOCK_INI.C
  • write_config() : PCDHCP.C
Generated on Wed Jan 25 15:42:44 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: Globals - Typedefs

  • arcnet_address : WATTCP.H
  • ax25_address : WATTCP.H
  • BYTE : WATTCP.H
  • DWORD : WATTCP.H
  • eth_address : WATTCP.H
  • fddi_address : WATTCP.H
  • icmp_upcall : WATTCP.H
  • int64 : WATTCP.H
  • ip6_address : WATTCP.H
  • ProtoHandler : WATTCP.H
  • tok_address : WATTCP.H
  • UINT : WATTCP.H
  • uint64 : WATTCP.H
  • UserHandler : WATTCP.H
  • WORD : WATTCP.H
Generated on Wed Jan 25 15:42:44 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: Globals - Variables

- _ -

  • _bootp_on : SOCK_INI.C
  • _default_tos : IP4_OUT.H, IP4_OUT.C
  • _default_ttl : IP4_OUT.H, IP4_OUT.C
  • _dhcp6_on : SOCK_INI.C
  • _dhcp_on : SOCK_INI.C
  • _do_mask_req : SOCK_INI.C
  • _eth_addr : PCSED.C
  • _eth_brdcast : PCSED.C
  • _eth_is_init : PCSED.H, PCSED.C
  • _eth_last : PCSED.H, PCSED.C
  • _eth_loop_addr : PCSED.C
  • _eth_mac_len : PCSED.H, PCSED.C
  • _eth_real_addr : PCSED.C
  • _eth_recv_hook : PCSED.C
  • _ip4_dont_frag : IP4_OUT.H, IP4_OUT.C
  • _ip4_id_increment : IP4_OUT.H, IP4_OUT.C
  • _ip_recursion : PCSED.H, PCSED.C
  • _pkt_errno : PCPKT.H, PCPKT.C
  • _pkt_forced_rxmode : WINPCAP.C, PCPKT.H
  • _pkt_inf : WINPCAP.H, WINPCAP.C, PCPKT.H, PCPKT.C
  • _pkt_ip_ofs : PCPKT.H, PCPKT.C
  • _pkt_rxmode : WINPCAP.C, PCPKT.H, PCPKT.C
  • _pkt_rxmode0 : WINPCAP.C, PCPKT.H, PCPKT.C
  • _pkt_type_ofs : PCPKT.C
  • _pktdevclass : PCPKT.H, PCPKT.C
  • _pktdevlevel : PCPKT.H, PCPKT.C
  • _pktdrvrname : PCPKT.H
  • _pktserial : PCPKT.H, PCPKT.C
  • _printk_file : PRINTK.H, PRINTK.C
  • _printk_safe : PRINTK.H, PRINTK.C
  • _rarp_on : SOCK_INI.C
  • _tcp_allsocs : PCTCP.H, PCTCP.C
  • _udp_allsocs : PCTCP.H, PCTCP.C
  • _watt_assert_buf : MISC.C
  • _watt_cbroke : PC_CBRK.C
  • _watt_do_exit : SOCK_INI.C
  • _watt_dosFp : TARGET.H, MISC.C
  • _watt_fatal_error : MISC.C
  • _watt_handle_cbreak : PC_CBRK.C
  • _watt_is_init : SOCK_INI.C
  • _watt_no_config : SOCK_INI.C
  • _watt_os_ver : MISC.C

- a -

  • addr_mask_id : PCICMP.C

- b -

  • block_icmp : PCTCP.C
  • block_ip : PCTCP.C
  • block_tcp : PCTCP.C
  • block_udp : PCTCP.C

- c -

  • called_from_resolve : UDP_DOM.H, UDP_DOM.C
  • capa : VERSION.C
  • clocks_per_usec : TIMER.C
  • cstate_dseg : PCPKT.C

- d -

  • daemon_timer : PCTCP.C
  • dbg_mode_all : PCDBUG.H, PCDBUG.C
  • defaultdomain : UDP_DOM.C

- e -

  • exc_app_start : WDPMI.C

- h -

  • has_8254 : TIMER.C
  • has_rdtsc : TIMER.C
  • hostname : PCTCP.C

- i -

  • icmp_id : PCARP.C
  • inuse : SOCKET.C

- m -

  • mac_tx_format : PCSED.C
  • MAX_DAEMONS : PCTCP.C
  • mcast_set : SOCKET.C
  • mtu_blackhole : PCTCP.H, PCTCP.C
  • mtu_discover : PCTCP.H, PCTCP.C
  • my_ip_addr : PCTCP.C

- o -

  • old_break : SOCK_INI.C

- p -

  • prev_cfg_hook : PCARP.C

- r -

  • rmcb : X32VM.C
  • rtt_cache : PCTCP.C

- s -

  • sel_min_block : SELECT.C
  • sign_opt : PCTCP.C
  • sin_mask : PCTCP.C
  • sk_scope : BSDDBUG.C
  • sock_init_called : SOCK_INI.C
  • start_day : TIMER.C
  • start_time : TIMER.C
  • survive_bootp : SOCK_INI.C
  • survive_dhcp : SOCK_INI.C
  • survive_eth : SOCK_INI.C
  • survive_rarp : SOCK_INI.C

- t -

  • tcp_CLOSE_TO : PCTCP.C
  • tcp_is_init : SOCK_INI.C
  • tcp_keep_idle : PCTCP.C
  • tcp_keep_intvl : PCTCP.C
  • tcp_max_idle : PCTCP.C
  • tcp_MAX_VJSA : PCTCP.C
  • tcp_MAX_VJSD : PCTCP.C
  • tcp_nagle : PCTCP.H, PCTCP.C
  • tcp_OPEN_TO : PCTCP.C
  • tcp_opt_ts : PCTCP.H, PCTCP.C
  • tcp_recv_win : PCTCP.C
  • tcp_RETRAN_TIME : PCTCP.C
  • tcp_RST_TIME : PCTCP.C
  • tcp_RTO_ADD : PCTCP.C
  • tcp_RTO_BASE : PCTCP.C
  • tcp_RTO_SCALE : PCTCP.C
  • transient_cfg : PCDHCP.C

- u -

  • use_except : SOCK_INI.C
  • use_rdtsc : TIMER.C
  • userName : PPPOE.C
  • using_int8 : TIMER.C
  • usr_post_init : PCCONFIG.C

- w -

  • win32_dos_box : MISC.C
Generated on Wed Jan 25 15:42:44 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: Todo List

Todo List

Global _tcp_Socket::missed_seq [2]
Make a prober re-assembly queue. missed_seq[0] is left edge of missing segment. missed_seq[1] is right edge (in peer's absolute SEQ space)

Global _tcp_Socket::tx_wscale
window scales shifts, Tx/Rx

Global ADAPTER::Name [ADAPTER_NAME_LENGTH]
: remove this

Class DNS_Hdr
parse the SRV resource record (RFC 2052)

Global res_mkquery (int, const char *, int, int, const u_char *, int, const u_char *, u_char *, int)
Handle STATUS case

Global _eth_arrived (WORD *type, BOOL *brdcast)
push back packet, else it's lost

Global init_misc (void)

Global tcp_tick (sock_type *s)
Limit the time spent here (clamp # of loops)

Global watt_sock_init (size_t, size_t)
Use auto-configuration and set 'my_ip_addr' to 169.254/16

Global _sock_append (_tcp_Socket **tcp)
Implement SYN-cookies. http://cr.yp.to/syncookies.html

Global _sock_append (_tcp_Socket **tcp)
Implement SYN-cookies and drop the segment if no match

drop the oldest (or a random) slot in the listen-queue.

Global accept (int s, struct sockaddr *addr, int *addrlen)
Should maybe loop over all maxconn TCBs and accept the one with oldest 'syn_timestamp'.

Global bind (int s, const struct sockaddr *myaddr, int namelen)
check for "sleeping" ports (lport_inuse in pctcp.c) also. And return EADDRINUSE if local port not free.

Global echo_discard_daemon (void)
handle jumbo packets (IP-fragments)

Global main (int argc, char **argv)
Make a echo client/server test program

Global fcntlsocket (int s, int cmd,...)
handle O_TEXT and O_BINARY

Global gethostbyaddr_internal (const char *addr_name, int len, int type, struct _hostent *ret)
Should return all our addresses if we're multihomed.

should be the new aliases

Global gethostbyname_internal (const char *name, const char **alias, struct _hostent *ret)
should be canonical name

Global gethostbyaddr6_internal (const char *addr, struct _hostent6 *ret)
should check all addresses

should be the new aliases

Global is_watt32_func (const char *func)
Fill in the rest (use a generated table?)

Global IDNA_convert_from_ACE (char *name, size_t *size)
Check for over-run on output.

Global eth_ifnet (void)
fill info

Global iface_ioctrl (Socket *socket, long cmd, char *argp)
Get point-to-point address

Set point-to-point address

Set interface metric

Handle deleting interface address

Handle add/change interface alias

Global tok_ifnet (void)
fill info

Global waterm_ioctrl (Socket *socket, long cmd, char *argp)
set high watermark

get high watermark

set low watermark

get low watermark

OOB data available?

Global init_frag (int argc, char **argv)
Simulate fragment timeout

Global _ip4_handler (const in_Header *ip, BOOL broadcast)
check for LSRR option and replace ip->source with actual source-address burried in option (ref. RFC-1122)

handle compressed IP (use zlib)

Global _ip4_output (in_Header *ip, DWORD src_ip, DWORD dst_ip, BYTE protocol, BYTE ttl, BYTE tos, WORD ip_id, int data_len, const void *sock, const char *file, unsigned line)
Handle IP-fragments here (call ip4_send_fragments() when needed)

Global _ip4_send_fragments (sock_type *s, BYTE proto, DWORD dest, const void *buf, unsigned len, const char *file, unsigned line)
Maybe send highest offset fragment first?

support sending raw IPv4 fragments

Global _ip6_output (in6_Header *ip, ip6_address *src_ip, ip6_address *dst_ip, BYTE protocol, unsigned data_len, int hop_lim, const void *sock, const char *file, unsigned line)
: Support fragments

Global icmp_loopback (ICMP_PKT *icmp, unsigned icmp_len)
fall-through to another ICMP loopback handler

Global udp_loopback (udp_Header *udp, unsigned udp_len)
UDP loopback handler should handle ECHO protocol

UDP loopback handler should handle DISCARD protocol

Global crtdbg_report (int type, char *message, int *ret_val)
make a stack dumper

Global _watt_dosFp
detect program restarts

Global ExpandVarStr (const char *str)
support several in one line and malloc the result.

Global icmp4_dump (const in_Header *ip)
Handle debugging of these

Global MatchIp6Dest (const in6_Header *ip)
needs work

Global dbg_mode_all
make them static.

Global DHCP_offer (const struct dhcp *in)
make a hook for SMB-lib

Global set_vend_class (const char *value)
Support setting vendor class

Global icmp_handler (const in_Header *ip, BOOL broadcast)
Handle cancelling raw sockets

send reply?

should store

send reply

send reply upwards

File PCMULTI.C
Support IGMP v3 (draft-ietf-idmr-igmp-v3-??.txt)

Global pkt_api_entry (IREGS *reg, unsigned called_from_line)
Use 32-bit API; accessing card via pmode driver

Global pkt_release (void)
We might be called between 1st and 2nd packet-driver upcall. Need to wait for 2nd upcall to finish or else freeing the RMCB too early could cause a crash or a stuck PKTDRVR.

Global pkt_send (const void *tx, int length)
Change this so that we doesn't retry if the driver was stuck for "too long". I've seen drivers using approx. 100 msec on each iteration below. Retrying if the driver is stuck is not worth the time.

Global pkt_send (const void *tx, int length)
estimate max time this should take

Global setup_pkt_inf (void)
Make dynamic allocation based on 'pkt_num_rx_bufs'. Allocate multiple 64kB blocks if needed (would involve messy 16-bit coding in asmpkt.nas).

Global pkt_eth_init (mac_address *eth)
Support Win-9x too

Global sarp_receive (const struct sarp_Packet *sarp)

Global fix_llc_head (void **mac)
handle IEEE 802.3 encapsulation also.

Global update_in_stat (void)
Count PPP protocols LCP and IPCP

Count these IPv6 protocols

Global update_out_stat (void)
Count the PPP protocols LCP and IPCP

Count these IPv6 protocols

Global tcp_listen (_tcp_Socket *s, WORD lport, DWORD ip, WORD port, ProtoHandler handler, WORD timeout)
use mss from setsockopt()

Global tcp_open (_tcp_Socket *s, WORD lport, DWORD ip, WORD rport, ProtoHandler handler)
use mss from setsockopt()

use TCP_NODELAY set in setsockopt()

Global tcp_Retransmitter (BOOL force)
set "Slow-start" threshold

Allow for 3 SYN before giving up

Global tcp_rtt_win (_tcp_Socket *s)
Use TimeStamp option values

Use the threshold to signify "end-of-Slow-Start" (equilibrium)

Global udp_demux (const in_Header *ip, BOOL ip_bcast, DWORD destin, WORD srcPort, WORD dstPort, BOOL *udp_err)
use some kind of hashing to speed up the search.

Global mtu_blackhole
Add PMTU blackhole detection

Global mtu_discover
Add PMTU discovery method

Global init_localport (void)
Make empherical port range configurable.

Use some hashing technique to speed up find_free_port().

Global sock_puts (sock_type *s, const BYTE *dp)
suppport UDP frags

Global std_negotiation (struct ppp_state *state, struct ppp_xcp *xcp)
extract LCP_MRU option

Global pppoe_start (void)
Fix-me: The new MTU/MSS affects all connections (also those which doesn't use PPPoE framing).

Global userName [MAX_VALUELEN+1]
PPP user/passwd not handled

Global tcp_receive (Socket *sock, void *buf, int len, int flags, struct sockaddr *from, int *fromlen)
Handle receiving Out-of-Band data

Global udp_receive (Socket *sock, void *buf, int len, int flags, struct sockaddr *from, int *fromlen)
This needs a redesign

Global exc_select (int s, Socket *socket)
Only arrival of OOB-data should count here

Global sel_min_block
Should be configurable.

Global shutdown (int s, int how)
For tcp, should send RST if we get incoming data. Don't send ICMP error.

For tcp, should send FIN when all Tx data has been ack'ed. close_s(s) should be same as shutdown(s,SHUT_WR)

Global except_handler (int sig)
Disassemble crash address

Global sock_getcw (sock_type *s)
Wide character version of sock_getc()

Global sock_getsw (sock_type *s, wchar_t *data, int n)
Wide character version of sock_gets()

Global sock_putcw (sock_type *s, wchar_t ch)
Wide character versions of above functions.

Global sock_putsw (sock_type *s, const wchar_t *data)
Wide character version of sock_puts()

Global _sock_crit_stop (void)
handle SIGALRM raised in a critical-section

Global _sock_set_rcv_buf (sock_type *s, size_t len)
allow user to define size using SO_RCVBUF/SO_SNDBUF before calling connect().

Global _TCP6_listen (Socket *socket, const void *host, WORD loc_port)
Support TCP listen() for AF_INET6

Global _TCP6_open (Socket *socket, const void *dst, WORD loc_port, WORD rem_port)
use mss from setsockopt()

Yield for IPv6 sockets

use TCP_NODELAY set in setsockopt()

Global _UDP6_listen (Socket *socket, const void *host, WORD port)
Support UDP listen() for AF_INET6

Global _UDP6_open (Socket *socket, const void *host, WORD loc_port, WORD rem_port)
Support UDP connect() for AF_INET6

Global set_proto (int type, BOOL is_ip6, int *proto)
IPPROTO_XTP

Global sock_packet_receive (Socket *sock, void *buf, unsigned len, struct sockaddr *from, int *fromlen)
This should loop until some packet is received.

Global sock_raw4_recv (const in_Header *ip)
Handle receiving bad IP-packets for SOCK_RAW sockets.

Global get_sol_opt (Socket *s, int opt, void *val, int *len)
Handle urgent (OOB) data

Handle these SOL_OPTIONS:

Global raw6_rx_buf (_raw6_Socket *raw, DWORD size)
Support setting Rx-buffer size of raw IPv6 sockets

Global raw6_tx_buf (_raw6_Socket *raw, DWORD size)
Support setting Tx-buffer size of raw IPv6 sockets

Global raw_rx_buf (_raw_Socket *raw, DWORD size)
Support setting Rx-buffer size of raw IPv4 sockets

Global raw_tx_buf (_raw_Socket *raw, DWORD size)
Support setting Tx-buffer size of raw IPv4 sockets

Global split_ip6 (struct pkt_split *, const in6_Header *)
Handle Fragment, ESP, AUTH, IPv6 encap

File SYSLOG.C
configure variables in syslog2.c when calling openlog() thus making syslog() independant of watt_sock_init().

Global tcp_process_data (_tcp_Socket *s, const tcp_Header *tcp, int len, int *flags)
Handle Out-of-Order urgent data. Raise SIGURG.

Global tcp_reassemble (_tcp_Socket *s, const tcp_Header *tcp, const BYTE *data, UINT len, int *flags)
Create a better TCP reassembler some day. Current logic only handles 1 missed segment. We should handle at least 2.

Global tcp_set_window (_tcp_Socket *s, const tcp_Header *tcp)
Set slow-start threshold

Global tcp_synsent_state (_tcp_Socket **, const in_Header *, tcp_Header *, int)
recalculate RTT-timer

File TFTP.C
Support option negotiation and ETFTP (RFC-1986)

File TIMER.C
To get rid of the timer problem once and for all we need a timer ISR that increments a 32-bit value no regard to day roll-over etc. Maybe hook up IRQ 8 to call a real-mode stub that we opy to DOS-memory (similar to the pkt_receiver stub code. Then far-peek at that timer variable.

Global init_timers (void)
check if 8254 PIT is really working

Global ip4_transmit (Socket *socket, const void *tx, unsigned len)
Handle sending fragments with IP optons

Global ip6_transmit (Socket *socket, const void *tx, unsigned len)
support fragmentation

Global tcp_transmit (Socket *socket, const void *buf, unsigned len, int flags)
Allow non-blocking sockets to send in SYNSENT state

Global query_init_ip6 (struct DNS_query *q, const void *addr)
Use "ip6.arpa" bitstring format ?

Global exc_app_start
find the real application start

Global find_adapter (char *aname, size_t size)
Use IPhlpAPI function to return list of adapters

Global _dx_real_alloc (int para_count, WORD *para, WORD *largest)

Global PmGlueEnd (void)
Support 32-bit Watcom with X32VM

Global rmcb [MAX_WRAPPERS]
find the real application start
Generated on Wed Jan 25 15:42:44 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: Deprecated List

Deprecated List

Class watt_sockaddr
Old style sockaddr

File BSDNAME.C
Oldstyle BSD similar functions are prefixed with '_'.

File NETBACK.C
Background ISR.

Global set_ttimeout (unsigned ticks)
. Not needed in Watt-32. Return timeout from ticks.

Global tcp_cbrk (int mode)
. Actually simply a macro in <tcp.h>

File PCSLIP.H
Generated on Wed Jan 25 15:42:44 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: Data Structures

Here are the data structures with brief descriptions:
_hostent |
_hostent6 |
_netent |
_protoent |
_raw6_Socket |
_raw_Socket |
_servent |
_tcp_Socket |
_udp_Socket |
ADAPTER | Describes an opened network adapter
ADAPTER_INFO | Contains comprehensive information about a network adapter
arcnet_Header |
arcnet_Packet |
arp_entry |
arp_Header |
bootp |
bootp_vend |
bpf_hdr | Berkeley Packet Filter header
cmd_block | Run a COMMAND.COM/4DOS external/internal command
dhcp |
DNS_Hdr | Debug of DNS (udp) records
eth_Header |
eth_Packet |
fddi_Header |
fddi_Packet |
gate_entry |
ICMP_ip |
ICMP_needfrag |
ICMP_unused |
IGMP_packet |
in6_Header |
in_Header |
ip_Packet |
link_Packet |
llc_Header |
macstat |
MultiCast | Multicast internal structure
npf_if_addr | Addresses of a network adapter
on_exit | Register an on-exit function
PACKET | Structure for PacketReceivePacket + PacketSendPacket
PACKET_OID_DATA | Structure containing an OID request
ping_cache |
ping_pkt |
pkt_info | Placeholder for vital data accessed by capture thread
pkt_ringbuf |
pppoestat |
route_entry | ROUTE (& REDIRECT) HANDLING
sock_type |
tcp_Header |
tcp_PseudoHeader |
tcp_PseudoHeader6 |
tcp_rtt |
tok_Header |
tok_Packet |
udp_Header |
vlan_Header |
vlan_Packet |
watt_sockaddr |
Generated on Wed Jan 25 15:42:44 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: Alphabetical List

Watt-32 tcp/ip Data Structure Index

_ | A | B | C | D | E | F | G | I | L | M | N | O | P | R | S | T | U | V | W

_
bpf_hdr in_Header pppoestat
_hostent
C
ip_Packet
R
_hostent6 cmd_block
L
route_entry
_netent
D
link_Packet
S
_protoent dhcp llc_Header sock_type
_raw6_Socket DNS_Hdr
M
T
_raw_Socket
E
macstat tcp_Header
_servent eth_Header MultiCast tcp_PseudoHeader
_tcp_Socket eth_Packet
N
tcp_PseudoHeader6
_udp_Socket
F
npf_if_addr tcp_rtt
A
fddi_Header
O
tok_Header
ADAPTER fddi_Packet on_exit tok_Packet
ADAPTER_INFO
G
P
U
arcnet_Header gate_entry PACKET udp_Header
arcnet_Packet
I
PACKET_OID_DATA
V
arp_entry ICMP_ip ping_cache vlan_Header
arp_Header ICMP_needfrag ping_pkt vlan_Packet
B
ICMP_unused pkt_info
W
bootp IGMP_packet pkt_ringbuf watt_sockaddr
bootp_vend in6_Header

_ | A | B | C | D | E | F | G | I | L | M | N | O | P | R | S | T | U | V | W

Generated on Wed Jan 25 15:42:44 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: File Index

Watt-32 tcp/ip File List

Here is a list of all documented files with brief descriptions:
inc/ERR.H [code]
inc/NETDB.H [code]
inc/RESOLV.H [code]
inc/SYSLOG.H [code]
inc/TCP.H [code]
inc/WINSOCK2.H [code]
inc/WS2TCPIP.H [code]
inc/arpa/FTP.H [code]
inc/arpa/INET.H [code]
inc/arpa/NAMESER.H [code]
inc/arpa/TELNET.H [code]
inc/arpa/TFTP.H [code]
inc/net/BPF.H [code]
inc/net/BPFDESC.H [code]
inc/net/ETHERTYP.H [code]
inc/net/IF.H [code]
inc/net/IF_ARC.H [code]
inc/net/IF_ARP.H [code]
inc/net/IF_ATM.H [code]
inc/net/IF_DL.H [code]
inc/net/IF_ETHER.H [code]
inc/net/IF_FDDI.H [code]
inc/net/IF_LLC.H [code]
inc/net/IF_MEDIA.H [code]
inc/net/IF_PACKE.H [code]
inc/net/IF_PPP.H [code]
inc/net/IF_PPPVA.H [code]
inc/net/IF_SLVAR.H [code]
inc/net/IF_STRIP.H [code]
inc/net/IF_TUN.H [code]
inc/net/IF_TYPES.H [code]
inc/net/NETISR.H [code]
inc/net/PFIL.H [code]
inc/net/PPP-COMP.H [code]
inc/net/PPP_DEFS.H [code]
inc/net/RADIX.H [code]
inc/net/RAW_CB.H [code]
inc/net/ROUTE.H [code]
inc/net/SLCOMPRE.H [code]
inc/net/SLIP.H [code]
inc/netinet/ICMP6.H [code]
inc/netinet/ICMP_VAR.H [code]
inc/netinet/IF_ETHER.H [code]
inc/netinet/IF_FDDI.H [code]
inc/netinet/IGMP.H [code]
inc/netinet/IGMP_VAR.H [code]
inc/netinet/IN.H [code]
inc/netinet/IN_PCB.H [code]
inc/netinet/IN_SYSTM.H [code]
inc/netinet/IN_VAR.H [code]
inc/netinet/IP.H [code]
inc/netinet/IP6.H [code]
inc/netinet/IP_FW.H [code]
inc/netinet/IP_ICMP.H [code]
inc/netinet/IP_MROUT.H [code]
inc/netinet/IP_VAR.H [code]
inc/netinet/IPV6.H [code]
inc/netinet/TCP.H [code]
inc/netinet/TCP_DEBU.H [code]
inc/netinet/TCP_FSM.H [code]
inc/netinet/TCP_SCOR.H [code]
inc/netinet/TCP_SEQ.H [code]
inc/netinet/TCP_TIME.H [code]
inc/netinet/TCP_VAR.H [code]
inc/netinet/TCPIP.H [code]
inc/netinet/UDP.H [code]
inc/netinet/UDP_VAR.H [code]
inc/netinet6/AH.H [code]
inc/netinet6/AH6.H [code]
inc/netinet6/ESP.H [code]
inc/netinet6/ESP6.H [code]
inc/netinet6/ESP_RIJN.H [code]
inc/netinet6/IN6.H [code]
inc/netinet6/IN6_GIF.H [code]
inc/netinet6/IN6_IFAT.H [code]
inc/netinet6/IN6_PCB.H [code]
inc/netinet6/IN6_PREF.H [code]
inc/netinet6/IN6_VAR.H [code]
inc/netinet6/IP6_ECN.H [code]
inc/netinet6/IP6_FW.H [code]
inc/netinet6/IP6_MROU.H [code]
inc/netinet6/IP6_VAR.H [code]
inc/netinet6/IP6PROTO.H [code]
inc/netinet6/IPCOMP.H [code]
inc/netinet6/IPCOMP6.H [code]
inc/netinet6/IPSEC.H [code]
inc/netinet6/IPSEC6.H [code]
inc/netinet6/MLD6_VAR.H [code]
inc/netinet6/ND6.H [code]
inc/netinet6/PIM6.H [code]
inc/netinet6/PIM6_VAR.H [code]
inc/netinet6/RAW_IP6.H [code]
inc/netinet6/SCOPE6_V.H [code]
inc/netinet6/TCP6_VAR.H [code]
inc/netinet6/UDP6_VAR.H [code]
inc/protocol/DUMPREST.H [code]
inc/protocol/ROUTED.H [code]
inc/protocol/RWHOD.H [code]
inc/protocol/TALKD.H [code]
inc/protocol/TIMED.H [code]
inc/rpc/AUTH.H [code]
inc/rpc/AUTH_DES.H [code]
inc/rpc/AUTH_UNI.H [code]
inc/rpc/CLNT.H [code]
inc/rpc/KEY_PROT.H [code]
inc/rpc/PMAP_CLN.H [code]
inc/rpc/PMAP_PRO.H [code]
inc/rpc/PMAP_RMT.H [code]
inc/rpc/RPC.H [code]
inc/rpc/RPC_MSG.H [code]
inc/rpc/SVC.H [code]
inc/rpc/SVC_AUTH.H [code]
inc/rpc/TYPES.H [code]
inc/rpc/XDR.H [code]
inc/rpcsvc/YP_PROT.H [code]
inc/rpcsvc/YPCLNT.H [code]
inc/sys/CDEFS.H [code]
inc/sys/ERRNO.H [code]
inc/sys/IOCTL.H [code]
inc/sys/PACKOFF.H [code]
inc/sys/PACKON.H [code]
inc/sys/PARAM.H [code]
inc/sys/POLL.H [code]
inc/sys/QUEUE.H [code]
inc/sys/SELECT.H [code]
inc/sys/SO_IOCTL.H [code]
inc/sys/SOCKET.H [code]
inc/sys/SWAP.H [code]
inc/sys/SYSLOG.H [code]
inc/sys/UIO.H [code]
inc/sys/W32API.H [code]
inc/sys/WERRNO.H [code]
inc/sys/WTIME.H [code]
inc/sys/WTYPES.H [code]
SRC/ACCEPT.C [code]
SRC/ADR2ASC.C [code]
SRC/ASC2ADR.C [code]
SRC/ASMPKT.H [code]
SRC/BIND.C [code]
SRC/BSDDBUG.C [code]
SRC/BSDDBUG.H [code]
SRC/BSDNAME.C [code]
SRC/BSDNAME.H [code]
SRC/BTRACE.H [code]
SRC/BTREE.C [code]
SRC/BTREE.H [code]
SRC/CHKSUM.C [code]
SRC/CHKSUM.H [code]
SRC/CLOSE.C [code]
SRC/CONFIG.H [code]
SRC/CONNECT.C [code]
SRC/COPYRIGH.H [code]
SRC/COUNTRY.C [code]
SRC/CPUMODEL.H [code]
SRC/CRC.C [code]
SRC/CRIT.C [code]
SRC/DYNIP.C [code]
SRC/DYNIP.H [code]
SRC/ECHO.C [code]
SRC/ECHO.H [code]
SRC/FCNTL.C [code]
SRC/FORTIFY.C [code]
SRC/FORTIFY.H [code]
SRC/FSEXT.C [code]
SRC/GET_AI.C [code]
SRC/GET_IP.C [code]
SRC/GET_NI.C [code]
SRC/GET_XBY.H [code]
SRC/GETETH.C [code]
SRC/GETHOST.C [code]
SRC/GETHOST6.C [code]
SRC/GETNAME.C [code]
SRC/GETNET.C [code]
SRC/GETOPT.C [code]
SRC/GETOPT.H [code]
SRC/GETPROT.C [code]
SRC/GETPUT.C [code]
SRC/GETSERV.C [code]
SRC/GETTOD.C [code]
SRC/GETTOD.H [code]
SRC/HIGHC.C [code]
SRC/IDNA.C [code]
SRC/IDNA.H [code]
SRC/IOCTL.C [code]
SRC/IOPORT.H [code]
SRC/IP4_FRAG.C [code]
SRC/IP4_FRAG.H [code]
SRC/IP4_IN.C [code]
SRC/IP4_IN.H [code]
SRC/IP4_OUT.C [code]
SRC/IP4_OUT.H [code]
SRC/IP6_IN.C [code]
SRC/IP6_IN.H [code]
SRC/IP6_OUT.C [code]
SRC/IP6_OUT.H [code]
SRC/LANGUAGE.H [code]
SRC/LANGUAGE.L [code]
SRC/LINKADDR.C [code]
SRC/LISTEN.C [code]
SRC/LOOKUP.C [code]
SRC/LOOPBACK.C [code]
SRC/LOOPBACK.H [code]
SRC/MISC.C [code]
SRC/MISC.H [code]
SRC/NETADDR.C [code]
SRC/NETADDR.H [code]
SRC/NETBACK.C [code]
SRC/NETERR.C [code]
SRC/NETTIME.C [code]
SRC/NOCHKSTK.H [code]
SRC/NSAPADDR.C [code]
SRC/Ntddndis.h [code]
SRC/OLDSTUFF.C [code]
SRC/PACKET32.C [code]
SRC/Packet32.h [code]
SRC/PC_CBRK.C [code]
SRC/PCARP.C [code]
SRC/PCARP.H [code]
SRC/PCBOOTP.C [code]
SRC/PCBOOTP.H [code]
SRC/PCBUF.C [code]
SRC/PCBUF.H [code]
SRC/PCCONFIG.C [code]
SRC/PCCONFIG.H [code]
SRC/PCDBUG.C [code]
SRC/PCDBUG.H [code]
SRC/PCDHCP.C [code]
SRC/PCDHCP.H [code]
SRC/PCICMP.C [code]
SRC/PCICMP.H [code]
SRC/PCICMP6.C [code]
SRC/PCICMP6.H [code]
SRC/PCINTR.C [code]
SRC/PCMULTI.C [code]
SRC/PCMULTI.H [code]
SRC/PCPING.C [code]
SRC/PCPING.H [code]
SRC/PCPKT.C [code]
SRC/PCPKT.H [code]
SRC/PCPKT32.C [code]
SRC/PCPKT32.H [code]
SRC/PCQUEUE.C [code]
SRC/PCQUEUE.H [code]
SRC/PCRARP.C [code]
SRC/PCRARP.H [code]
SRC/PCRECV.C [code]
SRC/PCRECV.H [code]
SRC/PCSARP.C [code]
SRC/PCSARP.H [code]
SRC/PCSED.C [code]
SRC/PCSED.H [code]
SRC/PCSLIP.H [code]
SRC/PCSTAT.C [code]
SRC/PCSTAT.H [code]
SRC/PCTCP.C [code]
SRC/PCTCP.H [code]
SRC/POLL.C [code]
SRC/PORTS.C [code]
SRC/POWERPAK.C [code]
SRC/POWERPAK.H [code]
SRC/PPP.C [code]
SRC/PPP.H [code]
SRC/PPPOE.C [code]
SRC/PPPOE.H [code]
SRC/PRESADDR.C [code]
SRC/PRINTK.C [code]
SRC/PRINTK.H [code]
SRC/PUNYCODE.C [code]
SRC/PUNYCODE.H [code]
SRC/QMSG.C [code]
SRC/RECEIVE.C [code]
SRC/REGISTER.H [code]
SRC/RES_COMP.C [code]
SRC/RES_DATA.C [code]
SRC/RES_DEBU.C [code]
SRC/RES_INIT.C [code]
SRC/RES_LOC.C [code]
SRC/RES_MKQU.C [code]
SRC/RES_QUER.C [code]
SRC/RES_SEND.C [code]
SRC/RESOLVER.H [code]
SRC/RS232.C [code]
SRC/RS232.H [code]
SRC/SELECT.C [code]
SRC/SETTOD.C [code]
SRC/SETTOD.H [code]
SRC/SHUTDOWN.C [code]
SRC/SIGNAL.C [code]
SRC/SOCK_DBU.C [code]
SRC/SOCK_IN.C [code]
SRC/SOCK_INI.C [code]
SRC/SOCK_INI.H [code]
SRC/SOCK_IO.C [code]
SRC/SOCK_PRN.C [code]
SRC/SOCK_SCN.C [code]
SRC/SOCK_SEL.C [code]
SRC/SOCKET.C [code]
SRC/SOCKET.H [code]
SRC/SOCKOPT.C [code]
SRC/SPLIT.C [code]
SRC/SPLIT.H [code]
SRC/STREAM.C [code]
SRC/STRINGS.C [code]
SRC/STRINGS.H [code]
SRC/SYSLOG.C [code]
SRC/SYSLOG2.C [code]
SRC/SYSLOG2.H [code]
SRC/TARGET.H [code]
SRC/TCP_FSM.C [code]
SRC/TCP_MD5.C [code]
SRC/TCP_MD5.H [code]
SRC/TEREDO64.C [code]
SRC/TEREDO64.H [code]
SRC/TFTP.C [code]
SRC/TFTP.H [code]
SRC/TIMER.C [code]
SRC/TIMER.H [code]
SRC/TRANSMIT.C [code]
SRC/TST.C [code]
SRC/UDP_DOM.C [code]
SRC/UDP_DOM.H [code]
SRC/UDP_REV.C [code]
SRC/UFORTIFY.H [code]
SRC/VERSION.C [code]
SRC/WATTCP.C [code]
SRC/WATTCP.H [code]
SRC/WDPMI.C [code]
SRC/WDPMI.H [code]
SRC/WINMISC.C [code]
SRC/WINPCAP.C [code]
SRC/WINPCAP.H [code]
SRC/X32VM.C [code]
SRC/X32VM.H [code]
Generated on Wed Jan 25 15:42:32 2006 for Watt-32 tcp/ip by doxygen 1.3.8


Watt-32 tcp/ip: Page Index

Watt-32 tcp/ip Related Pages

Here is a list of all related documentation pages:
  • Todo List
  • Deprecated List
Generated on Wed Jan 25 15:42:44 2006 for Watt-32 tcp/ip by doxygen 1.3.8