* Return a copy of the data packet that is ready for PIM Register * encapsulation. * XXX: Note that in the returned copy the IP header is a valid one. */
| 2363 | * XXX: Note that in the returned copy the IP header is a valid one. |
| 2364 | */ |
| 2365 | static struct mbuf * |
| 2366 | pim_register_prepare(struct ip *ip, struct mbuf *m) |
| 2367 | { |
| 2368 | struct mbuf *mb_copy = NULL; |
| 2369 | int mtu; |
| 2370 | |
| 2371 | /* Take care of delayed checksums */ |
| 2372 | if (m->m_pkthdr.csum_flags & CSUM_DELAY_DATA) { |
| 2373 | in_delayed_cksum(m); |
| 2374 | m->m_pkthdr.csum_flags &= ~CSUM_DELAY_DATA; |
| 2375 | } |
| 2376 | |
| 2377 | /* |
| 2378 | * Copy the old packet & pullup its IP header into the |
| 2379 | * new mbuf so we can modify it. |
| 2380 | */ |
| 2381 | mb_copy = m_copypacket(m, M_NOWAIT); |
| 2382 | if (mb_copy == NULL) |
| 2383 | return NULL; |
| 2384 | mb_copy = m_pullup(mb_copy, ip->ip_hl << 2); |
| 2385 | if (mb_copy == NULL) |
| 2386 | return NULL; |
| 2387 | |
| 2388 | /* take care of the TTL */ |
| 2389 | ip = mtod(mb_copy, struct ip *); |
| 2390 | --ip->ip_ttl; |
| 2391 | |
| 2392 | /* Compute the MTU after the PIM Register encapsulation */ |
| 2393 | mtu = 0xffff - sizeof(pim_encap_iphdr) - sizeof(pim_encap_pimhdr); |
| 2394 | |
| 2395 | if (ntohs(ip->ip_len) <= mtu) { |
| 2396 | /* Turn the IP header into a valid one */ |
| 2397 | ip->ip_sum = 0; |
| 2398 | ip->ip_sum = in_cksum(mb_copy, ip->ip_hl << 2); |
| 2399 | } else { |
| 2400 | /* Fragment the packet */ |
| 2401 | mb_copy->m_pkthdr.csum_flags |= CSUM_IP; |
| 2402 | if (ip_fragment(ip, &mb_copy, mtu, 0) != 0) { |
| 2403 | m_freem(mb_copy); |
| 2404 | return NULL; |
| 2405 | } |
| 2406 | } |
| 2407 | return mb_copy; |
| 2408 | } |
| 2409 | |
| 2410 | /* |
| 2411 | * Send an upcall with the data packet to the user-level process. |
no test coverage detected