* get next header offset. m will be retained. */
| 1625 | * get next header offset. m will be retained. |
| 1626 | */ |
| 1627 | int |
| 1628 | ip6_nexthdr(const struct mbuf *m, int off, int proto, int *nxtp) |
| 1629 | { |
| 1630 | struct ip6_hdr ip6; |
| 1631 | struct ip6_ext ip6e; |
| 1632 | struct ip6_frag fh; |
| 1633 | |
| 1634 | /* just in case */ |
| 1635 | if (m == NULL) |
| 1636 | panic("ip6_nexthdr: m == NULL"); |
| 1637 | if ((m->m_flags & M_PKTHDR) == 0 || m->m_pkthdr.len < off) |
| 1638 | return -1; |
| 1639 | |
| 1640 | switch (proto) { |
| 1641 | case IPPROTO_IPV6: |
| 1642 | if (m->m_pkthdr.len < off + sizeof(ip6)) |
| 1643 | return -1; |
| 1644 | m_copydata(m, off, sizeof(ip6), (caddr_t)&ip6); |
| 1645 | if (nxtp) |
| 1646 | *nxtp = ip6.ip6_nxt; |
| 1647 | off += sizeof(ip6); |
| 1648 | return off; |
| 1649 | |
| 1650 | case IPPROTO_FRAGMENT: |
| 1651 | /* |
| 1652 | * terminate parsing if it is not the first fragment, |
| 1653 | * it does not make sense to parse through it. |
| 1654 | */ |
| 1655 | if (m->m_pkthdr.len < off + sizeof(fh)) |
| 1656 | return -1; |
| 1657 | m_copydata(m, off, sizeof(fh), (caddr_t)&fh); |
| 1658 | /* IP6F_OFF_MASK = 0xfff8(BigEndian), 0xf8ff(LittleEndian) */ |
| 1659 | if (fh.ip6f_offlg & IP6F_OFF_MASK) |
| 1660 | return -1; |
| 1661 | if (nxtp) |
| 1662 | *nxtp = fh.ip6f_nxt; |
| 1663 | off += sizeof(struct ip6_frag); |
| 1664 | return off; |
| 1665 | |
| 1666 | case IPPROTO_AH: |
| 1667 | if (m->m_pkthdr.len < off + sizeof(ip6e)) |
| 1668 | return -1; |
| 1669 | m_copydata(m, off, sizeof(ip6e), (caddr_t)&ip6e); |
| 1670 | if (nxtp) |
| 1671 | *nxtp = ip6e.ip6e_nxt; |
| 1672 | off += (ip6e.ip6e_len + 2) << 2; |
| 1673 | return off; |
| 1674 | |
| 1675 | case IPPROTO_HOPOPTS: |
| 1676 | case IPPROTO_ROUTING: |
| 1677 | case IPPROTO_DSTOPTS: |
| 1678 | if (m->m_pkthdr.len < off + sizeof(ip6e)) |
| 1679 | return -1; |
| 1680 | m_copydata(m, off, sizeof(ip6e), (caddr_t)&ip6e); |
| 1681 | if (nxtp) |
| 1682 | *nxtp = ip6e.ip6e_nxt; |
| 1683 | off += (ip6e.ip6e_len + 1) << 3; |
| 1684 | return off; |
no test coverage detected