* Setup generic address and protocol structures for raw_input routine, then * pass them along with mbuf chain. */
| 280 | * pass them along with mbuf chain. |
| 281 | */ |
| 282 | int |
| 283 | rip_input(struct mbuf **mp, int *offp, int proto) |
| 284 | { |
| 285 | struct ifnet *ifp; |
| 286 | struct mbuf *m = *mp; |
| 287 | struct ip *ip = mtod(m, struct ip *); |
| 288 | struct inpcb *inp, *last; |
| 289 | struct sockaddr_in ripsrc; |
| 290 | int hash; |
| 291 | |
| 292 | NET_EPOCH_ASSERT(); |
| 293 | |
| 294 | *mp = NULL; |
| 295 | |
| 296 | bzero(&ripsrc, sizeof(ripsrc)); |
| 297 | ripsrc.sin_len = sizeof(ripsrc); |
| 298 | ripsrc.sin_family = AF_INET; |
| 299 | ripsrc.sin_addr = ip->ip_src; |
| 300 | last = NULL; |
| 301 | |
| 302 | ifp = m->m_pkthdr.rcvif; |
| 303 | |
| 304 | hash = INP_PCBHASH_RAW(proto, ip->ip_src.s_addr, |
| 305 | ip->ip_dst.s_addr, V_ripcbinfo.ipi_hashmask); |
| 306 | CK_LIST_FOREACH(inp, &V_ripcbinfo.ipi_hashbase[hash], inp_hash) { |
| 307 | if (inp->inp_ip_p != proto) |
| 308 | continue; |
| 309 | #ifdef INET6 |
| 310 | /* XXX inp locking */ |
| 311 | if ((inp->inp_vflag & INP_IPV4) == 0) |
| 312 | continue; |
| 313 | #endif |
| 314 | if (inp->inp_laddr.s_addr != ip->ip_dst.s_addr) |
| 315 | continue; |
| 316 | if (inp->inp_faddr.s_addr != ip->ip_src.s_addr) |
| 317 | continue; |
| 318 | if (last != NULL) { |
| 319 | struct mbuf *n; |
| 320 | |
| 321 | n = m_copym(m, 0, M_COPYALL, M_NOWAIT); |
| 322 | if (n != NULL) |
| 323 | (void) rip_append(last, ip, n, &ripsrc); |
| 324 | /* XXX count dropped packet */ |
| 325 | INP_RUNLOCK(last); |
| 326 | last = NULL; |
| 327 | } |
| 328 | INP_RLOCK(inp); |
| 329 | if (__predict_false(inp->inp_flags2 & INP_FREED)) |
| 330 | goto skip_1; |
| 331 | if (jailed_without_vnet(inp->inp_cred)) { |
| 332 | /* |
| 333 | * XXX: If faddr was bound to multicast group, |
| 334 | * jailed raw socket will drop datagram. |
| 335 | */ |
| 336 | if (prison_check_ip4(inp->inp_cred, &ip->ip_dst) != 0) |
| 337 | goto skip_1; |
| 338 | } |
| 339 | last = inp; |
no test coverage detected