Deleted Added
full compact
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 ---