1/*
2 * ip.h
3 *
4 * Internet Protocol (RFC 791).
5 *
6 * Copyright (c) 2000 Dug Song <dugsong@monkey.org>
7 *
8 * $Id: ip.h,v 1.23 2003/03/16 17:39:17 dugsong Exp $
9 */
10
11#ifndef DNET_IP_H
12#define DNET_IP_H
13
14#define IP_ADDR_LEN	4		/* IP address length */
15#define IP_ADDR_BITS	32		/* IP address bits */
16
17#define IP_HDR_LEN	20		/* base IP header length */
18#define IP_OPT_LEN	2		/* base IP option length */
19#define IP_OPT_LEN_MAX	40
20#define IP_HDR_LEN_MAX	(IP_HDR_LEN + IP_OPT_LEN_MAX)
21
22#define IP_LEN_MAX	65535
23#define IP_LEN_MIN	IP_HDR_LEN
24
25typedef uint32_t	ip_addr_t;
26
27#ifndef __GNUC__
28# define __attribute__(x)
29# pragma pack(1)
30#endif
31
32/*
33 * IP header, without options
34 */
35struct ip_hdr {
36#if DNET_BYTESEX == DNET_BIG_ENDIAN
37        uint8_t		ip_v:4,		/* version */
38                        ip_hl:4;	/* header length (incl any options) */
39#elif DNET_BYTESEX == DNET_LIL_ENDIAN
40        uint8_t		ip_hl:4,
41                        ip_v:4;
42#else
43# error "need to include <dnet.h>"
44#endif
45        uint8_t		ip_tos;		/* type of service */
46        uint16_t	ip_len;		/* total length (incl header) */
47        uint16_t	ip_id;		/* identification */
48        uint16_t	ip_off;		/* fragment offset and flags */
49        uint8_t		ip_ttl;		/* time to live */
50        uint8_t		ip_p;		/* protocol */
51        uint16_t	ip_sum;		/* checksum */
52        ip_addr_t	ip_src;		/* source address */
53        ip_addr_t	ip_dst;		/* destination address */
54};
55
56/*
57 * Type of service (ip_tos), RFC 1349 ("obsoleted by RFC 2474")
58 */
59#define IP_TOS_DEFAULT		0x00	/* default */
60#define IP_TOS_LOWDELAY		0x10	/* low delay */
61#define IP_TOS_THROUGHPUT	0x08	/* high throughput */
62#define IP_TOS_RELIABILITY	0x04	/* high reliability */
63#define IP_TOS_LOWCOST		0x02	/* low monetary cost - XXX */
64#define IP_TOS_ECT		0x02	/* ECN-capable transport */
65#define IP_TOS_CE		0x01	/* congestion experienced */
66
67/*
68 * IP precedence (high 3 bits of ip_tos), hopefully unused
69 */
70#define IP_TOS_PREC_ROUTINE		0x00
71#define IP_TOS_PREC_PRIORITY		0x20
72#define IP_TOS_PREC_IMMEDIATE		0x40
73#define IP_TOS_PREC_FLASH		0x60
74#define IP_TOS_PREC_FLASHOVERRIDE	0x80
75#define IP_TOS_PREC_CRITIC_ECP		0xa0
76#define IP_TOS_PREC_INTERNETCONTROL	0xc0
77#define IP_TOS_PREC_NETCONTROL		0xe0
78
79/*
80 * Fragmentation flags (ip_off)
81 */
82#define IP_RF		0x8000		/* reserved */
83#define IP_DF		0x4000		/* don't fragment */
84#define IP_MF		0x2000		/* more fragments (not last frag) */
85#define IP_OFFMASK	0x1fff		/* mask for fragment offset */
86
87/*
88 * Time-to-live (ip_ttl), seconds
89 */
90#define IP_TTL_DEFAULT	64		/* default ttl, RFC 1122, RFC 1340 */
91#define IP_TTL_MAX	255		/* maximum ttl */
92
93/*
94 * Protocol (ip_p) - http://www.iana.org/assignments/protocol-numbers
95 */
96#define	IP_PROTO_IP		0		/* dummy for IP */
97#define IP_PROTO_HOPOPTS	IP_PROTO_IP	/* IPv6 hop-by-hop options */
98#define	IP_PROTO_ICMP		1		/* ICMP */
99#define	IP_PROTO_IGMP		2		/* IGMP */
100#define IP_PROTO_GGP		3		/* gateway-gateway protocol */
101#define	IP_PROTO_IPIP		4		/* IP in IP */
102#define IP_PROTO_ST		5		/* ST datagram mode */
103#define	IP_PROTO_TCP		6		/* TCP */
104#define IP_PROTO_CBT		7		/* CBT */
105#define	IP_PROTO_EGP		8		/* exterior gateway protocol */
106#define IP_PROTO_IGP		9		/* interior gateway protocol */
107#define IP_PROTO_BBNRCC		10		/* BBN RCC monitoring */
108#define IP_PROTO_NVP		11		/* Network Voice Protocol */
109#define	IP_PROTO_PUP		12		/* PARC universal packet */
110#define IP_PROTO_ARGUS		13		/* ARGUS */
111#define IP_PROTO_EMCON		14		/* EMCON */
112#define IP_PROTO_XNET		15		/* Cross Net Debugger */
113#define IP_PROTO_CHAOS		16		/* Chaos */
114#define	IP_PROTO_UDP		17		/* UDP */
115#define IP_PROTO_MUX		18		/* multiplexing */
116#define IP_PROTO_DCNMEAS	19		/* DCN measurement */
117#define IP_PROTO_HMP		20		/* Host Monitoring Protocol */
118#define IP_PROTO_PRM		21		/* Packet Radio Measurement */
119#define	IP_PROTO_IDP		22		/* Xerox NS IDP */
120#define IP_PROTO_TRUNK1		23		/* Trunk-1 */
121#define IP_PROTO_TRUNK2		24		/* Trunk-2 */
122#define IP_PROTO_LEAF1		25		/* Leaf-1 */
123#define IP_PROTO_LEAF2		26		/* Leaf-2 */
124#define IP_PROTO_RDP		27		/* "Reliable Datagram" proto */
125#define IP_PROTO_IRTP		28		/* Inet Reliable Transaction */
126#define	IP_PROTO_TP		29 		/* ISO TP class 4 */
127#define IP_PROTO_NETBLT		30		/* Bulk Data Transfer */
128#define IP_PROTO_MFPNSP		31		/* MFE Network Services */
129#define IP_PROTO_MERITINP	32		/* Merit Internodal Protocol */
130#define IP_PROTO_SEP		33		/* Sequential Exchange proto */
131#define IP_PROTO_3PC		34		/* Third Party Connect proto */
132#define IP_PROTO_IDPR		35		/* Interdomain Policy Route */
133#define IP_PROTO_XTP		36		/* Xpress Transfer Protocol */
134#define IP_PROTO_DDP		37		/* Datagram Delivery Proto */
135#define IP_PROTO_CMTP		38		/* IDPR Ctrl Message Trans */
136#define IP_PROTO_TPPP		39		/* TP++ Transport Protocol */
137#define IP_PROTO_IL		40		/* IL Transport Protocol */
138#define IP_PROTO_IPV6		41		/* IPv6 */
139#define IP_PROTO_SDRP		42		/* Source Demand Routing */
140#define IP_PROTO_ROUTING	43		/* IPv6 routing header */
141#define IP_PROTO_FRAGMENT	44		/* IPv6 fragmentation header */
142#define IP_PROTO_RSVP		46		/* Reservation protocol */
143#define	IP_PROTO_GRE		47		/* General Routing Encap */
144#define IP_PROTO_MHRP		48		/* Mobile Host Routing */
145#define IP_PROTO_ENA		49		/* ENA */
146#define	IP_PROTO_ESP		50		/* Encap Security Payload */
147#define	IP_PROTO_AH		51		/* Authentication Header */
148#define IP_PROTO_INLSP		52		/* Integated Net Layer Sec */
149#define IP_PROTO_SWIPE		53		/* SWIPE */
150#define IP_PROTO_NARP		54		/* NBMA Address Resolution */
151#define	IP_PROTO_MOBILE		55		/* Mobile IP, RFC 2004 */
152#define IP_PROTO_TLSP		56		/* Transport Layer Security */
153#define IP_PROTO_SKIP		57		/* SKIP */
154#define IP_PROTO_ICMPV6		58		/* ICMP for IPv6 */
155#define IP_PROTO_NONE		59		/* IPv6 no next header */
156#define IP_PROTO_DSTOPTS	60		/* IPv6 destination options */
157#define IP_PROTO_ANYHOST	61		/* any host internal proto */
158#define IP_PROTO_CFTP		62		/* CFTP */
159#define IP_PROTO_ANYNET		63		/* any local network */
160#define IP_PROTO_EXPAK		64		/* SATNET and Backroom EXPAK */
161#define IP_PROTO_KRYPTOLAN	65		/* Kryptolan */
162#define IP_PROTO_RVD		66		/* MIT Remote Virtual Disk */
163#define IP_PROTO_IPPC		67		/* Inet Pluribus Packet Core */
164#define IP_PROTO_DISTFS		68		/* any distributed fs */
165#define IP_PROTO_SATMON		69		/* SATNET Monitoring */
166#define IP_PROTO_VISA		70		/* VISA Protocol */
167#define IP_PROTO_IPCV		71		/* Inet Packet Core Utility */
168#define IP_PROTO_CPNX		72		/* Comp Proto Net Executive */
169#define IP_PROTO_CPHB		73		/* Comp Protocol Heart Beat */
170#define IP_PROTO_WSN		74		/* Wang Span Network */
171#define IP_PROTO_PVP		75		/* Packet Video Protocol */
172#define IP_PROTO_BRSATMON	76		/* Backroom SATNET Monitor */
173#define IP_PROTO_SUNND		77		/* SUN ND Protocol */
174#define IP_PROTO_WBMON		78		/* WIDEBAND Monitoring */
175#define IP_PROTO_WBEXPAK	79		/* WIDEBAND EXPAK */
176#define	IP_PROTO_EON		80		/* ISO CNLP */
177#define IP_PROTO_VMTP		81		/* Versatile Msg Transport*/
178#define IP_PROTO_SVMTP		82		/* Secure VMTP */
179#define IP_PROTO_VINES		83		/* VINES */
180#define IP_PROTO_TTP		84		/* TTP */
181#define IP_PROTO_NSFIGP		85		/* NSFNET-IGP */
182#define IP_PROTO_DGP		86		/* Dissimilar Gateway Proto */
183#define IP_PROTO_TCF		87		/* TCF */
184#define IP_PROTO_EIGRP		88		/* EIGRP */
185#define IP_PROTO_OSPF		89		/* Open Shortest Path First */
186#define IP_PROTO_SPRITERPC	90		/* Sprite RPC Protocol */
187#define IP_PROTO_LARP		91		/* Locus Address Resolution */
188#define IP_PROTO_MTP		92		/* Multicast Transport Proto */
189#define IP_PROTO_AX25		93		/* AX.25 Frames */
190#define IP_PROTO_IPIPENCAP	94		/* yet-another IP encap */
191#define IP_PROTO_MICP		95		/* Mobile Internet Ctrl */
192#define IP_PROTO_SCCSP		96		/* Semaphore Comm Sec Proto */
193#define IP_PROTO_ETHERIP	97		/* Ethernet in IPv4 */
194#define	IP_PROTO_ENCAP		98		/* encapsulation header */
195#define IP_PROTO_ANYENC		99		/* private encryption scheme */
196#define IP_PROTO_GMTP		100		/* GMTP */
197#define IP_PROTO_IFMP		101		/* Ipsilon Flow Mgmt Proto */
198#define IP_PROTO_PNNI		102		/* PNNI over IP */
199#define IP_PROTO_PIM		103		/* Protocol Indep Multicast */
200#define IP_PROTO_ARIS		104		/* ARIS */
201#define IP_PROTO_SCPS		105		/* SCPS */
202#define IP_PROTO_QNX		106		/* QNX */
203#define IP_PROTO_AN		107		/* Active Networks */
204#define IP_PROTO_IPCOMP		108		/* IP Payload Compression */
205#define IP_PROTO_SNP		109		/* Sitara Networks Protocol */
206#define IP_PROTO_COMPAQPEER	110		/* Compaq Peer Protocol */
207#define IP_PROTO_IPXIP		111		/* IPX in IP */
208#define IP_PROTO_VRRP		112		/* Virtual Router Redundancy */
209#define IP_PROTO_PGM		113		/* PGM Reliable Transport */
210#define IP_PROTO_ANY0HOP	114		/* 0-hop protocol */
211#define IP_PROTO_L2TP		115		/* Layer 2 Tunneling Proto */
212#define IP_PROTO_DDX		116		/* D-II Data Exchange (DDX) */
213#define IP_PROTO_IATP		117		/* Interactive Agent Xfer */
214#define IP_PROTO_STP		118		/* Schedule Transfer Proto */
215#define IP_PROTO_SRP		119		/* SpectraLink Radio Proto */
216#define IP_PROTO_UTI		120		/* UTI */
217#define IP_PROTO_SMP		121		/* Simple Message Protocol */
218#define IP_PROTO_SM		122		/* SM */
219#define IP_PROTO_PTP		123		/* Performance Transparency */
220#define IP_PROTO_ISIS		124		/* ISIS over IPv4 */
221#define IP_PROTO_FIRE		125		/* FIRE */
222#define IP_PROTO_CRTP		126		/* Combat Radio Transport */
223#define IP_PROTO_CRUDP		127		/* Combat Radio UDP */
224#define IP_PROTO_SSCOPMCE	128		/* SSCOPMCE */
225#define IP_PROTO_IPLT		129		/* IPLT */
226#define IP_PROTO_SPS		130		/* Secure Packet Shield */
227#define IP_PROTO_PIPE		131		/* Private IP Encap in IP */
228#define IP_PROTO_SCTP		132		/* Stream Ctrl Transmission */
229#define IP_PROTO_FC		133		/* Fibre Channel */
230#define IP_PROTO_RSVPIGN	134		/* RSVP-E2E-IGNORE */
231#define	IP_PROTO_RAW		255		/* Raw IP packets */
232#define IP_PROTO_RESERVED	IP_PROTO_RAW	/* Reserved */
233#define	IP_PROTO_MAX		255
234
235/*
236 * Option types (opt_type) - http://www.iana.org/assignments/ip-parameters
237 */
238#define IP_OPT_CONTROL		0x00		/* control */
239#define IP_OPT_DEBMEAS		0x40		/* debugging & measurement */
240#define IP_OPT_COPY		0x80		/* copy into all fragments */
241#define IP_OPT_RESERVED1	0x20
242#define IP_OPT_RESERVED2	0x60
243
244#define IP_OPT_EOL	  0			/* end of option list */
245#define IP_OPT_NOP	  1			/* no operation */
246#define IP_OPT_SEC	 (2|IP_OPT_COPY)	/* DoD basic security */
247#define IP_OPT_LSRR	 (3|IP_OPT_COPY)	/* loose source route */
248#define IP_OPT_TS	 (4|IP_OPT_DEBMEAS)	/* timestamp */
249#define IP_OPT_ESEC	 (5|IP_OPT_COPY)	/* DoD extended security */
250#define IP_OPT_CIPSO	 (6|IP_OPT_COPY)	/* commercial security */
251#define IP_OPT_RR	  7			/* record route */
252#define IP_OPT_SATID	 (8|IP_OPT_COPY)	/* stream ID (obsolete) */
253#define IP_OPT_SSRR	 (9|IP_OPT_COPY)	/* strict source route */
254#define IP_OPT_ZSU	 10			/* experimental measurement */
255#define IP_OPT_MTUP	 11			/* MTU probe */
256#define IP_OPT_MTUR	 12			/* MTU reply */
257#define IP_OPT_FINN	(13|IP_OPT_COPY|IP_OPT_DEBMEAS)	/* exp flow control */
258#define IP_OPT_VISA	(14|IP_OPT_COPY)	/* exp access control */
259#define IP_OPT_ENCODE	 15			/* ??? */
260#define IP_OPT_IMITD	(16|IP_OPT_COPY)	/* IMI traffic descriptor */
261#define IP_OPT_EIP	(17|IP_OPT_COPY)	/* extended IP, RFC 1385 */
262#define IP_OPT_TR	(18|IP_OPT_DEBMEAS)	/* traceroute */
263#define IP_OPT_ADDEXT	(19|IP_OPT_COPY)	/* IPv7 ext addr, RFC 1475 */
264#define IP_OPT_RTRALT	(20|IP_OPT_COPY)	/* router alert, RFC 2113 */
265#define IP_OPT_SDB	(21|IP_OPT_COPY)	/* directed bcast, RFC 1770 */
266#define IP_OPT_NSAPA	(22|IP_OPT_COPY)	/* NSAP addresses */
267#define IP_OPT_DPS	(23|IP_OPT_COPY)	/* dynamic packet state */
268#define IP_OPT_UMP	(24|IP_OPT_COPY)	/* upstream multicast */
269#define IP_OPT_MAX	 25
270
271#define IP_OPT_COPIED(o)	((o) & 0x80)
272#define IP_OPT_CLASS(o)		((o) & 0x60)
273#define IP_OPT_NUMBER(o)	((o) & 0x1f)
274#define IP_OPT_TYPEONLY(o)	((o) == IP_OPT_EOL || (o) == IP_OPT_NOP)
275
276/*
277 * Security option data - RFC 791, 3.1
278 */
279struct ip_opt_data_sec {
280        uint16_t	s;		/* security */
281        uint16_t	c;		/* compartments */
282        uint16_t	h;		/* handling restrictions */
283        uint8_t		tcc[3];		/* transmission control code */
284} __attribute__((__packed__));
285
286#define IP_OPT_SEC_UNCLASS	0x0000	/* unclassified */
287#define IP_OPT_SEC_CONFID	0xf135	/* confidential */
288#define IP_OPT_SEC_EFTO		0x789a	/* EFTO */
289#define IP_OPT_SEC_MMMM		0xbc4d	/* MMMM */
290#define IP_OPT_SEC_PROG		0x5e26	/* PROG */
291#define IP_OPT_SEC_RESTR	0xaf13	/* restricted */
292#define IP_OPT_SEC_SECRET	0xd788	/* secret */
293#define IP_OPT_SEC_TOPSECRET	0x6bc5	/* top secret */
294
295/*
296 * {Loose Source, Record, Strict Source} Route option data - RFC 791, 3.1
297 */
298struct ip_opt_data_rr {
299        uint8_t		ptr;		/* from start of option, >= 4 */
300        uint32_t	iplist __flexarr; /* list of IP addresses */
301} __attribute__((__packed__));
302
303/*
304 * Timestamp option data - RFC 791, 3.1
305 */
306struct ip_opt_data_ts {
307        uint8_t		ptr;		/* from start of option, >= 5 */
308#if DNET_BYTESEX == DNET_BIG_ENDIAN
309        uint8_t		oflw:4,		/* number of IPs skipped */
310                        flg:4;		/* address[ / timestamp] flag */
311#elif DNET_BYTESEX == DNET_LIL_ENDIAN
312        uint8_t		flg:4,
313                        oflw:4;
314#endif
315        uint32_t	ipts __flexarr;	/* IP address [/ timestamp] pairs */
316} __attribute__((__packed__));
317
318#define IP_OPT_TS_TSONLY	0	/* timestamps only */
319#define IP_OPT_TS_TSADDR	1	/* IP address / timestamp pairs */
320#define IP_OPT_TS_PRESPEC	3	/* IP address / zero timestamp pairs */
321
322/*
323 * Traceroute option data - RFC 1393, 2.2
324 */
325struct ip_opt_data_tr {
326        uint16_t	id;		/* ID number */
327        uint16_t	ohc;		/* outbound hop count */
328        uint16_t	rhc;		/* return hop count */
329        uint32_t	origip;		/* originator IP address */
330} __attribute__((__packed__));
331
332/*
333 * IP option (following IP header)
334 */
335struct ip_opt {
336        uint8_t		opt_type;	/* option type */
337        uint8_t		opt_len;	/* option length >= IP_OPT_LEN */
338        union ip_opt_data {
339                struct ip_opt_data_sec	sec;	   /* IP_OPT_SEC */
340                struct ip_opt_data_rr	rr;	   /* IP_OPT_{L,S}RR */
341                struct ip_opt_data_ts	ts;	   /* IP_OPT_TS */
342                uint16_t		satid;	   /* IP_OPT_SATID */
343                uint16_t		mtu;	   /* IP_OPT_MTU{P,R} */
344                struct ip_opt_data_tr	tr;	   /* IP_OPT_TR */
345                uint32_t		addext[2]; /* IP_OPT_ADDEXT */
346                uint16_t		rtralt;    /* IP_OPT_RTRALT */
347                uint32_t		sdb[9];    /* IP_OPT_SDB */
348                uint8_t			data8[IP_OPT_LEN_MAX - IP_OPT_LEN];
349        } opt_data;
350} __attribute__((__packed__));
351
352#ifndef __GNUC__
353# pragma pack()
354#endif
355
356/*
357 * Classful addressing
358 */
359#define	IP_CLASSA(i)		(((uint32_t)(i) & htonl(0x80000000)) == \
360                                 htonl(0x00000000))
361#define	IP_CLASSA_NET		(htonl(0xff000000))
362#define	IP_CLASSA_NSHIFT	24
363#define	IP_CLASSA_HOST		(htonl(0x00ffffff))
364#define	IP_CLASSA_MAX		128
365
366#define	IP_CLASSB(i)		(((uint32_t)(i) & htonl(0xc0000000)) == \
367                                 htonl(0x80000000))
368#define	IP_CLASSB_NET		(htonl(0xffff0000))
369#define	IP_CLASSB_NSHIFT	16
370#define	IP_CLASSB_HOST		(htonl(0x0000ffff))
371#define	IP_CLASSB_MAX		65536
372
373#define	IP_CLASSC(i)		(((uint32_t)(i) & htonl(0xe0000000)) == \
374                                 htonl(0xc0000000))
375#define	IP_CLASSC_NET		(htonl(0xffffff00))
376#define	IP_CLASSC_NSHIFT	8
377#define	IP_CLASSC_HOST		(htonl(0x000000ff))
378
379#define	IP_CLASSD(i)		(((uint32_t)(i) & htonl(0xf0000000)) == \
380                                 htonl(0xe0000000))
381/* These ones aren't really net and host fields, but routing needn't know. */
382#define	IP_CLASSD_NET		(htonl(0xf0000000))
383#define	IP_CLASSD_NSHIFT	28
384#define	IP_CLASSD_HOST		(htonl(0x0fffffff))
385#define	IP_MULTICAST(i)		IP_CLASSD(i)
386
387#define	IP_EXPERIMENTAL(i)	(((uint32_t)(i) & htonl(0xf0000000)) == \
388                                 htonl(0xf0000000))
389#define	IP_BADCLASS(i)		(((uint32_t)(i) & htonl(0xf0000000)) == \
390                                 htonl(0xf0000000))
391#define	IP_LOCAL_GROUP(i)	(((uint32_t)(i) & htonl(0xffffff00)) == \
392                                 htonl(0xe0000000))
393/*
394 * Reserved addresses
395 */
396#define IP_ADDR_ANY		(htonl(0x00000000))	/* 0.0.0.0 */
397#define IP_ADDR_BROADCAST	(htonl(0xffffffff))	/* 255.255.255.255 */
398#define IP_ADDR_LOOPBACK	(htonl(0x7f000001))	/* 127.0.0.1 */
399#define IP_ADDR_MCAST_ALL	(htonl(0xe0000001))	/* 224.0.0.1 */
400#define IP_ADDR_MCAST_LOCAL	(htonl(0xe00000ff))	/* 224.0.0.225 */
401
402#define ip_pack_hdr(hdr, tos, len, id, off, ttl, p, src, dst) do {	\
403        struct ip_hdr *ip_pack_p = (struct ip_hdr *)(hdr);		\
404        ip_pack_p->ip_v = 4; ip_pack_p->ip_hl = 5;			\
405        ip_pack_p->ip_tos = tos; ip_pack_p->ip_len = htons(len);	\
406        ip_pack_p->ip_id = htons(id); ip_pack_p->ip_off = htons(off);	\
407        ip_pack_p->ip_ttl = ttl; ip_pack_p->ip_p = p;			\
408        ip_pack_p->ip_src = src; ip_pack_p->ip_dst = dst;		\
409} while (0)
410
411typedef struct ip_handle ip_t;
412
413__BEGIN_DECLS
414ip_t	*ip_open(void);
415size_t	 ip_send(ip_t *i, const void *buf, size_t len);
416ip_t	*ip_close(ip_t *i);
417
418char	*ip_ntop(const ip_addr_t *ip, char *dst, size_t len);
419int	 ip_pton(const char *src, ip_addr_t *dst);
420char	*ip_ntoa(const ip_addr_t *ip);
421#define	 ip_aton ip_pton
422
423size_t	 ip_add_option(void *buf, size_t len,
424            int proto, const void *optbuf, size_t optlen);
425void	 ip_checksum(void *buf, size_t len);
426
427inline int
428ip_cksum_add(const void *buf, size_t len, int cksum)
429{
430        uint16_t *sp = (uint16_t *)buf;
431        int sn;
432
433        sn = len / 2;
434
435        do {
436            cksum += *sp++;
437        } while (--sn > 0);
438        if (len & 1)
439                cksum += htons(*(u_char *)sp << 8);
440
441        return (cksum);
442}
443
444inline uint16_t
445ip_cksum_carry(int x)
446{
447        x = (x >> 16) + (x & 0xffff);
448        return ~(x + (x >> 16)) & 0xffff;
449}
450
451__END_DECLS
452
453#endif /* DNET_IP_H */
454