* ipoff and off are measured from the start of the mbuf chain. * h must be at "ipoff" on the mbuf chain. */
| 5377 | * h must be at "ipoff" on the mbuf chain. |
| 5378 | */ |
| 5379 | void * |
| 5380 | pf_pull_hdr(struct mbuf *m, int off, void *p, int len, |
| 5381 | u_short *actionp, u_short *reasonp, sa_family_t af) |
| 5382 | { |
| 5383 | switch (af) { |
| 5384 | #ifdef INET |
| 5385 | case AF_INET: { |
| 5386 | struct ip *h = mtod(m, struct ip *); |
| 5387 | u_int16_t fragoff = (ntohs(h->ip_off) & IP_OFFMASK) << 3; |
| 5388 | |
| 5389 | if (fragoff) { |
| 5390 | if (fragoff >= len) |
| 5391 | ACTION_SET(actionp, PF_PASS); |
| 5392 | else { |
| 5393 | ACTION_SET(actionp, PF_DROP); |
| 5394 | REASON_SET(reasonp, PFRES_FRAG); |
| 5395 | } |
| 5396 | return (NULL); |
| 5397 | } |
| 5398 | if (m->m_pkthdr.len < off + len || |
| 5399 | ntohs(h->ip_len) < off + len) { |
| 5400 | ACTION_SET(actionp, PF_DROP); |
| 5401 | REASON_SET(reasonp, PFRES_SHORT); |
| 5402 | return (NULL); |
| 5403 | } |
| 5404 | break; |
| 5405 | } |
| 5406 | #endif /* INET */ |
| 5407 | #ifdef INET6 |
| 5408 | case AF_INET6: { |
| 5409 | struct ip6_hdr *h = mtod(m, struct ip6_hdr *); |
| 5410 | |
| 5411 | if (m->m_pkthdr.len < off + len || |
| 5412 | (ntohs(h->ip6_plen) + sizeof(struct ip6_hdr)) < |
| 5413 | (unsigned)(off + len)) { |
| 5414 | ACTION_SET(actionp, PF_DROP); |
| 5415 | REASON_SET(reasonp, PFRES_SHORT); |
| 5416 | return (NULL); |
| 5417 | } |
| 5418 | break; |
| 5419 | } |
| 5420 | #endif /* INET6 */ |
| 5421 | } |
| 5422 | m_copydata(m, off, len, p); |
| 5423 | return (p); |
| 5424 | } |
| 5425 | |
| 5426 | int |
| 5427 | pf_routable(struct pf_addr *addr, sa_family_t af, struct pfi_kkif *kif, |
no test coverage detected