ip6_input.c (120649) | ip6_input.c (120856) |
---|---|
1/* $FreeBSD: head/sys/netinet6/ip6_input.c 120649 2003-10-01 21:24:28Z ume $ */ | 1/* $FreeBSD: head/sys/netinet6/ip6_input.c 120856 2003-10-06 14:02:09Z ume $ */ |
2/* $KAME: ip6_input.c,v 1.259 2002/01/21 04:58:09 jinmei Exp $ */ 3 4/* 5 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions --- 889 unchanged lines hidden (view full) --- 899 } 900#endif 901 off += hbhlen; 902 hbhlen -= sizeof(struct ip6_hbh); 903 opt = (u_int8_t *)hbh + sizeof(struct ip6_hbh); 904 905 if (ip6_process_hopopts(m, (u_int8_t *)hbh + sizeof(struct ip6_hbh), 906 hbhlen, rtalertp, plenp) < 0) | 2/* $KAME: ip6_input.c,v 1.259 2002/01/21 04:58:09 jinmei Exp $ */ 3 4/* 5 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions --- 889 unchanged lines hidden (view full) --- 899 } 900#endif 901 off += hbhlen; 902 hbhlen -= sizeof(struct ip6_hbh); 903 opt = (u_int8_t *)hbh + sizeof(struct ip6_hbh); 904 905 if (ip6_process_hopopts(m, (u_int8_t *)hbh + sizeof(struct ip6_hbh), 906 hbhlen, rtalertp, plenp) < 0) |
907 return(-1); | 907 return (-1); |
908 909 *offp = off; 910 *mp = m; | 908 909 *offp = off; 910 *mp = m; |
911 return(0); | 911 return (0); |
912} 913 914/* 915 * Search header for all Hop-by-hop options and process each option. 916 * This function is separate from ip6_hopopts_input() in order to 917 * handle a case where the sending node itself process its hop-by-hop 918 * options header. In such a case, the function is called from ip6_output(). 919 * --- 34 unchanged lines hidden (view full) --- 954 ip6stat.ip6s_toosmall++; 955 goto bad; 956 } 957 if (*(opt + 1) != IP6OPT_RTALERT_LEN - 2) { 958 /* XXX stat */ 959 icmp6_error(m, ICMP6_PARAM_PROB, 960 ICMP6_PARAMPROB_HEADER, 961 erroff + opt + 1 - opthead); | 912} 913 914/* 915 * Search header for all Hop-by-hop options and process each option. 916 * This function is separate from ip6_hopopts_input() in order to 917 * handle a case where the sending node itself process its hop-by-hop 918 * options header. In such a case, the function is called from ip6_output(). 919 * --- 34 unchanged lines hidden (view full) --- 954 ip6stat.ip6s_toosmall++; 955 goto bad; 956 } 957 if (*(opt + 1) != IP6OPT_RTALERT_LEN - 2) { 958 /* XXX stat */ 959 icmp6_error(m, ICMP6_PARAM_PROB, 960 ICMP6_PARAMPROB_HEADER, 961 erroff + opt + 1 - opthead); |
962 return(-1); | 962 return (-1); |
963 } 964 optlen = IP6OPT_RTALERT_LEN; 965 bcopy((caddr_t)(opt + 2), (caddr_t)&rtalert_val, 2); 966 *rtalertp = ntohs(rtalert_val); 967 break; 968 case IP6OPT_JUMBO: 969 /* XXX may need check for alignment */ 970 if (hbhlen < IP6OPT_JUMBO_LEN) { 971 ip6stat.ip6s_toosmall++; 972 goto bad; 973 } 974 if (*(opt + 1) != IP6OPT_JUMBO_LEN - 2) { 975 /* XXX stat */ 976 icmp6_error(m, ICMP6_PARAM_PROB, 977 ICMP6_PARAMPROB_HEADER, 978 erroff + opt + 1 - opthead); | 963 } 964 optlen = IP6OPT_RTALERT_LEN; 965 bcopy((caddr_t)(opt + 2), (caddr_t)&rtalert_val, 2); 966 *rtalertp = ntohs(rtalert_val); 967 break; 968 case IP6OPT_JUMBO: 969 /* XXX may need check for alignment */ 970 if (hbhlen < IP6OPT_JUMBO_LEN) { 971 ip6stat.ip6s_toosmall++; 972 goto bad; 973 } 974 if (*(opt + 1) != IP6OPT_JUMBO_LEN - 2) { 975 /* XXX stat */ 976 icmp6_error(m, ICMP6_PARAM_PROB, 977 ICMP6_PARAMPROB_HEADER, 978 erroff + opt + 1 - opthead); |
979 return(-1); | 979 return (-1); |
980 } 981 optlen = IP6OPT_JUMBO_LEN; 982 983 /* 984 * IPv6 packets that have non 0 payload length 985 * must not contain a jumbo payload option. 986 */ 987 ip6 = mtod(m, struct ip6_hdr *); 988 if (ip6->ip6_plen) { 989 ip6stat.ip6s_badoptions++; 990 icmp6_error(m, ICMP6_PARAM_PROB, 991 ICMP6_PARAMPROB_HEADER, 992 erroff + opt - opthead); | 980 } 981 optlen = IP6OPT_JUMBO_LEN; 982 983 /* 984 * IPv6 packets that have non 0 payload length 985 * must not contain a jumbo payload option. 986 */ 987 ip6 = mtod(m, struct ip6_hdr *); 988 if (ip6->ip6_plen) { 989 ip6stat.ip6s_badoptions++; 990 icmp6_error(m, ICMP6_PARAM_PROB, 991 ICMP6_PARAMPROB_HEADER, 992 erroff + opt - opthead); |
993 return(-1); | 993 return (-1); |
994 } 995 996 /* 997 * We may see jumbolen in unaligned location, so 998 * we'd need to perform bcopy(). 999 */ 1000 bcopy(opt + 2, &jumboplen, sizeof(jumboplen)); 1001 jumboplen = (u_int32_t)htonl(jumboplen); --- 7 unchanged lines hidden (view full) --- 1009 * multiple options does not make sense, however, 1010 * there's no explicit mention in specification. 1011 */ 1012 if (*plenp != 0) { 1013 ip6stat.ip6s_badoptions++; 1014 icmp6_error(m, ICMP6_PARAM_PROB, 1015 ICMP6_PARAMPROB_HEADER, 1016 erroff + opt + 2 - opthead); | 994 } 995 996 /* 997 * We may see jumbolen in unaligned location, so 998 * we'd need to perform bcopy(). 999 */ 1000 bcopy(opt + 2, &jumboplen, sizeof(jumboplen)); 1001 jumboplen = (u_int32_t)htonl(jumboplen); --- 7 unchanged lines hidden (view full) --- 1009 * multiple options does not make sense, however, 1010 * there's no explicit mention in specification. 1011 */ 1012 if (*plenp != 0) { 1013 ip6stat.ip6s_badoptions++; 1014 icmp6_error(m, ICMP6_PARAM_PROB, 1015 ICMP6_PARAMPROB_HEADER, 1016 erroff + opt + 2 - opthead); |
1017 return(-1); | 1017 return (-1); |
1018 } 1019#endif 1020 1021 /* 1022 * jumbo payload length must be larger than 65535. 1023 */ 1024 if (jumboplen <= IPV6_MAXPACKET) { 1025 ip6stat.ip6s_badoptions++; 1026 icmp6_error(m, ICMP6_PARAM_PROB, 1027 ICMP6_PARAMPROB_HEADER, 1028 erroff + opt + 2 - opthead); | 1018 } 1019#endif 1020 1021 /* 1022 * jumbo payload length must be larger than 65535. 1023 */ 1024 if (jumboplen <= IPV6_MAXPACKET) { 1025 ip6stat.ip6s_badoptions++; 1026 icmp6_error(m, ICMP6_PARAM_PROB, 1027 ICMP6_PARAMPROB_HEADER, 1028 erroff + opt + 2 - opthead); |
1029 return(-1); | 1029 return (-1); |
1030 } 1031 *plenp = jumboplen; 1032 1033 break; 1034 default: /* unknown option */ 1035 if (hbhlen < IP6OPT_MINLEN) { 1036 ip6stat.ip6s_toosmall++; 1037 goto bad; 1038 } 1039 optlen = ip6_unknown_opt(opt, m, 1040 erroff + opt - opthead); 1041 if (optlen == -1) | 1030 } 1031 *plenp = jumboplen; 1032 1033 break; 1034 default: /* unknown option */ 1035 if (hbhlen < IP6OPT_MINLEN) { 1036 ip6stat.ip6s_toosmall++; 1037 goto bad; 1038 } 1039 optlen = ip6_unknown_opt(opt, m, 1040 erroff + opt - opthead); 1041 if (optlen == -1) |
1042 return(-1); | 1042 return (-1); |
1043 optlen += 2; 1044 break; 1045 } 1046 } 1047 | 1043 optlen += 2; 1044 break; 1045 } 1046 } 1047 |
1048 return(0); | 1048 return (0); |
1049 1050 bad: 1051 m_freem(m); | 1049 1050 bad: 1051 m_freem(m); |
1052 return(-1); | 1052 return (-1); |
1053} 1054 1055/* 1056 * Unknown option processing. 1057 * The third argument `off' is the offset from the IPv6 header to the option, 1058 * which is necessary if the IPv6 header the and option header and IPv6 header 1059 * is not continuous in order to return an ICMPv6 error. 1060 */ 1061int 1062ip6_unknown_opt(optp, m, off) 1063 u_int8_t *optp; 1064 struct mbuf *m; 1065 int off; 1066{ 1067 struct ip6_hdr *ip6; 1068 1069 switch (IP6OPT_TYPE(*optp)) { 1070 case IP6OPT_TYPE_SKIP: /* ignore the option */ | 1053} 1054 1055/* 1056 * Unknown option processing. 1057 * The third argument `off' is the offset from the IPv6 header to the option, 1058 * which is necessary if the IPv6 header the and option header and IPv6 header 1059 * is not continuous in order to return an ICMPv6 error. 1060 */ 1061int 1062ip6_unknown_opt(optp, m, off) 1063 u_int8_t *optp; 1064 struct mbuf *m; 1065 int off; 1066{ 1067 struct ip6_hdr *ip6; 1068 1069 switch (IP6OPT_TYPE(*optp)) { 1070 case IP6OPT_TYPE_SKIP: /* ignore the option */ |
1071 return((int)*(optp + 1)); | 1071 return ((int)*(optp + 1)); |
1072 case IP6OPT_TYPE_DISCARD: /* silently discard */ 1073 m_freem(m); | 1072 case IP6OPT_TYPE_DISCARD: /* silently discard */ 1073 m_freem(m); |
1074 return(-1); | 1074 return (-1); |
1075 case IP6OPT_TYPE_FORCEICMP: /* send ICMP even if multicasted */ 1076 ip6stat.ip6s_badoptions++; 1077 icmp6_error(m, ICMP6_PARAM_PROB, ICMP6_PARAMPROB_OPTION, off); | 1075 case IP6OPT_TYPE_FORCEICMP: /* send ICMP even if multicasted */ 1076 ip6stat.ip6s_badoptions++; 1077 icmp6_error(m, ICMP6_PARAM_PROB, ICMP6_PARAMPROB_OPTION, off); |
1078 return(-1); | 1078 return (-1); |
1079 case IP6OPT_TYPE_ICMP: /* send ICMP if not multicasted */ 1080 ip6stat.ip6s_badoptions++; 1081 ip6 = mtod(m, struct ip6_hdr *); 1082 if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst) || 1083 (m->m_flags & (M_BCAST|M_MCAST))) 1084 m_freem(m); 1085 else 1086 icmp6_error(m, ICMP6_PARAM_PROB, 1087 ICMP6_PARAMPROB_OPTION, off); | 1079 case IP6OPT_TYPE_ICMP: /* send ICMP if not multicasted */ 1080 ip6stat.ip6s_badoptions++; 1081 ip6 = mtod(m, struct ip6_hdr *); 1082 if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst) || 1083 (m->m_flags & (M_BCAST|M_MCAST))) 1084 m_freem(m); 1085 else 1086 icmp6_error(m, ICMP6_PARAM_PROB, 1087 ICMP6_PARAMPROB_OPTION, off); |
1088 return(-1); | 1088 return (-1); |
1089 } 1090 1091 m_freem(m); /* XXX: NOTREACHED */ | 1089 } 1090 1091 m_freem(m); /* XXX: NOTREACHED */ |
1092 return(-1); | 1092 return (-1); |
1093} 1094 1095/* 1096 * Create the "control" list for this pcb. 1097 * The function will not modify mbuf chain at all. 1098 * 1099 * with KAME mbuf chain restriction: 1100 * The routine will be called from upper layer handlers like tcp6_input(). --- 339 unchanged lines hidden (view full) --- 1440char * 1441ip6_get_prevhdr(m, off) 1442 struct mbuf *m; 1443 int off; 1444{ 1445 struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *); 1446 1447 if (off == sizeof(struct ip6_hdr)) | 1093} 1094 1095/* 1096 * Create the "control" list for this pcb. 1097 * The function will not modify mbuf chain at all. 1098 * 1099 * with KAME mbuf chain restriction: 1100 * The routine will be called from upper layer handlers like tcp6_input(). --- 339 unchanged lines hidden (view full) --- 1440char * 1441ip6_get_prevhdr(m, off) 1442 struct mbuf *m; 1443 int off; 1444{ 1445 struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *); 1446 1447 if (off == sizeof(struct ip6_hdr)) |
1448 return(&ip6->ip6_nxt); | 1448 return (&ip6->ip6_nxt); |
1449 else { 1450 int len, nxt; 1451 struct ip6_ext *ip6e = NULL; 1452 1453 nxt = ip6->ip6_nxt; 1454 len = sizeof(struct ip6_hdr); 1455 while (len < off) { 1456 ip6e = (struct ip6_ext *)(mtod(m, caddr_t) + len); --- 7 unchanged lines hidden (view full) --- 1464 break; 1465 default: 1466 len += (ip6e->ip6e_len + 1) << 3; 1467 break; 1468 } 1469 nxt = ip6e->ip6e_nxt; 1470 } 1471 if (ip6e) | 1449 else { 1450 int len, nxt; 1451 struct ip6_ext *ip6e = NULL; 1452 1453 nxt = ip6->ip6_nxt; 1454 len = sizeof(struct ip6_hdr); 1455 while (len < off) { 1456 ip6e = (struct ip6_ext *)(mtod(m, caddr_t) + len); --- 7 unchanged lines hidden (view full) --- 1464 break; 1465 default: 1466 len += (ip6e->ip6e_len + 1) << 3; 1467 break; 1468 } 1469 nxt = ip6e->ip6e_nxt; 1470 } 1471 if (ip6e) |
1472 return(&ip6e->ip6e_nxt); | 1472 return (&ip6e->ip6e_nxt); |
1473 else 1474 return NULL; 1475 } 1476} 1477 1478/* 1479 * get next header offset. m will be retained. 1480 */ --- 152 unchanged lines hidden --- | 1473 else 1474 return NULL; 1475 } 1476} 1477 1478/* 1479 * get next header offset. m will be retained. 1480 */ --- 152 unchanged lines hidden --- |