/*
 *	Definitions for the dummy or localhost IP implementation.
 *
 *	01/21/94, kay roemer.
 */

#ifndef _IP_H
#define _IP_H

#include "timer.h"
#include "buf.h"
#include "if.h"
#include "route.h"

/* Minimal accepable length of an IP packet */
#define IP_MINLEN	(sizeof (struct ip_dgram))

#define IP_DEFAULT_TTL	255
#define IP_DEFAULT_TOS	0

/* Some macros to access data in the ip header for higher level protocols */
#define IP_HDRLEN(buf)	(((struct ip_dgram *)(buf)->dstart)->hdrlen * 4)
#define IP_DADDR(buf)	(((struct ip_dgram *)(buf)->dstart)->daddr)
#define IP_SADDR(buf)	(((struct ip_dgram *)(buf)->dstart)->saddr)
#define IP_PROTO(buf)	(((struct ip_dgram *)(buf)->dstart)->proto)
#define IP_DATA(buf)	((buf)->dstart + \
	((struct ip_dgram *)(buf)->dstart)->hdrlen * sizeof (long))

/* IP datagramm */
struct ip_dgram {
	unsigned char	version:4;	/* version number */
#define IP_VERSION	4		/* current IP version */

	unsigned char	hdrlen:4;	/* header len */
	unsigned char	tos;		/* type of service and precedence */
	unsigned short	length;		/* datagram length */
	unsigned short	id;		/* datagram id */
	unsigned short	fragoff;	/* fragment offset */
#define IP_MF		0x2000		/* more fragments bit */
#define IP_DF		0x4000		/* don't fragment bit */
#define IP_FRAGOFF	0x1fff		/* fragment offset */

	unsigned char	ttl;		/* time to live */
	unsigned char	proto;		/* next protocol id */
	short		chksum;		/* checksum */
	unsigned long	saddr;		/* IP source address */
	unsigned long	daddr;		/* IP destination address */
	char		data[0];	/* options and data */
};

struct fragment {
	BUF		*buf;		/* chain of fragments */
	short		id;		/* IP datagram id */
	unsigned long	saddr;		/* IP source address */
	long		totlen;		/* total datagram length */
	long		curlen;		/* current datagram length */
	struct event	tmout;		/* timeout event */
};

#define IPFRAG_HEADS	16		/* max # of fragment lists */
#define IPFRAG_TMOUT	(60000/EVTGRAN)	/* timeout reassambly after 1 min */

struct ip_options {
	short		pri;
	unsigned char	ttl;
	unsigned char	tos;
	unsigned char	hdrincl:1;
};

/* IP Type Of Service */
#define IPTOS_LOWDELAY	0x10
#define IPTOS_THROUPUT	0x08
#define IPTOS_RELIABLE	0x04

#define IPTOS_PRIORITY(x)	(((x) & 0xe0) >> 5)

/* IP options */
#define IPOPT_COPY	0x80		/* copy on fragmentation flag */
#define IPOPT_CLASS	0x60		/* option class */
#define IPOPT_NUMBER	0x1f		/* option number */
#define IPOPT_TYPE	(IPOPT_CLASS|IPOPT_NUMBER)

#define IPOPT_EOL	0x00		/* end of option list */
#define IPOPT_NOP	0x01		/* no operation */
#define IPOPT_SECURITY	0x02		/* security option */
#define IPOPT_LSRR	0x03		/* loose source and record route */
#define IPOPT_SSRR	0x09		/* strict source and record route */
#define IPOPT_RR	0x07		/* record route option */
#define IPOPT_STREAM	0x08		/* SATNET stream id option */
#define IPOPT_STAMP	0x44		/* internet time stamp option */

/*
 * Return values from ip_chk_addr()
 */
#define IPADDR_NONE	0
#define IPADDR_LOCAL	1
#define IPADDR_BRDCST	2
#define IPADDR_BADCLASS	3

/*
 * Flags for ip_send()
 */
#define IP_DONTROUTE	0x01
#define IP_BROADCAST	0x02

#ifndef NOEXTERNS
extern long		ip_setsockopt (struct ip_options *, short, short,
				char *, long);
extern long		ip_getsockopt (struct ip_options *, short, short,
				char *, long *);

extern short		ip_is_brdcst_addr (unsigned long);
extern short		ip_is_local_addr (unsigned long);

extern unsigned long	ip_local_addr (unsigned long);
extern short		ip_same_addr (unsigned long, unsigned long);
extern unsigned long	ip_dst_addr (unsigned long);
extern short		ip_chk_addr (unsigned long, struct route *);
extern short		ip_priority (short, unsigned char);

struct in_ip_ops;

extern void		ip_register (struct in_ip_ops *);
extern unsigned long	ip_netmask (unsigned long);
extern void		ip_input (struct netif *, BUF *);
extern long		ip_send (unsigned long, unsigned long, BUF *,
				short, short, struct ip_options *);

extern long		ip_output (BUF *);
#endif

#endif /* _IP_H */
