icmp6.c (9307d8bdd4de57183bb421d18d34d21febe98656) icmp6.c (1db8d1f8433157f6579fa297b1959d67540782b4)
1/*-
2 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 91 unchanged lines hidden (view full) ---

100
101#include <netinet6/in6_ifattach.h>
102#include <netinet6/in6_pcb.h>
103#include <netinet6/ip6protosw.h>
104#include <netinet6/ip6_var.h>
105#include <netinet6/scope6_var.h>
106#include <netinet6/mld6_var.h>
107#include <netinet6/nd6.h>
1/*-
2 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 91 unchanged lines hidden (view full) ---

100
101#include <netinet6/in6_ifattach.h>
102#include <netinet6/in6_pcb.h>
103#include <netinet6/ip6protosw.h>
104#include <netinet6/ip6_var.h>
105#include <netinet6/scope6_var.h>
106#include <netinet6/mld6_var.h>
107#include <netinet6/nd6.h>
108#include <netinet6/send.h>
108
109#ifdef IPSEC
110#include <netipsec/ipsec.h>
111#include <netipsec/key.h>
112#endif
113
114extern struct domain inet6domain;
115

--- 293 unchanged lines hidden (view full) ---

409 struct mbuf *m = *mp, *n;
410 struct ifnet *ifp;
411 struct ip6_hdr *ip6, *nip6;
412 struct icmp6_hdr *icmp6, *nicmp6;
413 int off = *offp;
414 int icmp6len = m->m_pkthdr.len - *offp;
415 int code, sum, noff;
416 char ip6bufs[INET6_ADDRSTRLEN], ip6bufd[INET6_ADDRSTRLEN];
109
110#ifdef IPSEC
111#include <netipsec/ipsec.h>
112#include <netipsec/key.h>
113#endif
114
115extern struct domain inet6domain;
116

--- 293 unchanged lines hidden (view full) ---

410 struct mbuf *m = *mp, *n;
411 struct ifnet *ifp;
412 struct ip6_hdr *ip6, *nip6;
413 struct icmp6_hdr *icmp6, *nicmp6;
414 int off = *offp;
415 int icmp6len = m->m_pkthdr.len - *offp;
416 int code, sum, noff;
417 char ip6bufs[INET6_ADDRSTRLEN], ip6bufd[INET6_ADDRSTRLEN];
418 int ip6len, error;
417
418 ifp = m->m_pkthdr.rcvif;
419
420#ifndef PULLDOWN_TEST
421 IP6_EXTHDR_CHECK(m, off, sizeof(struct icmp6_hdr), IPPROTO_DONE);
422 /* m might change if M_LOOP. So, call mtod after this */
423#endif
424
425 /*
426 * Locate icmp6 structure in mbuf, and check
427 * that not corrupted and of at least minimum length
428 */
429
430 ip6 = mtod(m, struct ip6_hdr *);
419
420 ifp = m->m_pkthdr.rcvif;
421
422#ifndef PULLDOWN_TEST
423 IP6_EXTHDR_CHECK(m, off, sizeof(struct icmp6_hdr), IPPROTO_DONE);
424 /* m might change if M_LOOP. So, call mtod after this */
425#endif
426
427 /*
428 * Locate icmp6 structure in mbuf, and check
429 * that not corrupted and of at least minimum length
430 */
431
432 ip6 = mtod(m, struct ip6_hdr *);
433 ip6len = sizeof(struct ip6_hdr) + ntohs(ip6->ip6_plen);
431 if (icmp6len < sizeof(struct icmp6_hdr)) {
432 ICMP6STAT_INC(icp6s_tooshort);
433 goto freeit;
434 }
435
436 /*
437 * Check multicast group membership.
438 * Note: SSM filters are not applied for ICMPv6 traffic.

--- 322 unchanged lines hidden (view full) ---

761 case ND_ROUTER_SOLICIT:
762 icmp6_ifstat_inc(ifp, ifs6_in_routersolicit);
763 if (code != 0)
764 goto badcode;
765 if (icmp6len < sizeof(struct nd_router_solicit))
766 goto badlen;
767 if ((n = m_copym(m, 0, M_COPYALL, M_DONTWAIT)) == NULL) {
768 /* give up local */
434 if (icmp6len < sizeof(struct icmp6_hdr)) {
435 ICMP6STAT_INC(icp6s_tooshort);
436 goto freeit;
437 }
438
439 /*
440 * Check multicast group membership.
441 * Note: SSM filters are not applied for ICMPv6 traffic.

--- 322 unchanged lines hidden (view full) ---

764 case ND_ROUTER_SOLICIT:
765 icmp6_ifstat_inc(ifp, ifs6_in_routersolicit);
766 if (code != 0)
767 goto badcode;
768 if (icmp6len < sizeof(struct nd_router_solicit))
769 goto badlen;
770 if ((n = m_copym(m, 0, M_COPYALL, M_DONTWAIT)) == NULL) {
771 /* give up local */
769 nd6_rs_input(m, off, icmp6len);
772
773 /* Send incoming SeND packet to user space. */
774 if (send_sendso_input_hook != NULL) {
775 IP6_EXTHDR_CHECK(m, off,
776 icmp6len, IPPROTO_DONE);
777 error = send_sendso_input_hook(m, ifp,
778 SND_IN, ip6len);
779 /* -1 == no app on SEND socket */
780 if (error == 0)
781 return (IPPROTO_DONE);
782 nd6_rs_input(m, off, icmp6len);
783 } else
784 nd6_rs_input(m, off, icmp6len);
770 m = NULL;
771 goto freeit;
772 }
785 m = NULL;
786 goto freeit;
787 }
773 nd6_rs_input(n, off, icmp6len);
788 if (send_sendso_input_hook != NULL) {
789 IP6_EXTHDR_CHECK(m, off,
790 icmp6len, IPPROTO_DONE);
791 error = send_sendso_input_hook(n, ifp,
792 SND_IN, ip6len);
793 if (error == 0) {
794 m_freem(n);
795 return (IPPROTO_DONE);
796 }
797 /* -1 == no app on SEND socket */
798 nd6_rs_input(n, off, icmp6len);
799 } else
800 nd6_rs_input(n, off, icmp6len);
774 /* m stays. */
775 break;
776
777 case ND_ROUTER_ADVERT:
778 icmp6_ifstat_inc(ifp, ifs6_in_routeradvert);
779 if (code != 0)
780 goto badcode;
781 if (icmp6len < sizeof(struct nd_router_advert))
782 goto badlen;
783 if ((n = m_copym(m, 0, M_COPYALL, M_DONTWAIT)) == NULL) {
801 /* m stays. */
802 break;
803
804 case ND_ROUTER_ADVERT:
805 icmp6_ifstat_inc(ifp, ifs6_in_routeradvert);
806 if (code != 0)
807 goto badcode;
808 if (icmp6len < sizeof(struct nd_router_advert))
809 goto badlen;
810 if ((n = m_copym(m, 0, M_COPYALL, M_DONTWAIT)) == NULL) {
784 /* give up local */
785 nd6_ra_input(m, off, icmp6len);
811
812 /* Send incoming SeND-protected/ND packet to user space. */
813 if (send_sendso_input_hook != NULL) {
814 error = send_sendso_input_hook(m, ifp,
815 SND_IN, ip6len);
816 if (error == 0)
817 return (IPPROTO_DONE);
818 nd6_ra_input(m, off, icmp6len);
819 } else
820 nd6_ra_input(m, off, icmp6len);
786 m = NULL;
821 m = NULL;
822 m_freem(n);
787 goto freeit;
788 }
823 goto freeit;
824 }
789 nd6_ra_input(n, off, icmp6len);
825 if (send_sendso_input_hook != NULL) {
826 error = send_sendso_input_hook(n, ifp,
827 SND_IN, ip6len);
828 if (error == 0)
829 return (IPPROTO_DONE);
830 nd6_ra_input(n, off, icmp6len);
831 } else
832 nd6_ra_input(n, off, icmp6len);
790 /* m stays. */
791 break;
792
793 case ND_NEIGHBOR_SOLICIT:
794 icmp6_ifstat_inc(ifp, ifs6_in_neighborsolicit);
795 if (code != 0)
796 goto badcode;
797 if (icmp6len < sizeof(struct nd_neighbor_solicit))
798 goto badlen;
799 if ((n = m_copym(m, 0, M_COPYALL, M_DONTWAIT)) == NULL) {
833 /* m stays. */
834 break;
835
836 case ND_NEIGHBOR_SOLICIT:
837 icmp6_ifstat_inc(ifp, ifs6_in_neighborsolicit);
838 if (code != 0)
839 goto badcode;
840 if (icmp6len < sizeof(struct nd_neighbor_solicit))
841 goto badlen;
842 if ((n = m_copym(m, 0, M_COPYALL, M_DONTWAIT)) == NULL) {
800 /* give up local */
801 nd6_ns_input(m, off, icmp6len);
843 if (send_sendso_input_hook != NULL) {
844 error = send_sendso_input_hook(m, ifp,
845 SND_IN, ip6len);
846 if (error == 0)
847 return (IPPROTO_DONE);
848 nd6_ns_input(m, off, icmp6len);
849 } else
850 nd6_ns_input(m, off, icmp6len);
851 m_freem(n);
802 m = NULL;
803 goto freeit;
804 }
852 m = NULL;
853 goto freeit;
854 }
805 nd6_ns_input(n, off, icmp6len);
855 if (send_sendso_input_hook != NULL) {
856 error = send_sendso_input_hook(n, ifp,
857 SND_IN, ip6len);
858 if (error == 0)
859 return (IPPROTO_DONE);
860 nd6_ns_input(n, off, icmp6len);
861 } else
862 nd6_ns_input(n, off, icmp6len);
806 /* m stays. */
807 break;
808
809 case ND_NEIGHBOR_ADVERT:
810 icmp6_ifstat_inc(ifp, ifs6_in_neighboradvert);
811 if (code != 0)
812 goto badcode;
813 if (icmp6len < sizeof(struct nd_neighbor_advert))
814 goto badlen;
815 if ((n = m_copym(m, 0, M_COPYALL, M_DONTWAIT)) == NULL) {
863 /* m stays. */
864 break;
865
866 case ND_NEIGHBOR_ADVERT:
867 icmp6_ifstat_inc(ifp, ifs6_in_neighboradvert);
868 if (code != 0)
869 goto badcode;
870 if (icmp6len < sizeof(struct nd_neighbor_advert))
871 goto badlen;
872 if ((n = m_copym(m, 0, M_COPYALL, M_DONTWAIT)) == NULL) {
816 /* give up local */
817 nd6_na_input(m, off, icmp6len);
873
874 /* Send incoming SeND-protected/ND packet to user space. */
875 if (send_sendso_input_hook != NULL) {
876 error = send_sendso_input_hook(m, ifp,
877 SND_IN, ip6len);
878 if (error == 0)
879 return (IPPROTO_DONE);
880 nd6_na_input(m, off, icmp6len);
881 } else
882 nd6_na_input(m, off, icmp6len);
883 m_freem(n);
818 m = NULL;
819 goto freeit;
820 }
884 m = NULL;
885 goto freeit;
886 }
821 nd6_na_input(n, off, icmp6len);
887 if (send_sendso_input_hook != NULL) {
888 error = send_sendso_input_hook(n, ifp,
889 SND_IN, ip6len);
890 if (error == 0)
891 return (IPPROTO_DONE);
892 nd6_na_input(n, off, icmp6len);
893 } else
894 nd6_na_input(n, off, icmp6len);
822 /* m stays. */
823 break;
824
825 case ND_REDIRECT:
826 icmp6_ifstat_inc(ifp, ifs6_in_redirect);
827 if (code != 0)
828 goto badcode;
829 if (icmp6len < sizeof(struct nd_redirect))
830 goto badlen;
831 if ((n = m_copym(m, 0, M_COPYALL, M_DONTWAIT)) == NULL) {
895 /* m stays. */
896 break;
897
898 case ND_REDIRECT:
899 icmp6_ifstat_inc(ifp, ifs6_in_redirect);
900 if (code != 0)
901 goto badcode;
902 if (icmp6len < sizeof(struct nd_redirect))
903 goto badlen;
904 if ((n = m_copym(m, 0, M_COPYALL, M_DONTWAIT)) == NULL) {
832 /* give up local */
833 icmp6_redirect_input(m, off);
905 if (send_sendso_input_hook != NULL) {
906 error = send_sendso_input_hook(m, ifp,
907 SND_IN, ip6len);
908 if (error == 0)
909 return (IPPROTO_DONE);
910 icmp6_redirect_input(m, off);
911 } else
912 icmp6_redirect_input(m, off);
913 m_freem(n);
834 m = NULL;
835 goto freeit;
836 }
914 m = NULL;
915 goto freeit;
916 }
837 icmp6_redirect_input(n, off);
917 if (send_sendso_input_hook != NULL) {
918 error = send_sendso_input_hook(n, ifp,
919 SND_IN, ip6len);
920 if (error == 0)
921 return (IPPROTO_DONE);
922 icmp6_redirect_input(n, off);
923 } else
924 icmp6_redirect_input(n, off);
838 /* m stays. */
839 break;
840
841 case ICMP6_ROUTER_RENUMBERING:
842 if (code != ICMP6_ROUTER_RENUMBERING_COMMAND &&
843 code != ICMP6_ROUTER_RENUMBERING_RESULT)
844 goto badcode;
845 if (icmp6len < sizeof(struct icmp6_router_renum))

