* Process a Node Information Query packet, based on * draft-ietf-ipngwg-icmp-name-lookups-07. * * Spec incompatibilities: * - IPv6 Subject address handling * - IPv4 Subject address handling support missing * - Proxy reply (answer even if it's not for me) * - joins NI group address at in6_ifattach() time only, does not cope * with hostname changes by sethostname(3) */
| 1168 | * with hostname changes by sethostname(3) |
| 1169 | */ |
| 1170 | static struct mbuf * |
| 1171 | ni6_input(struct mbuf *m, int off, struct prison *pr) |
| 1172 | { |
| 1173 | struct icmp6_nodeinfo *ni6, *nni6; |
| 1174 | struct mbuf *n = NULL; |
| 1175 | u_int16_t qtype; |
| 1176 | int subjlen; |
| 1177 | int replylen = sizeof(struct ip6_hdr) + sizeof(struct icmp6_nodeinfo); |
| 1178 | struct ni_reply_fqdn *fqdn; |
| 1179 | int addrs; /* for NI_QTYPE_NODEADDR */ |
| 1180 | struct ifnet *ifp = NULL; /* for NI_QTYPE_NODEADDR */ |
| 1181 | struct in6_addr in6_subj; /* subject address */ |
| 1182 | struct ip6_hdr *ip6; |
| 1183 | int oldfqdn = 0; /* if 1, return pascal string (03 draft) */ |
| 1184 | char *subj = NULL; |
| 1185 | struct in6_ifaddr *ia6 = NULL; |
| 1186 | |
| 1187 | ip6 = mtod(m, struct ip6_hdr *); |
| 1188 | ni6 = (struct icmp6_nodeinfo *)(mtod(m, caddr_t) + off); |
| 1189 | |
| 1190 | /* |
| 1191 | * Validate IPv6 source address. |
| 1192 | * The default configuration MUST be to refuse answering queries from |
| 1193 | * global-scope addresses according to RFC4602. |
| 1194 | * Notes: |
| 1195 | * - it's not very clear what "refuse" means; this implementation |
| 1196 | * simply drops it. |
| 1197 | * - it's not very easy to identify global-scope (unicast) addresses |
| 1198 | * since there are many prefixes for them. It should be safer |
| 1199 | * and in practice sufficient to check "all" but loopback and |
| 1200 | * link-local (note that site-local unicast was deprecated and |
| 1201 | * ULA is defined as global scope-wise) |
| 1202 | */ |
| 1203 | if ((V_icmp6_nodeinfo & ICMP6_NODEINFO_GLOBALOK) == 0 && |
| 1204 | !IN6_IS_ADDR_LOOPBACK(&ip6->ip6_src) && |
| 1205 | !IN6_IS_ADDR_LINKLOCAL(&ip6->ip6_src)) |
| 1206 | goto bad; |
| 1207 | |
| 1208 | /* |
| 1209 | * Validate IPv6 destination address. |
| 1210 | * |
| 1211 | * The Responder must discard the Query without further processing |
| 1212 | * unless it is one of the Responder's unicast or anycast addresses, or |
| 1213 | * a link-local scope multicast address which the Responder has joined. |
| 1214 | * [RFC4602, Section 5.] |
| 1215 | */ |
| 1216 | if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst)) { |
| 1217 | if (!IN6_IS_ADDR_MC_LINKLOCAL(&ip6->ip6_dst)) |
| 1218 | goto bad; |
| 1219 | /* else it's a link-local multicast, fine */ |
| 1220 | } else { /* unicast or anycast */ |
| 1221 | ia6 = in6ifa_ifwithaddr(&ip6->ip6_dst, 0 /* XXX */); |
| 1222 | if (ia6 == NULL) |
| 1223 | goto bad; /* XXX impossible */ |
| 1224 | |
| 1225 | if ((ia6->ia6_flags & IN6_IFF_TEMPORARY) && |
| 1226 | !(V_icmp6_nodeinfo & ICMP6_NODEINFO_TMPADDROK)) { |
| 1227 | ifa_free(&ia6->ia_ifa); |
no test coverage detected