* Unknown option processing. * The third argument `off' is the offset from the IPv6 header to the option, * which is necessary if the IPv6 header the and option header and IPv6 header * is not contiguous in order to return an ICMPv6 error. */
| 1129 | * is not contiguous in order to return an ICMPv6 error. |
| 1130 | */ |
| 1131 | int |
| 1132 | ip6_unknown_opt(u_int8_t *optp, struct mbuf *m, int off) |
| 1133 | { |
| 1134 | struct ip6_hdr *ip6; |
| 1135 | |
| 1136 | switch (IP6OPT_TYPE(*optp)) { |
| 1137 | case IP6OPT_TYPE_SKIP: /* ignore the option */ |
| 1138 | return ((int)*(optp + 1)); |
| 1139 | case IP6OPT_TYPE_DISCARD: /* silently discard */ |
| 1140 | m_freem(m); |
| 1141 | return (-1); |
| 1142 | case IP6OPT_TYPE_FORCEICMP: /* send ICMP even if multicasted */ |
| 1143 | IP6STAT_INC(ip6s_badoptions); |
| 1144 | icmp6_error(m, ICMP6_PARAM_PROB, ICMP6_PARAMPROB_OPTION, off); |
| 1145 | return (-1); |
| 1146 | case IP6OPT_TYPE_ICMP: /* send ICMP if not multicasted */ |
| 1147 | IP6STAT_INC(ip6s_badoptions); |
| 1148 | ip6 = mtod(m, struct ip6_hdr *); |
| 1149 | if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst) || |
| 1150 | (m->m_flags & (M_BCAST|M_MCAST))) |
| 1151 | m_freem(m); |
| 1152 | else |
| 1153 | icmp6_error(m, ICMP6_PARAM_PROB, |
| 1154 | ICMP6_PARAMPROB_OPTION, off); |
| 1155 | return (-1); |
| 1156 | } |
| 1157 | |
| 1158 | m_freem(m); /* XXX: NOTREACHED */ |
| 1159 | return (-1); |
| 1160 | } |
| 1161 | |
| 1162 | /* |
| 1163 | * Create the "control" list for this pcb. |
no test coverage detected