4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
24 * Copyright (c) 2015, Joyent, Inc. All rights reserved.
25 */
26 /*
27 * Copyright 2014 Nexenta Systems, Inc. All rights reserved.
28 */
29
30 #include <sys/cmn_err.h>
31 #include <sys/strsun.h>
32 #include <sys/sdt.h>
33 #include <sys/mac.h>
34 #include <sys/mac_impl.h>
35 #include <sys/mac_client_impl.h>
36 #include <sys/mac_client_priv.h>
37 #include <sys/ethernet.h>
38 #include <sys/vlan.h>
39 #include <sys/dlpi.h>
40 #include <sys/avl.h>
41 #include <inet/ip.h>
42 #include <inet/ip6.h>
43 #include <inet/arp.h>
44 #include <netinet/arp.h>
795 return (0);
796 }
797
798 /*
799 * Locate the start of a DHCPv6 header.
800 * The possible return values and associated meanings are:
801 * 0 - packet is DHCP and has a DHCP header.
802 * EINVAL - packet is not DHCP. the recommended action is to let it pass.
803 * ENOSPC - packet is a initial fragment that is DHCP or is unidentifiable.
804 * the recommended action is to drop it.
805 */
806 static int
807 get_dhcpv6_info(ip6_t *ip6h, uchar_t *end, dhcpv6_message_t **dh6)
808 {
809 uint16_t hdrlen, client, server;
810 boolean_t first_frag = B_FALSE;
811 ip6_frag_t *frag = NULL;
812 uint8_t proto;
813 struct udphdr *udph;
814 uchar_t *dh;
815
816 if (!mac_ip_hdr_length_v6(ip6h, end, &hdrlen, &proto, &frag))
817 return (ENOSPC);
818
819 if (proto != IPPROTO_UDP)
820 return (EINVAL);
821
822 if (frag != NULL) {
823 /*
824 * All non-initial fragments may pass because we cannot
825 * identify their type. It's safe to let them through
826 * because reassembly will fail if we decide to drop the
827 * initial fragment.
828 */
829 if ((ntohs(frag->ip6f_offlg) & ~7) != 0)
830 return (EINVAL);
831 first_frag = B_TRUE;
832 }
833 /* drop packets without a udp header */
834 udph = (struct udphdr *)((uchar_t *)ip6h + hdrlen);
835 if ((uchar_t *)&udph[1] > end)
836 return (ENOSPC);
837
844 /* drop dhcp fragments */
845 if (first_frag)
846 return (ENOSPC);
847
848 dh = (uchar_t *)&udph[1];
849 if (dh + sizeof (dhcpv6_message_t) > end)
850 return (EINVAL);
851
852 *dh6 = (dhcpv6_message_t *)dh;
853 return (0);
854 }
855
856 static int
857 get_ra_info(ip6_t *ip6h, uchar_t *end, nd_router_advert_t **ra)
858 {
859 uint16_t hdrlen;
860 ip6_frag_t *frag = NULL;
861 uint8_t proto;
862 uchar_t *hdrp;
863 struct icmp6_hdr *icmp;
864
865 if (!mac_ip_hdr_length_v6(ip6h, end, &hdrlen, &proto, &frag))
866 return (ENOSPC);
867
868 if (proto != IPPROTO_ICMPV6)
869 return (EINVAL);
870
871 if (frag != NULL) {
872 /*
873 * All non-initial fragments may pass because we cannot
874 * identify their type. It's safe to let them through
875 * because reassembly will fail if we decide to drop the
876 * initial fragment.
877 */
878 if ((ntohs(frag->ip6f_offlg) & ~7) != 0)
879 return (EINVAL);
880 return (ENOSPC);
881 }
882
883 /*
884 * Ensure that the ICMP header falls w/in packet boundaries, in case
885 * we've received a malicious packet that reports incorrect lengths.
886 */
|
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
24 * Copyright (c) 2019, Joyent, Inc. All rights reserved.
25 */
26 /*
27 * Copyright 2014 Nexenta Systems, Inc. All rights reserved.
28 */
29
30 #include <sys/cmn_err.h>
31 #include <sys/strsun.h>
32 #include <sys/sdt.h>
33 #include <sys/mac.h>
34 #include <sys/mac_impl.h>
35 #include <sys/mac_client_impl.h>
36 #include <sys/mac_client_priv.h>
37 #include <sys/ethernet.h>
38 #include <sys/vlan.h>
39 #include <sys/dlpi.h>
40 #include <sys/avl.h>
41 #include <inet/ip.h>
42 #include <inet/ip6.h>
43 #include <inet/arp.h>
44 #include <netinet/arp.h>
795 return (0);
796 }
797
798 /*
799 * Locate the start of a DHCPv6 header.
800 * The possible return values and associated meanings are:
801 * 0 - packet is DHCP and has a DHCP header.
802 * EINVAL - packet is not DHCP. the recommended action is to let it pass.
803 * ENOSPC - packet is a initial fragment that is DHCP or is unidentifiable.
804 * the recommended action is to drop it.
805 */
806 static int
807 get_dhcpv6_info(ip6_t *ip6h, uchar_t *end, dhcpv6_message_t **dh6)
808 {
809 uint16_t hdrlen, client, server;
810 boolean_t first_frag = B_FALSE;
811 ip6_frag_t *frag = NULL;
812 uint8_t proto;
813 struct udphdr *udph;
814 uchar_t *dh;
815 int errno;
816
817 errno = mac_ip_hdr_length_v6(ip6h, end, &hdrlen, &proto, &frag);
818 if (errno != 0)
819 return (errno);
820
821 if (proto != IPPROTO_UDP)
822 return (EINVAL);
823
824 if (frag != NULL) {
825 /*
826 * All non-initial fragments may pass because we cannot
827 * identify their type. It's safe to let them through
828 * because reassembly will fail if we decide to drop the
829 * initial fragment.
830 */
831 if ((ntohs(frag->ip6f_offlg) & ~7) != 0)
832 return (EINVAL);
833 first_frag = B_TRUE;
834 }
835 /* drop packets without a udp header */
836 udph = (struct udphdr *)((uchar_t *)ip6h + hdrlen);
837 if ((uchar_t *)&udph[1] > end)
838 return (ENOSPC);
839
846 /* drop dhcp fragments */
847 if (first_frag)
848 return (ENOSPC);
849
850 dh = (uchar_t *)&udph[1];
851 if (dh + sizeof (dhcpv6_message_t) > end)
852 return (EINVAL);
853
854 *dh6 = (dhcpv6_message_t *)dh;
855 return (0);
856 }
857
858 static int
859 get_ra_info(ip6_t *ip6h, uchar_t *end, nd_router_advert_t **ra)
860 {
861 uint16_t hdrlen;
862 ip6_frag_t *frag = NULL;
863 uint8_t proto;
864 uchar_t *hdrp;
865 struct icmp6_hdr *icmp;
866 int errno;
867
868 errno = mac_ip_hdr_length_v6(ip6h, end, &hdrlen, &proto, &frag);
869 if (errno != 0)
870 return (errno);
871
872 if (proto != IPPROTO_ICMPV6)
873 return (EINVAL);
874
875 if (frag != NULL) {
876 /*
877 * All non-initial fragments may pass because we cannot
878 * identify their type. It's safe to let them through
879 * because reassembly will fail if we decide to drop the
880 * initial fragment.
881 */
882 if ((ntohs(frag->ip6f_offlg) & ~7) != 0)
883 return (EINVAL);
884 return (ENOSPC);
885 }
886
887 /*
888 * Ensure that the ICMP header falls w/in packet boundaries, in case
889 * we've received a malicious packet that reports incorrect lengths.
890 */
|