* Hop-by-Hop options header processing. If a valid jumbo payload option is * included, the real payload length will be stored in plenp. * * rtalertp - XXX: should be stored more smart way */
| 944 | * rtalertp - XXX: should be stored more smart way |
| 945 | */ |
| 946 | static int |
| 947 | ip6_hopopts_input(u_int32_t *plenp, u_int32_t *rtalertp, |
| 948 | struct mbuf **mp, int *offp) |
| 949 | { |
| 950 | struct mbuf *m = *mp; |
| 951 | int off = *offp, hbhlen; |
| 952 | struct ip6_hbh *hbh; |
| 953 | |
| 954 | /* validation of the length of the header */ |
| 955 | if (m->m_len < off + sizeof(*hbh)) { |
| 956 | m = m_pullup(m, off + sizeof(*hbh)); |
| 957 | if (m == NULL) { |
| 958 | IP6STAT_INC(ip6s_exthdrtoolong); |
| 959 | *mp = NULL; |
| 960 | return (-1); |
| 961 | } |
| 962 | } |
| 963 | hbh = (struct ip6_hbh *)(mtod(m, caddr_t) + off); |
| 964 | hbhlen = (hbh->ip6h_len + 1) << 3; |
| 965 | |
| 966 | if (m->m_len < off + hbhlen) { |
| 967 | m = m_pullup(m, off + hbhlen); |
| 968 | if (m == NULL) { |
| 969 | IP6STAT_INC(ip6s_exthdrtoolong); |
| 970 | *mp = NULL; |
| 971 | return (-1); |
| 972 | } |
| 973 | } |
| 974 | hbh = (struct ip6_hbh *)(mtod(m, caddr_t) + off); |
| 975 | off += hbhlen; |
| 976 | hbhlen -= sizeof(struct ip6_hbh); |
| 977 | if (ip6_process_hopopts(m, (u_int8_t *)hbh + sizeof(struct ip6_hbh), |
| 978 | hbhlen, rtalertp, plenp) < 0) { |
| 979 | *mp = NULL; |
| 980 | return (-1); |
| 981 | } |
| 982 | |
| 983 | *offp = off; |
| 984 | *mp = m; |
| 985 | return (0); |
| 986 | } |
| 987 | |
| 988 | /* |
| 989 | * Search header for all Hop-by-hop options and process each option. |
no test coverage detected