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 --- |