* Search header for all Hop-by-hop options and process each option. * This function is separate from ip6_hopopts_input() in order to * handle a case where the sending node itself process its hop-by-hop * options header. In such a case, the function is called from ip6_output(). * * The function assumes that hbh header is located right after the IPv6 header * (RFC2460 p7), opthead is pointer i
| 996 | * opthead + hbhlen is located in contiguous memory region. |
| 997 | */ |
| 998 | int |
| 999 | ip6_process_hopopts(struct mbuf *m, u_int8_t *opthead, int hbhlen, |
| 1000 | u_int32_t *rtalertp, u_int32_t *plenp) |
| 1001 | { |
| 1002 | struct ip6_hdr *ip6; |
| 1003 | int optlen = 0; |
| 1004 | u_int8_t *opt = opthead; |
| 1005 | u_int16_t rtalert_val; |
| 1006 | u_int32_t jumboplen; |
| 1007 | const int erroff = sizeof(struct ip6_hdr) + sizeof(struct ip6_hbh); |
| 1008 | |
| 1009 | for (; hbhlen > 0; hbhlen -= optlen, opt += optlen) { |
| 1010 | switch (*opt) { |
| 1011 | case IP6OPT_PAD1: |
| 1012 | optlen = 1; |
| 1013 | break; |
| 1014 | case IP6OPT_PADN: |
| 1015 | if (hbhlen < IP6OPT_MINLEN) { |
| 1016 | IP6STAT_INC(ip6s_toosmall); |
| 1017 | goto bad; |
| 1018 | } |
| 1019 | optlen = *(opt + 1) + 2; |
| 1020 | break; |
| 1021 | case IP6OPT_ROUTER_ALERT: |
| 1022 | /* XXX may need check for alignment */ |
| 1023 | if (hbhlen < IP6OPT_RTALERT_LEN) { |
| 1024 | IP6STAT_INC(ip6s_toosmall); |
| 1025 | goto bad; |
| 1026 | } |
| 1027 | if (*(opt + 1) != IP6OPT_RTALERT_LEN - 2) { |
| 1028 | /* XXX stat */ |
| 1029 | icmp6_error(m, ICMP6_PARAM_PROB, |
| 1030 | ICMP6_PARAMPROB_HEADER, |
| 1031 | erroff + opt + 1 - opthead); |
| 1032 | return (-1); |
| 1033 | } |
| 1034 | optlen = IP6OPT_RTALERT_LEN; |
| 1035 | bcopy((caddr_t)(opt + 2), (caddr_t)&rtalert_val, 2); |
| 1036 | *rtalertp = ntohs(rtalert_val); |
| 1037 | break; |
| 1038 | case IP6OPT_JUMBO: |
| 1039 | /* XXX may need check for alignment */ |
| 1040 | if (hbhlen < IP6OPT_JUMBO_LEN) { |
| 1041 | IP6STAT_INC(ip6s_toosmall); |
| 1042 | goto bad; |
| 1043 | } |
| 1044 | if (*(opt + 1) != IP6OPT_JUMBO_LEN - 2) { |
| 1045 | /* XXX stat */ |
| 1046 | icmp6_error(m, ICMP6_PARAM_PROB, |
| 1047 | ICMP6_PARAMPROB_HEADER, |
| 1048 | erroff + opt + 1 - opthead); |
| 1049 | return (-1); |
| 1050 | } |
| 1051 | optlen = IP6OPT_JUMBO_LEN; |
| 1052 | |
| 1053 | /* |
| 1054 | * IPv6 packets that have non 0 payload length |
| 1055 | * must not contain a jumbo payload option. |
no test coverage detected