xref: /plan9-contrib/sys/src/9k/ip/ipv6.h (revision a3323688dee1e9a0fcc1d7d933e3ce101170952d)
1*9ef1f84bSDavid du Colombier /*
2*9ef1f84bSDavid du Colombier  * Internet Protocol Version 6
3*9ef1f84bSDavid du Colombier  *
4*9ef1f84bSDavid du Colombier  * rfc2460 defines the protocol, rfc2461 neighbour discovery, and
5*9ef1f84bSDavid du Colombier  * rfc2462 address autoconfiguration.  rfc4443 defines ICMP; was rfc2463.
6*9ef1f84bSDavid du Colombier  * rfc4291 defines the address architecture (including prefices), was rfc3513.
7*9ef1f84bSDavid du Colombier  * rfc4007 defines the scoped address architecture.
8*9ef1f84bSDavid du Colombier  *
9*9ef1f84bSDavid du Colombier  * global unicast is anything but unspecified (::), loopback (::1),
10*9ef1f84bSDavid du Colombier  * multicast (ff00::/8), and link-local unicast (fe80::/10).
11*9ef1f84bSDavid du Colombier  *
12*9ef1f84bSDavid du Colombier  * site-local (fec0::/10) is now deprecated, originally by rfc3879.
13*9ef1f84bSDavid du Colombier  *
14*9ef1f84bSDavid du Colombier  * Unique Local IPv6 Unicast Addresses are defined by rfc4193.
15*9ef1f84bSDavid du Colombier  * prefix is fc00::/7, scope is global, routing is limited to roughly a site.
16*9ef1f84bSDavid du Colombier  */
17*9ef1f84bSDavid du Colombier #define isv6mcast(addr)	  ((addr)[0] == 0xff)
18*9ef1f84bSDavid du Colombier #define islinklocal(addr) ((addr)[0] == 0xfe && ((addr)[1] & 0xc0) == 0x80)
19*9ef1f84bSDavid du Colombier 
20*9ef1f84bSDavid du Colombier #define optexsts(np)	(nhgets((np)->ploadlen) > 24)
21*9ef1f84bSDavid du Colombier #define issmcast(addr)	(memcmp((addr), v6solicitednode, 13) == 0)
22*9ef1f84bSDavid du Colombier 
23*9ef1f84bSDavid du Colombier enum {				/* Header Types */
24*9ef1f84bSDavid du Colombier 	HBH		= 0,	/* hop-by-hop multicast routing protocol */
25*9ef1f84bSDavid du Colombier 	ICMP		= 1,
26*9ef1f84bSDavid du Colombier 	IGMP		= 2,
27*9ef1f84bSDavid du Colombier 	GGP		= 3,
28*9ef1f84bSDavid du Colombier 	IPINIP		= 4,
29*9ef1f84bSDavid du Colombier 	ST		= 5,
30*9ef1f84bSDavid du Colombier 	TCP		= 6,
31*9ef1f84bSDavid du Colombier 	UDP		= 17,
32*9ef1f84bSDavid du Colombier 	ISO_TP4		= 29,
33*9ef1f84bSDavid du Colombier 	RH		= 43,
34*9ef1f84bSDavid du Colombier 	FH		= 44,
35*9ef1f84bSDavid du Colombier 	IDRP		= 45,
36*9ef1f84bSDavid du Colombier 	RSVP		= 46,
37*9ef1f84bSDavid du Colombier 	AH		= 51,
38*9ef1f84bSDavid du Colombier 	ESP		= 52,
39*9ef1f84bSDavid du Colombier 	ICMPv6		= 58,
40*9ef1f84bSDavid du Colombier 	NNH		= 59,
41*9ef1f84bSDavid du Colombier 	DOH		= 60,
42*9ef1f84bSDavid du Colombier 	ISO_IP		= 80,
43*9ef1f84bSDavid du Colombier 	IGRP		= 88,
44*9ef1f84bSDavid du Colombier 	OSPF		= 89,
45*9ef1f84bSDavid du Colombier 
46*9ef1f84bSDavid du Colombier 	Maxhdrtype	= 256,
47*9ef1f84bSDavid du Colombier };
48*9ef1f84bSDavid du Colombier 
49*9ef1f84bSDavid du Colombier enum {
50*9ef1f84bSDavid du Colombier 	/* multicast flags and scopes */
51*9ef1f84bSDavid du Colombier 
52*9ef1f84bSDavid du Colombier //	Well_known_flg	= 0,
53*9ef1f84bSDavid du Colombier //	Transient_flg	= 1,
54*9ef1f84bSDavid du Colombier 
55*9ef1f84bSDavid du Colombier //	Interface_local_scop = 1,
56*9ef1f84bSDavid du Colombier 	Link_local_scop	= 2,
57*9ef1f84bSDavid du Colombier //	Site_local_scop	= 5,
58*9ef1f84bSDavid du Colombier //	Org_local_scop	= 8,
59*9ef1f84bSDavid du Colombier 	Global_scop	= 14,
60*9ef1f84bSDavid du Colombier 
61*9ef1f84bSDavid du Colombier 	/* various prefix lengths */
62*9ef1f84bSDavid du Colombier 	SOLN_PREF_LEN	= 13,
63*9ef1f84bSDavid du Colombier 
64*9ef1f84bSDavid du Colombier 	/* icmpv6 unreachability codes */
65*9ef1f84bSDavid du Colombier 	Icmp6_no_route		= 0,
66*9ef1f84bSDavid du Colombier 	Icmp6_ad_prohib		= 1,
67*9ef1f84bSDavid du Colombier 	Icmp6_out_src_scope	= 2,
68*9ef1f84bSDavid du Colombier 	Icmp6_adr_unreach	= 3,
69*9ef1f84bSDavid du Colombier 	Icmp6_port_unreach	= 4,
70*9ef1f84bSDavid du Colombier 	Icmp6_gress_src_fail	= 5,
71*9ef1f84bSDavid du Colombier 	Icmp6_rej_route		= 6,
72*9ef1f84bSDavid du Colombier 	Icmp6_unknown		= 7,  /* our own invention for internal use */
73*9ef1f84bSDavid du Colombier 
74*9ef1f84bSDavid du Colombier 	/* various flags & constants */
75*9ef1f84bSDavid du Colombier 	v6MINTU		= 1280,
76*9ef1f84bSDavid du Colombier 	HOP_LIMIT	= 255,
77*9ef1f84bSDavid du Colombier 	IP6HDR		= 40,		/* sizeof(Ip6hdr) = 8 + 2*16 */
78*9ef1f84bSDavid du Colombier 
79*9ef1f84bSDavid du Colombier 	/* option types */
80*9ef1f84bSDavid du Colombier 
81*9ef1f84bSDavid du Colombier 	/* neighbour discovery */
82*9ef1f84bSDavid du Colombier 	SRC_LLADDR	= 1,
83*9ef1f84bSDavid du Colombier 	TARGET_LLADDR	= 2,
84*9ef1f84bSDavid du Colombier 	PREFIX_INFO	= 3,
85*9ef1f84bSDavid du Colombier 	REDIR_HEADER	= 4,
86*9ef1f84bSDavid du Colombier 	MTU_OPTION	= 5,
87*9ef1f84bSDavid du Colombier 	/* new since rfc2461; see iana.org/assignments/icmpv6-parameters */
88*9ef1f84bSDavid du Colombier 	V6nd_home	= 8,
89*9ef1f84bSDavid du Colombier 	V6nd_srcaddrs	= 9,		/* rfc3122 */
90*9ef1f84bSDavid du Colombier 	V6nd_ip		= 17,
91*9ef1f84bSDavid du Colombier 	/* /lib/rfc/drafts/draft-jeong-dnsop-ipv6-dns-discovery-12.txt */
92*9ef1f84bSDavid du Colombier 	V6nd_rdns	= 25,
93*9ef1f84bSDavid du Colombier 	/* plan 9 extensions */
94*9ef1f84bSDavid du Colombier 	V6nd_9fs	= 250,
95*9ef1f84bSDavid du Colombier 	V6nd_9auth	= 251,
96*9ef1f84bSDavid du Colombier 
97*9ef1f84bSDavid du Colombier 	SRC_UNSPEC	= 0,
98*9ef1f84bSDavid du Colombier 	SRC_UNI		= 1,
99*9ef1f84bSDavid du Colombier 	TARG_UNI	= 2,
100*9ef1f84bSDavid du Colombier 	TARG_MULTI	= 3,
101*9ef1f84bSDavid du Colombier 
102*9ef1f84bSDavid du Colombier 	Tunitent	= 1,
103*9ef1f84bSDavid du Colombier 	Tuniproxy	= 2,
104*9ef1f84bSDavid du Colombier 	Tunirany	= 3,
105*9ef1f84bSDavid du Colombier 
106*9ef1f84bSDavid du Colombier 	/* Node constants */
107*9ef1f84bSDavid du Colombier 	MAX_MULTICAST_SOLICIT	= 3,
108*9ef1f84bSDavid du Colombier 	RETRANS_TIMER		= 1000,
109*9ef1f84bSDavid du Colombier };
110*9ef1f84bSDavid du Colombier 
111*9ef1f84bSDavid du Colombier typedef struct Ip6hdr	Ip6hdr;
112*9ef1f84bSDavid du Colombier typedef struct Opthdr	Opthdr;
113*9ef1f84bSDavid du Colombier typedef struct Routinghdr Routinghdr;
114*9ef1f84bSDavid du Colombier typedef struct Fraghdr6	Fraghdr6;
115*9ef1f84bSDavid du Colombier 
116*9ef1f84bSDavid du Colombier /* we do this in case there's padding at the end of Ip6hdr */
117*9ef1f84bSDavid du Colombier #define IPV6HDR \
118*9ef1f84bSDavid du Colombier 	uchar	vcf[4];		/* version:4, traffic class:8, flow label:20 */\
119*9ef1f84bSDavid du Colombier 	uchar	ploadlen[2];	/* payload length: packet length - 40 */ \
120*9ef1f84bSDavid du Colombier 	uchar	proto;		/* next header type */ \
121*9ef1f84bSDavid du Colombier 	uchar	ttl;		/* hop limit */ \
122*9ef1f84bSDavid du Colombier 	uchar	src[IPaddrlen]; \
123*9ef1f84bSDavid du Colombier 	uchar	dst[IPaddrlen]
124*9ef1f84bSDavid du Colombier 
125*9ef1f84bSDavid du Colombier struct	Ip6hdr {
126*9ef1f84bSDavid du Colombier 	IPV6HDR;
127*9ef1f84bSDavid du Colombier 	uchar	payload[];
128*9ef1f84bSDavid du Colombier };
129*9ef1f84bSDavid du Colombier 
130*9ef1f84bSDavid du Colombier struct	Opthdr {		/* unused */
131*9ef1f84bSDavid du Colombier 	uchar	nexthdr;
132*9ef1f84bSDavid du Colombier 	uchar	len;
133*9ef1f84bSDavid du Colombier };
134*9ef1f84bSDavid du Colombier 
135*9ef1f84bSDavid du Colombier /*
136*9ef1f84bSDavid du Colombier  * Beware routing header type 0 (loose source routing); see
137*9ef1f84bSDavid du Colombier  * http://www.secdev.org/conf/IPv6_RH_security-csw07.pdf.
138*9ef1f84bSDavid du Colombier  * Type 1 is unused.  Type 2 is for MIPv6 (mobile IPv6) filtering
139*9ef1f84bSDavid du Colombier  * against type 0 header.
140*9ef1f84bSDavid du Colombier  */
141*9ef1f84bSDavid du Colombier struct	Routinghdr {		/* unused */
142*9ef1f84bSDavid du Colombier 	uchar	nexthdr;
143*9ef1f84bSDavid du Colombier 	uchar	len;
144*9ef1f84bSDavid du Colombier 	uchar	rtetype;
145*9ef1f84bSDavid du Colombier 	uchar	segrem;
146*9ef1f84bSDavid du Colombier };
147*9ef1f84bSDavid du Colombier 
148*9ef1f84bSDavid du Colombier struct	Fraghdr6 {
149*9ef1f84bSDavid du Colombier 	uchar	nexthdr;
150*9ef1f84bSDavid du Colombier 	uchar	res;
151*9ef1f84bSDavid du Colombier 	uchar	offsetRM[2];	/* Offset, Res, M flag */
152*9ef1f84bSDavid du Colombier 	uchar	id[4];
153*9ef1f84bSDavid du Colombier };
154*9ef1f84bSDavid du Colombier 
155*9ef1f84bSDavid du Colombier extern uchar v6allnodesN[IPaddrlen];
156*9ef1f84bSDavid du Colombier extern uchar v6allnodesL[IPaddrlen];
157*9ef1f84bSDavid du Colombier extern uchar v6allroutersN[IPaddrlen];
158*9ef1f84bSDavid du Colombier extern uchar v6allroutersL[IPaddrlen];
159*9ef1f84bSDavid du Colombier extern uchar v6allnodesNmask[IPaddrlen];
160*9ef1f84bSDavid du Colombier extern uchar v6allnodesLmask[IPaddrlen];
161*9ef1f84bSDavid du Colombier extern uchar v6solicitednode[IPaddrlen];
162*9ef1f84bSDavid du Colombier extern uchar v6solicitednodemask[IPaddrlen];
163*9ef1f84bSDavid du Colombier extern uchar v6Unspecified[IPaddrlen];
164*9ef1f84bSDavid du Colombier extern uchar v6loopback[IPaddrlen];
165*9ef1f84bSDavid du Colombier extern uchar v6loopbackmask[IPaddrlen];
166*9ef1f84bSDavid du Colombier extern uchar v6linklocal[IPaddrlen];
167*9ef1f84bSDavid du Colombier extern uchar v6linklocalmask[IPaddrlen];
168*9ef1f84bSDavid du Colombier extern uchar v6multicast[IPaddrlen];
169*9ef1f84bSDavid du Colombier extern uchar v6multicastmask[IPaddrlen];
170*9ef1f84bSDavid du Colombier 
171*9ef1f84bSDavid du Colombier extern int v6llpreflen;
172*9ef1f84bSDavid du Colombier extern int v6mcpreflen;
173*9ef1f84bSDavid du Colombier extern int v6snpreflen;
174*9ef1f84bSDavid du Colombier extern int v6aNpreflen;
175*9ef1f84bSDavid du Colombier extern int v6aLpreflen;
176*9ef1f84bSDavid du Colombier 
177*9ef1f84bSDavid du Colombier extern int ReTransTimer;
178*9ef1f84bSDavid du Colombier 
179*9ef1f84bSDavid du Colombier void ipv62smcast(uchar *, uchar *);
180*9ef1f84bSDavid du Colombier void icmpns(Fs *f, uchar* src, int suni, uchar* targ, int tuni, uchar* mac);
181*9ef1f84bSDavid du Colombier void icmpna(Fs *f, uchar* src, uchar* dst, uchar* targ, uchar* mac, uchar flags);
182*9ef1f84bSDavid du Colombier void icmpttlexceeded6(Fs *f, Ipifc *ifc, Block *bp);
183*9ef1f84bSDavid du Colombier void icmppkttoobig6(Fs *f, Ipifc *ifc, Block *bp);
184*9ef1f84bSDavid du Colombier void icmphostunr(Fs *f, Ipifc *ifc, Block *bp, int code, int free);
185