Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. =================================================================== RCS file: /ftp/cvs/cvsroot/src/sys/netinet/udp_usrreq.c,v rcsdiff: /ftp/cvs/cvsroot/src/sys/netinet/udp_usrreq.c,v: warning: Unknown phrases like `commitid ...;' are present. retrieving revision 1.80.2.3 retrieving revision 1.87 diff -u -p -r1.80.2.3 -r1.87 --- src/sys/netinet/udp_usrreq.c 2002/06/23 17:51:04 1.80.2.3 +++ src/sys/netinet/udp_usrreq.c 2001/10/29 07:02:34 1.87 @@ -1,9 +1,9 @@ -/* $NetBSD: udp_usrreq.c,v 1.80.2.3 2002/06/23 17:51:04 jdolecek Exp $ */ +/* $NetBSD: udp_usrreq.c,v 1.87 2001/10/29 07:02:34 simonb Exp $ */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. * All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -15,7 +15,7 @@ * 3. Neither the name of the project nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. - * + * * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE @@ -64,9 +64,6 @@ * @(#)udp_usrreq.c 8.6 (Berkeley) 5/23/95 */ -#include -__KERNEL_RCSID(0, "$NetBSD: udp_usrreq.c,v 1.80.2.3 2002/06/23 17:51:04 jdolecek Exp $"); - #include "opt_inet.h" #include "opt_ipsec.h" #include "opt_inet_csum.h" @@ -139,9 +136,6 @@ int udpcksum = 1; int udpcksum = 0; /* XXX */ #endif -struct inpcbtable udbtable; -struct udpstat udpstat; - #ifdef INET static void udp4_sendup __P((struct mbuf *, int, struct sockaddr *, struct socket *)); @@ -151,6 +145,8 @@ static int udp4_realinput __P((struct so #ifdef INET6 static void udp6_sendup __P((struct mbuf *, int, struct sockaddr *, struct socket *)); +static int in6_mcmatch __P((struct in6pcb *, struct in6_addr *, + struct ifnet *)); static int udp6_realinput __P((int, struct sockaddr_in6 *, struct sockaddr_in6 *, struct mbuf *, int)); #endif @@ -633,13 +629,15 @@ udp4_realinput(src, dst, m, off) */ /* - * KAME note: traditionally we dropped udpiphdr from mbuf here. + * KAME note: usually we drop udpiphdr from mbuf here. * we need udpiphdr for IPsec processing so we do that later. */ /* * Locate pcb(s) for datagram. */ - CIRCLEQ_FOREACH(inp, &udbtable.inpt_queue, inp_queue) { + for (inp = udbtable.inpt_queue.cqh_first; + inp != (struct inpcb *)&udbtable.inpt_queue; + inp = inp->inp_queue.cqe_next) { if (inp->inp_lport != *dport) continue; if (!in_nullhost(inp->inp_laddr)) { @@ -692,6 +690,29 @@ bad: #ifdef INET6 static int +in6_mcmatch(in6p, ia6, ifp) + struct in6pcb *in6p; + struct in6_addr *ia6; + struct ifnet *ifp; +{ + struct ip6_moptions *im6o = in6p->in6p_moptions; + struct in6_multi_mship *imm; + + if (im6o == NULL) + return 0; + + for (imm = im6o->im6o_memberships.lh_first; imm != NULL; + imm = imm->i6mm_chain.le_next) { + if ((ifp == NULL || + imm->i6mm_maddr->in6m_ifp == ifp) && + IN6_ARE_ADDR_EQUAL(&imm->i6mm_maddr->in6m_addr, + ia6)) + return 1; + } + return 0; +} + +static int udp6_realinput(af, src, dst, m, off) int af; /* af on packet */ struct sockaddr_in6 *src; @@ -717,7 +738,7 @@ udp6_realinput(af, src, dst, m, off) sport = src->sin6_port; in6_embedscope(&dst6, dst, NULL, NULL); dport = dst->sin6_port; - dst4 = (struct in_addr *)&dst->sin6_addr.s6_addr[12]; + dst4 = (struct in_addr *)&dst->sin6_addr.s6_addr32[12]; if (IN6_IS_ADDR_MULTICAST(&dst6) || (af == AF_INET && IN_MULTICAST(dst4->s_addr))) { @@ -739,7 +760,7 @@ udp6_realinput(af, src, dst, m, off) */ /* - * KAME note: traditionally we dropped udpiphdr from mbuf here. + * KAME note: usually we drop udpiphdr from mbuf here. * we need udpiphdr for IPsec processing so we do that later. */ /* @@ -750,9 +771,11 @@ udp6_realinput(af, src, dst, m, off) if (in6p->in6p_lport != dport) continue; if (!IN6_IS_ADDR_UNSPECIFIED(&in6p->in6p_laddr)) { - if (!IN6_ARE_ADDR_EQUAL(&in6p->in6p_laddr, &dst6)) + if (!IN6_ARE_ADDR_EQUAL(&in6p->in6p_laddr, &dst6) && + !in6_mcmatch(in6p, &dst6, m->m_pkthdr.rcvif)) continue; - } else { + } + else { if (IN6_IS_ADDR_V4MAPPED(&dst6) && (in6p->in6p_flags & IN6P_IPV6_V6ONLY)) continue; @@ -761,7 +784,8 @@ udp6_realinput(af, src, dst, m, off) if (!IN6_ARE_ADDR_EQUAL(&in6p->in6p_faddr, &src6) || in6p->in6p_fport != sport) continue; - } else { + } + else { if (IN6_IS_ADDR_V4MAPPED(&src6) && (in6p->in6p_flags & IN6P_IPV6_V6ONLY)) continue; @@ -1137,7 +1161,7 @@ udp_sysctl(name, namelen, oldp, oldlenp, return (sysctl_int(oldp, oldlenp, newp, newlen, &udp_sendspace)); case UDPCTL_RECVSPACE: - return (sysctl_int(oldp, oldlenp, newp, newlen, + return (sysctl_int(oldp, oldlenp, newp, newlen, &udp_recvspace)); default: return (ENOPROTOOPT);