xref: /plan9/sys/src/9/ip/ipv6.h (revision 3f8719e627c63fd3cbe3e47e2f558b11cf0e6b13)
1f2c197d9SDavid du Colombier /*
2f2c197d9SDavid du Colombier  * Internet Protocol Version 6
3f2c197d9SDavid du Colombier  *
4f2c197d9SDavid du Colombier  * rfc2460 defines the protocol, rfc2461 neighbour discovery, and
5f2c197d9SDavid du Colombier  * rfc2462 address autoconfiguration.  rfc4443 defines ICMP; was rfc2463.
6f2c197d9SDavid du Colombier  * rfc4291 defines the address architecture (including prefices), was rfc3513.
7f2c197d9SDavid du Colombier  * rfc4007 defines the scoped address architecture.
8f2c197d9SDavid du Colombier  *
9f2c197d9SDavid du Colombier  * global unicast is anything but unspecified (::), loopback (::1),
10f2c197d9SDavid du Colombier  * multicast (ff00::/8), and link-local unicast (fe80::/10).
11f2c197d9SDavid du Colombier  *
12f2c197d9SDavid du Colombier  * site-local (fec0::/10) is now deprecated, originally by rfc3879.
13f2c197d9SDavid du Colombier  *
14f2c197d9SDavid du Colombier  * Unique Local IPv6 Unicast Addresses are defined by rfc4193.
15f2c197d9SDavid du Colombier  * prefix is fc00::/7, scope is global, routing is limited to roughly a site.
16f2c197d9SDavid du Colombier  */
173ff48bf5SDavid du Colombier #define isv6mcast(addr)	  ((addr)[0] == 0xff)
187def40e1SDavid du Colombier #define islinklocal(addr) ((addr)[0] == 0xfe && ((addr)[1] & 0xc0) == 0x80)
197def40e1SDavid du Colombier 
203ff48bf5SDavid du Colombier #define optexsts(np)	(nhgets((np)->ploadlen) > 24)
213ff48bf5SDavid du Colombier #define issmcast(addr)	(memcmp((addr), v6solicitednode, 13) == 0)
223ff48bf5SDavid du Colombier 
233ff48bf5SDavid du Colombier enum {				/* Header Types */
24ccf6439bSDavid du Colombier 	HBH		= 0,	/* hop-by-hop multicast routing protocol */
253ff48bf5SDavid du Colombier 	ICMP		= 1,
263ff48bf5SDavid du Colombier 	IGMP		= 2,
273ff48bf5SDavid du Colombier 	GGP		= 3,
283ff48bf5SDavid du Colombier 	IPINIP		= 4,
293ff48bf5SDavid du Colombier 	ST		= 5,
303ff48bf5SDavid du Colombier 	TCP		= 6,
313ff48bf5SDavid du Colombier 	UDP		= 17,
323ff48bf5SDavid du Colombier 	ISO_TP4		= 29,
333ff48bf5SDavid du Colombier 	RH		= 43,
343ff48bf5SDavid du Colombier 	FH		= 44,
353ff48bf5SDavid du Colombier 	IDRP		= 45,
363ff48bf5SDavid du Colombier 	RSVP		= 46,
373ff48bf5SDavid du Colombier 	AH		= 51,
383ff48bf5SDavid du Colombier 	ESP		= 52,
393ff48bf5SDavid du Colombier 	ICMPv6		= 58,
403ff48bf5SDavid du Colombier 	NNH		= 59,
413ff48bf5SDavid du Colombier 	DOH		= 60,
423ff48bf5SDavid du Colombier 	ISO_IP		= 80,
433ff48bf5SDavid du Colombier 	IGRP		= 88,
443ff48bf5SDavid du Colombier 	OSPF		= 89,
453ff48bf5SDavid du Colombier 
463ff48bf5SDavid du Colombier 	Maxhdrtype	= 256,
473ff48bf5SDavid du Colombier };
483ff48bf5SDavid du Colombier 
493ff48bf5SDavid du Colombier enum {
50ccf6439bSDavid du Colombier 	/* multicast flags and scopes */
513ff48bf5SDavid du Colombier 
52f2c197d9SDavid du Colombier //	Well_known_flg	= 0,
53f2c197d9SDavid du Colombier //	Transient_flg	= 1,
543ff48bf5SDavid du Colombier 
55f2c197d9SDavid du Colombier //	Interface_local_scop = 1,
56ccf6439bSDavid du Colombier 	Link_local_scop	= 2,
57f2c197d9SDavid du Colombier //	Site_local_scop	= 5,
58f2c197d9SDavid du Colombier //	Org_local_scop	= 8,
59ccf6439bSDavid du Colombier 	Global_scop	= 14,
603ff48bf5SDavid du Colombier 
61ccf6439bSDavid du Colombier 	/* various prefix lengths */
623ff48bf5SDavid du Colombier 	SOLN_PREF_LEN	= 13,
633ff48bf5SDavid du Colombier 
64f2c197d9SDavid du Colombier 	/* icmpv6 unreachability codes */
65f2c197d9SDavid du Colombier 	Icmp6_no_route		= 0,
66f2c197d9SDavid du Colombier 	Icmp6_ad_prohib		= 1,
67f2c197d9SDavid du Colombier 	Icmp6_out_src_scope	= 2,
68f2c197d9SDavid du Colombier 	Icmp6_adr_unreach	= 3,
69f2c197d9SDavid du Colombier 	Icmp6_port_unreach	= 4,
70f2c197d9SDavid du Colombier 	Icmp6_gress_src_fail	= 5,
71f2c197d9SDavid du Colombier 	Icmp6_rej_route		= 6,
72f2c197d9SDavid du Colombier 	Icmp6_unknown		= 7,  /* our own invention for internal use */
733ff48bf5SDavid du Colombier 
74ccf6439bSDavid du Colombier 	/* various flags & constants */
753ff48bf5SDavid du Colombier 	v6MINTU		= 1280,
763ff48bf5SDavid du Colombier 	HOP_LIMIT	= 255,
77*697312d7SDavid du Colombier 	IP6HDR		= 40,		/* sizeof(Ip6hdr) = 8 + 2*16 */
783ff48bf5SDavid du Colombier 
79ccf6439bSDavid du Colombier 	/* option types */
803ff48bf5SDavid du Colombier 
818c6ab946SDavid du Colombier 	/* neighbour discovery */
82ccf6439bSDavid du Colombier 	SRC_LLADDR	= 1,
83ccf6439bSDavid du Colombier 	TARGET_LLADDR	= 2,
843ff48bf5SDavid du Colombier 	PREFIX_INFO	= 3,
853ff48bf5SDavid du Colombier 	REDIR_HEADER	= 4,
863ff48bf5SDavid du Colombier 	MTU_OPTION	= 5,
878c6ab946SDavid du Colombier 	/* new since rfc2461; see iana.org/assignments/icmpv6-parameters */
888c6ab946SDavid du Colombier 	V6nd_home	= 8,
898c6ab946SDavid du Colombier 	V6nd_srcaddrs	= 9,		/* rfc3122 */
908c6ab946SDavid du Colombier 	V6nd_ip		= 17,
918c6ab946SDavid du Colombier 	/* /lib/rfc/drafts/draft-jeong-dnsop-ipv6-dns-discovery-12.txt */
928c6ab946SDavid du Colombier 	V6nd_rdns	= 25,
938c6ab946SDavid du Colombier 	/* plan 9 extensions */
948c6ab946SDavid du Colombier 	V6nd_9fs	= 250,
958c6ab946SDavid du Colombier 	V6nd_9auth	= 251,
963ff48bf5SDavid du Colombier 
973ff48bf5SDavid du Colombier 	SRC_UNSPEC	= 0,
983ff48bf5SDavid du Colombier 	SRC_UNI		= 1,
993ff48bf5SDavid du Colombier 	TARG_UNI	= 2,
1003ff48bf5SDavid du Colombier 	TARG_MULTI	= 3,
1013ff48bf5SDavid du Colombier 
102f2c197d9SDavid du Colombier 	Tunitent	= 1,
103f2c197d9SDavid du Colombier 	Tuniproxy	= 2,
104f2c197d9SDavid du Colombier 	Tunirany	= 3,
1053ff48bf5SDavid du Colombier 
106ccf6439bSDavid du Colombier 	/* Node constants */
1073ff48bf5SDavid du Colombier 	MAX_MULTICAST_SOLICIT	= 3,
1083ff48bf5SDavid du Colombier 	RETRANS_TIMER		= 1000,
1093ff48bf5SDavid du Colombier };
1103ff48bf5SDavid du Colombier 
111ccf6439bSDavid du Colombier typedef struct Ip6hdr	Ip6hdr;
112ccf6439bSDavid du Colombier typedef struct Opthdr	Opthdr;
113ccf6439bSDavid du Colombier typedef struct Routinghdr Routinghdr;
114ccf6439bSDavid du Colombier typedef struct Fraghdr6	Fraghdr6;
115ccf6439bSDavid du Colombier 
116410ea80bSDavid du Colombier /* we do this in case there's padding at the end of Ip6hdr */
117410ea80bSDavid du Colombier #define IPV6HDR \
118410ea80bSDavid du Colombier 	uchar	vcf[4];		/* version:4, traffic class:8, flow label:20 */\
119410ea80bSDavid du Colombier 	uchar	ploadlen[2];	/* payload length: packet length - 40 */ \
120410ea80bSDavid du Colombier 	uchar	proto;		/* next header type */ \
121410ea80bSDavid du Colombier 	uchar	ttl;		/* hop limit */ \
122410ea80bSDavid du Colombier 	uchar	src[IPaddrlen]; \
123410ea80bSDavid du Colombier 	uchar	dst[IPaddrlen]
124410ea80bSDavid du Colombier 
125ccf6439bSDavid du Colombier struct	Ip6hdr {
126410ea80bSDavid du Colombier 	IPV6HDR;
1277ec5746aSDavid du Colombier 	uchar	payload[];
128ccf6439bSDavid du Colombier };
129ccf6439bSDavid du Colombier 
1307ec5746aSDavid du Colombier struct	Opthdr {		/* unused */
131ccf6439bSDavid du Colombier 	uchar	nexthdr;
132ccf6439bSDavid du Colombier 	uchar	len;
133ccf6439bSDavid du Colombier };
134ccf6439bSDavid du Colombier 
1350c6300e7SDavid du Colombier /*
1360c6300e7SDavid du Colombier  * Beware routing header type 0 (loose source routing); see
1370c6300e7SDavid du Colombier  * http://www.secdev.org/conf/IPv6_RH_security-csw07.pdf.
1380c6300e7SDavid du Colombier  * Type 1 is unused.  Type 2 is for MIPv6 (mobile IPv6) filtering
1390c6300e7SDavid du Colombier  * against type 0 header.
1400c6300e7SDavid du Colombier  */
1417ec5746aSDavid du Colombier struct	Routinghdr {		/* unused */
142ccf6439bSDavid du Colombier 	uchar	nexthdr;
143ccf6439bSDavid du Colombier 	uchar	len;
144ccf6439bSDavid du Colombier 	uchar	rtetype;
145ccf6439bSDavid du Colombier 	uchar	segrem;
146ccf6439bSDavid du Colombier };
147ccf6439bSDavid du Colombier 
148ccf6439bSDavid du Colombier struct	Fraghdr6 {
149ccf6439bSDavid du Colombier 	uchar	nexthdr;
150ccf6439bSDavid du Colombier 	uchar	res;
151ccf6439bSDavid du Colombier 	uchar	offsetRM[2];	/* Offset, Res, M flag */
152ccf6439bSDavid du Colombier 	uchar	id[4];
153ccf6439bSDavid du Colombier };
1543ff48bf5SDavid du Colombier 
1553ff48bf5SDavid du Colombier extern uchar v6allnodesN[IPaddrlen];
1563ff48bf5SDavid du Colombier extern uchar v6allnodesL[IPaddrlen];
1573ff48bf5SDavid du Colombier extern uchar v6allroutersN[IPaddrlen];
1583ff48bf5SDavid du Colombier extern uchar v6allroutersL[IPaddrlen];
1593ff48bf5SDavid du Colombier extern uchar v6allnodesNmask[IPaddrlen];
1603ff48bf5SDavid du Colombier extern uchar v6allnodesLmask[IPaddrlen];
1613ff48bf5SDavid du Colombier extern uchar v6solicitednode[IPaddrlen];
1623ff48bf5SDavid du Colombier extern uchar v6solicitednodemask[IPaddrlen];
1633ff48bf5SDavid du Colombier extern uchar v6Unspecified[IPaddrlen];
1643ff48bf5SDavid du Colombier extern uchar v6loopback[IPaddrlen];
1653ff48bf5SDavid du Colombier extern uchar v6loopbackmask[IPaddrlen];
1663ff48bf5SDavid du Colombier extern uchar v6linklocal[IPaddrlen];
1673ff48bf5SDavid du Colombier extern uchar v6linklocalmask[IPaddrlen];
1683ff48bf5SDavid du Colombier extern uchar v6multicast[IPaddrlen];
1693ff48bf5SDavid du Colombier extern uchar v6multicastmask[IPaddrlen];
1703ff48bf5SDavid du Colombier 
17167493d07SDavid du Colombier extern int v6llpreflen;
17267493d07SDavid du Colombier extern int v6mcpreflen;
17367493d07SDavid du Colombier extern int v6snpreflen;
17467493d07SDavid du Colombier extern int v6aNpreflen;
17567493d07SDavid du Colombier extern int v6aLpreflen;
1763ff48bf5SDavid du Colombier 
1773ff48bf5SDavid du Colombier extern int ReTransTimer;
178ccf6439bSDavid du Colombier 
179ccf6439bSDavid du Colombier void ipv62smcast(uchar *, uchar *);
180ccf6439bSDavid du Colombier void icmpns(Fs *f, uchar* src, int suni, uchar* targ, int tuni, uchar* mac);
181ccf6439bSDavid du Colombier void icmpna(Fs *f, uchar* src, uchar* dst, uchar* targ, uchar* mac, uchar flags);
182ccf6439bSDavid du Colombier void icmpttlexceeded6(Fs *f, Ipifc *ifc, Block *bp);
183ccf6439bSDavid du Colombier void icmppkttoobig6(Fs *f, Ipifc *ifc, Block *bp);
184ccf6439bSDavid du Colombier void icmphostunr(Fs *f, Ipifc *ifc, Block *bp, int code, int free);
185