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