* Get pointer to the previous header followed by the header * currently processed. */
| 1588 | * currently processed. |
| 1589 | */ |
| 1590 | int |
| 1591 | ip6_get_prevhdr(const struct mbuf *m, int off) |
| 1592 | { |
| 1593 | struct ip6_ext ip6e; |
| 1594 | struct ip6_hdr *ip6; |
| 1595 | int len, nlen, nxt; |
| 1596 | |
| 1597 | if (off == sizeof(struct ip6_hdr)) |
| 1598 | return (offsetof(struct ip6_hdr, ip6_nxt)); |
| 1599 | if (off < sizeof(struct ip6_hdr)) |
| 1600 | panic("%s: off < sizeof(struct ip6_hdr)", __func__); |
| 1601 | |
| 1602 | ip6 = mtod(m, struct ip6_hdr *); |
| 1603 | nxt = ip6->ip6_nxt; |
| 1604 | len = sizeof(struct ip6_hdr); |
| 1605 | nlen = 0; |
| 1606 | while (len < off) { |
| 1607 | m_copydata(m, len, sizeof(ip6e), (caddr_t)&ip6e); |
| 1608 | switch (nxt) { |
| 1609 | case IPPROTO_FRAGMENT: |
| 1610 | nlen = sizeof(struct ip6_frag); |
| 1611 | break; |
| 1612 | case IPPROTO_AH: |
| 1613 | nlen = (ip6e.ip6e_len + 2) << 2; |
| 1614 | break; |
| 1615 | default: |
| 1616 | nlen = (ip6e.ip6e_len + 1) << 3; |
| 1617 | } |
| 1618 | len += nlen; |
| 1619 | nxt = ip6e.ip6e_nxt; |
| 1620 | } |
| 1621 | return (len - nlen); |
| 1622 | } |
| 1623 | |
| 1624 | /* |
| 1625 | * get next header offset. m will be retained. |
no test coverage detected