#ifndef	_USOCK_H
#define	_USOCK_H

#ifndef	_MBUF_H
#include "mbuf.h"
#endif

#ifndef	_LZW_H
#include "lzw.h"
#endif

#ifndef _PROC_H
#include "proc.h"
#endif

#ifndef _TCP_H
#include "tcp.h"
#endif

#ifndef _UDP_H
#include "udp.h"
#endif

#ifndef _IP_H
#include "ip.h"
#endif

#ifndef _NETROM_H
#include "netrom.h"
#endif

/* Local IP wildcard address */
#define	INADDR_ANY	0x0L

/* IP protocol numbers */
#define	IPPROTO_ICMP	1
#define	IPPROTO_TCP	6
#define	IPPROTO_UDP	17

/* TCP port numbers */
#define	IPPORT_ECHO	7	/* Echo data port */
#define	IPPORT_DISCARD	9	/* Discard data port */
#define	IPPORT_FTPD	20	/* FTP Data port */
#define	IPPORT_FTP	21	/* FTP Control port */
#define IPPORT_TELNET	23	/* Telnet port */
#define IPPORT_SMTP	25	/* Mail port */
#define	IPPORT_FINGER	79	/* Finger port */
#define	IPPORT_TTYLINK	87	/* Chat port */
#define	IPPORT_NNTP	119	/* Netnews port */

/* UDP port numbers */
#define	IPPORT_DOMAIN	53
#define	IPPORT_RIP	520
#define	IPPORT_REMOTE	1234	/* Pulled out of the air */

#define	AF_INET		0
#define	AF_AX25		1
#define AF_NETROM	2
#define	AF_LOCAL	3

#define	SOCK_STREAM	0
#define	SOCK_DGRAM	1
#define	SOCK_RAW	2
#define SOCK_SEQPACKET	3

/* Socket flag values - controls newline mapping */
#define	SOCK_BINARY	0	/* socket in raw (binary) mode */
#define	SOCK_ASCII	1	/* socket in cooked (newline mapping) mode */
#define	SOCK_QUERY	2	/* Return setting without change */

#define	EMFILE	1
#define	EBADF	2
#define	EINVAL	3
#define	ESOCKTNOSUPPORT	4
#define	EAFNOSUPPORT	5
#define	EOPNOTSUPP	6
#define	EFAULT		7
#define	ENOTCONN	8
#define	ECONNREFUSED	9
#define EAFNOSUPP	10
#define	EISCONN		11
#define	EWOULDBLOCK	12
#define	EINTR		13
#define	EADDRINUSE	14
#define	ENOMEM		15
#define EMSGSIZE	16
#define	EALARM		17
#define	EABORT		18

extern int Axi_sock;	/* Socket listening to AX25 (there can be only one) */

/* Berkeley format socket address structures. These things were rather
 * poorly thought out, but compatibility is important (or so they say).
 * Note that all the sockaddr variants must be of the same size, 16 bytes
 * to be specific. Although attempts have been made to account for alignment
 * requirements (notably in sockaddr_ax), porters should check each
 * structure.
 */

/* Generic socket address structure */
struct sockaddr {
	short sa_family;
	char sa_data[14];
};

/* This is a structure for "historical" reasons (whatever they are) */
struct in_addr {
	unsigned long s_addr;
};

/* Socket address, DARPA Internet style */
struct sockaddr_in {
	short sin_family;
	unsigned short sin_port;
	struct in_addr sin_addr;
	char sin_zero[8];
};

/* Number of chars in interface field. The involved definition takes possible
 * alignment requirements into account, since ax25_addr is of an odd size.
 */
#define	ILEN	(sizeof(struct sockaddr) - sizeof(short) - AXALEN)

/* Socket address, AX.25 style */
struct sockaddr_ax {
	short sax_family;		/* 2 bytes */
	char ax25_addr[AXALEN];
	char iface[ILEN];		/* Interface name */
};

struct sockaddr_nr {
	short nr_family;
	struct nr4_addr nr_addr;
};

#define	SOCKSIZE	(sizeof(struct sockaddr))
#define MAXSOCKSIZE	SOCKSIZE /* All sockets are of the same size for now */
struct loc {
	struct usock *peer;
	struct mbuf *q;
	int hiwat;		/* Flow control point */
	int flags;
#define	LOC_SHUTDOWN	1
};
#define	NULLLOC	(struct loc *)0
#define	LOCDFLOW	5	/* dgram socket flow-control point, packets */
#define	LOCSFLOW	2048	/* stream socket flow control point, bytes */
#define	SOBUF		256	/* Size of buffer for usputc()/usprintf() */
#define	SOCKBASE	128	/* Start of socket indexes */

union cb {
	struct tcb *tcb;
	struct ax25_cb *ax25;
	struct udp_cb *udp;
	struct raw_ip *rip;
	struct raw_nr *rnr;
	struct nr4cb *nr4;
	struct loc *local;
	char *p;
};
union sp {
	struct sockaddr *sa;
	struct sockaddr_in *in;
	struct sockaddr_ax *ax;
	struct sockaddr_nr *nr;
	char *p;
};

/* User sockets */
struct usock {
	struct proc *owner;
	int refcnt;
	char noblock;
	char type;
#define	NOTUSED			0
#define	TYPE_TCP		1
#define	TYPE_UDP		2
#define	TYPE_AX25I		3
#define	TYPE_AX25UI		4
#define TYPE_RAW		5
#define TYPE_NETROML3		6
#define TYPE_NETROML4		7
#define	TYPE_LOCAL_STREAM	8
#define	TYPE_LOCAL_DGRAM	9
	int rdysock;
	union cb cb;
	char *name;
	int namelen;
	char *peername;
	int peernamelen;
	char errcodes[4];	/* Protocol-specific error codes */
	struct mbuf *obuf;	/* Output buffer */
	struct mbuf *ibuf;	/* Input buffer */
	char eol[3];		/* Text mode end-of-line sequence, if any */
	int flag;		/* Mode flags, defined in socket.h */
	int flush;		/* Character to trigger flush, if any */
	struct lzw *zout;	/* Pointer to compression structure */
	struct lzw *zin;
};
#define	NULLUSOCK	((struct usock *)0)

extern char Badsocket[];
extern char *Socktypes[];
extern struct usock *Usock;
extern int Nusock;

struct usock *itop __ARGS((int s));
void st_garbage __ARGS((int red));

#endif /* _USOCK_H */