--- 1625 unchanged lines hidden (view full) ---

2471void
2472icmp6_redirect_output(struct mbuf *m0, struct rtentry *rt)
2473{
2474 struct ifnet *ifp; /* my outgoing interface */
2475 struct in6_addr *ifp_ll6;
2476 struct in6_addr *router_ll6;
2477 struct ip6_hdr *sip6; /* m0 as struct ip6_hdr */
2478 struct mbuf *m = NULL; /* newly allocated one */
925 /* m stays. */
926 break;
927
928 case ICMP6_ROUTER_RENUMBERING:
929 if (code != ICMP6_ROUTER_RENUMBERING_COMMAND &&
930 code != ICMP6_ROUTER_RENUMBERING_RESULT)
931 goto badcode;
932 if (icmp6len < sizeof(struct icmp6_router_renum))

--- 1625 unchanged lines hidden (view full) ---

2558void
2559icmp6_redirect_output(struct mbuf *m0, struct rtentry *rt)
2560{
2561 struct ifnet *ifp; /* my outgoing interface */
2562 struct in6_addr *ifp_ll6;
2563 struct in6_addr *router_ll6;
2564 struct ip6_hdr *sip6; /* m0 as struct ip6_hdr */
2565 struct mbuf *m = NULL; /* newly allocated one */
2566 struct m_tag *mtag;
2479 struct ip6_hdr *ip6; /* m as struct ip6_hdr */
2480 struct nd_redirect *nd_rd;
2481 struct llentry *ln = NULL;
2482 size_t maxlen;
2483 u_char *p;
2484 struct ifnet *outif = NULL;
2485 struct sockaddr_in6 src_sa;
2486

--- 243 unchanged lines hidden (view full) ---

2730 in6_clearscope(&nd_rd->nd_rd_dst);
2731
2732 ip6->ip6_plen = htons(m->m_pkthdr.len - sizeof(struct ip6_hdr));
2733
2734 nd_rd->nd_rd_cksum = 0;
2735 nd_rd->nd_rd_cksum = in6_cksum(m, IPPROTO_ICMPV6,
2736 sizeof(*ip6), ntohs(ip6->ip6_plen));
2737
2567 struct ip6_hdr *ip6; /* m as struct ip6_hdr */
2568 struct nd_redirect *nd_rd;
2569 struct llentry *ln = NULL;
2570 size_t maxlen;
2571 u_char *p;
2572 struct ifnet *outif = NULL;
2573 struct sockaddr_in6 src_sa;
2574

--- 243 unchanged lines hidden (view full) ---

2818 in6_clearscope(&nd_rd->nd_rd_dst);
2819
2820 ip6->ip6_plen = htons(m->m_pkthdr.len - sizeof(struct ip6_hdr));
2821
2822 nd_rd->nd_rd_cksum = 0;
2823 nd_rd->nd_rd_cksum = in6_cksum(m, IPPROTO_ICMPV6,
2824 sizeof(*ip6), ntohs(ip6->ip6_plen));
2825
2826 if (send_sendso_input_hook != NULL) {
2827 mtag = m_tag_get(PACKET_TAG_ND_OUTGOING, sizeof(unsigned short),
2828 M_NOWAIT);
2829 if (mtag == NULL)
2830 goto fail;
2831 *(unsigned short *)(mtag + 1) = nd_rd->nd_rd_type;
2832 m_tag_prepend(m, mtag);
2833 }
2834
2738 /* send the packet to outside... */
2739 ip6_output(m, NULL, NULL, 0, NULL, &outif, NULL);
2740 if (outif) {
2741 icmp6_ifstat_inc(outif, ifs6_out_msg);
2742 icmp6_ifstat_inc(outif, ifs6_out_redirect);
2743 }
2744 ICMP6STAT_INC(icp6s_outhist[ND_REDIRECT]);
2745

--- 110 unchanged lines hidden ---
2835 /* send the packet to outside... */
2836 ip6_output(m, NULL, NULL, 0, NULL, &outif, NULL);
2837 if (outif) {
2838 icmp6_ifstat_inc(outif, ifs6_out_msg);
2839 icmp6_ifstat_inc(outif, ifs6_out_redirect);
2840 }
2841 ICMP6STAT_INC(icp6s_outhist[ND_REDIRECT]);
2842

--- 110 unchanged lines hidden ---