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