remove unused codepath (unifdef -UUDP6)

This commit is contained in:
itojun 2001-10-24 06:04:08 +00:00
parent 7bbe09e1d4
commit c7e6405a34
2 changed files with 2 additions and 632 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: udp_usrreq.c,v 1.85 2001/10/15 09:51:15 itojun Exp $ */
/* $NetBSD: udp_usrreq.c,v 1.86 2001/10/24 06:04:08 itojun Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@ -197,7 +197,6 @@ udp_init()
#endif /* UDP_CSUM_COUNTERS */
}
#ifndef UDP6
#ifdef INET
void
#if __STDC__
@ -833,309 +832,6 @@ bad:
}
#endif
#else /*UDP6*/
void
#if __STDC__
udp_input(struct mbuf *m, ...)
#else
udp_input(m, va_alist)
struct mbuf *m;
va_dcl
#endif
{
int proto;
struct ip *ip;
struct udphdr *uh;
struct inpcb *inp;
struct mbuf *opts = 0;
int len;
struct ip save_ip;
int iphlen;
va_list ap;
struct sockaddr_in udpsrc;
struct sockaddr *sa;
va_start(ap, m);
iphlen = va_arg(ap, int);
proto = va_arg(ap, int);
va_end(ap);
udpstat.udps_ipackets++;
/*
* Strip IP options, if any; should skip this,
* make available to user, and use on returned packets,
* but we don't yet have a way to check the checksum
* with options still present.
*/
if (iphlen > sizeof (struct ip)) {
ip_stripoptions(m, (struct mbuf *)0);
iphlen = sizeof(struct ip);
}
/*
* Get IP and UDP header together in first mbuf.
*/
ip = mtod(m, struct ip *);
if (m->m_len < iphlen + sizeof(struct udphdr)) {
if ((m = m_pullup(m, iphlen + sizeof(struct udphdr))) == 0) {
udpstat.udps_hdrops++;
return;
}
ip = mtod(m, struct ip *);
}
uh = (struct udphdr *)((caddr_t)ip + iphlen);
/* destination port of 0 is illegal, based on RFC768. */
if (uh->uh_dport == 0)
goto bad;
/*
* Make mbuf data length reflect UDP length.
* If not enough data to reflect UDP length, drop.
*/
len = ntohs((u_int16_t)uh->uh_ulen);
if (ip->ip_len != iphlen + len) {
if (ip->ip_len < iphlen + len || len < sizeof(struct udphdr)) {
udpstat.udps_badlen++;
goto bad;
}
m_adj(m, iphlen + len - ip->ip_len);
}
/*
* Save a copy of the IP header in case we want restore it
* for sending an ICMP error message in response.
*/
save_ip = *ip;
/*
* Checksum extended UDP header and data.
*/
if (uh->uh_sum) {
switch (m->m_pkthdr.csum_flags &
((m->m_pkthdr.rcvif->if_csum_flags & M_CSUM_UDPv4) |
M_CSUM_TCP_UDP_BAD | M_CSUM_DATA)) {
case M_CSUM_UDPv4|M_CSUM_TCP_UDP_BAD:
UDP_CSUM_COUNTER_INCR(&udp_hwcsum_bad);
goto badcsum;
case M_CSUM_UDPv4|M_CSUM_DATA:
UDP_CSUM_COUNTER_INCR(&udp_hwcsum_data);
if ((m->m_pkthdr.csum_data ^ 0xffff) != 0)
goto badcsum;
break;
case M_CSUM_UDPv4:
/* Checksum was okay. */
UDP_CSUM_COUNTER_INCR(&udp_hwcsum_ok);
break;
default:
/* Need to compute it ourselves. */
UDP_CSUM_COUNTER_INCR(&udp_swcsum);
bzero(((struct ipovly *)ip)->ih_x1,
sizeof ((struct ipovly *)ip)->ih_x1);
((struct ipovly *)ip)->ih_len = uh->uh_ulen;
if (in_cksum(m, len + sizeof (struct ip)) != 0)
goto badcsum;
break;
}
}
/*
* Construct sockaddr format source address.
*/
udpsrc.sin_family = AF_INET;
udpsrc.sin_len = sizeof(struct sockaddr_in);
udpsrc.sin_addr = ip->ip_src;
udpsrc.sin_port = uh->uh_sport;
bzero((caddr_t)udpsrc.sin_zero, sizeof(udpsrc.sin_zero));
if (IN_MULTICAST(ip->ip_dst.s_addr) ||
in_broadcast(ip->ip_dst, m->m_pkthdr.rcvif)) {
struct inpcb *last;
/*
* Deliver a multicast or broadcast datagram to *all* sockets
* for which the local and remote addresses and ports match
* those of the incoming datagram. This allows more than
* one process to receive multi/broadcasts on the same port.
* (This really ought to be done for unicast datagrams as
* well, but that would cause problems with existing
* applications that open both address-specific sockets and
* a wildcard socket listening to the same port -- they would
* end up receiving duplicates of every unicast datagram.
* Those applications open the multiple sockets to overcome an
* inadequacy of the UDP socket interface, but for backwards
* compatibility we avoid the problem here rather than
* fixing the interface. Maybe 4.5BSD will remedy this?)
*/
iphlen += sizeof(struct udphdr);
/*
* 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.
* (Algorithm copied from raw_intr().)
*/
last = NULL;
for (inp = udbtable.inpt_queue.cqh_first;
inp != (struct inpcb *)&udbtable.inpt_queue;
inp = inp->inp_queue.cqe_next) {
if (inp->inp_lport != uh->uh_dport)
continue;
if (!in_nullhost(inp->inp_laddr)) {
if (!in_hosteq(inp->inp_laddr, ip->ip_dst))
continue;
}
if (!in_nullhost(inp->inp_faddr)) {
if (!in_hosteq(inp->inp_faddr, ip->ip_src) ||
inp->inp_fport != uh->uh_sport)
continue;
}
if (last != NULL) {
struct mbuf *n;
#ifdef IPSEC
/* check AH/ESP integrity. */
if (last != NULL && ipsec4_in_reject(m, last)) {
ipsecstat.in_polvio++;
/* do not inject data to pcb */
} else
#endif /*IPSEC*/
if ((n = m_copy(m, 0, M_COPYALL)) != NULL) {
if (last->inp_flags & INP_CONTROLOPTS
|| last->inp_socket->so_options &
SO_TIMESTAMP) {
ip_savecontrol(last, &opts,
ip, n);
}
m_adj(n, iphlen);
sa = (struct sockaddr *)&udpsrc;
if (sbappendaddr(
&last->inp_socket->so_rcv,
sa, n, opts) == 0) {
m_freem(n);
if (opts)
m_freem(opts);
udpstat.udps_fullsock++;
} else
sorwakeup(last->inp_socket);
opts = 0;
}
}
last = inp;
/*
* Don't look for additional matches if this one does
* not have either the SO_REUSEPORT or SO_REUSEADDR
* socket options set. This heuristic avoids searching
* through all pcbs in the common case of a non-shared
* port. It * assumes that an application will never
* clear these options after setting them.
*/
if ((last->inp_socket->so_options &
(SO_REUSEPORT|SO_REUSEADDR)) == 0)
break;
}
if (last == NULL) {
/*
* No matching pcb found; discard datagram.
* (No need to send an ICMP Port Unreachable
* for a broadcast or multicast datgram.)
*/
udpstat.udps_noportbcast++;
goto bad;
}
#ifdef IPSEC
/* check AH/ESP integrity. */
if (last != NULL && ipsec4_in_reject(m, last)) {
ipsecstat.in_polvio++;
goto bad;
}
#endif /*IPSEC*/
if (last->inp_flags & INP_CONTROLOPTS ||
last->inp_socket->so_options & SO_TIMESTAMP)
ip_savecontrol(last, &opts, ip, m);
m->m_len -= iphlen;
m->m_pkthdr.len -= iphlen;
m->m_data += iphlen;
sa = (struct sockaddr *)&udpsrc;
if (sbappendaddr(&last->inp_socket->so_rcv, sa, m, opts) == 0) {
udpstat.udps_fullsock++;
goto bad;
}
sorwakeup(last->inp_socket);
return;
}
/*
* Locate pcb for datagram.
*/
inp = in_pcblookup_connect(&udbtable, ip->ip_src, uh->uh_sport,
ip->ip_dst, uh->uh_dport);
if (inp == 0) {
++udpstat.udps_pcbhashmiss;
inp = in_pcblookup_bind(&udbtable, ip->ip_dst, uh->uh_dport);
if (inp == 0) {
if (m->m_flags & (M_BCAST | M_MCAST)) {
udpstat.udps_noportbcast++;
goto bad;
}
udpstat.udps_noport++;
*ip = save_ip;
#ifdef IPKDB
if (checkipkdb(&ip->ip_src,
uh->uh_sport,
uh->uh_dport,
m,
iphlen + sizeof(struct udphdr),
len - sizeof(struct udphdr)))
/* It was a debugger connect packet, just drop it now */
goto bad;
#endif
icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_PORT, 0, 0);
return;
}
}
#ifdef IPSEC
if (inp != NULL && ipsec4_in_reject(m, inp)) {
ipsecstat.in_polvio++;
goto bad;
}
#endif /*IPSEC*/
/*
* Stuff source address and datagram in user buffer.
*/
if (inp->inp_flags & INP_CONTROLOPTS ||
inp->inp_socket->so_options & SO_TIMESTAMP)
ip_savecontrol(inp, &opts, ip, m);
iphlen += sizeof(struct udphdr);
m->m_len -= iphlen;
m->m_pkthdr.len -= iphlen;
m->m_data += iphlen;
sa = (struct sockaddr *)&udpsrc;
if (sbappendaddr(&inp->inp_socket->so_rcv, sa, m, opts) == 0) {
udpstat.udps_fullsock++;
goto bad;
}
sorwakeup(inp->inp_socket);
return;
bad:
m_freem(m);
if (opts)
m_freem(opts);
return;
badcsum:
udpstat.udps_badsum++;
m_freem(m);
}
#endif /*UDP6*/
#ifdef INET
/*
* Notify a udp user of an asynchronous error;

View File

@ -1,4 +1,4 @@
/* $NetBSD: udp6_usrreq.c,v 1.47 2001/10/18 07:44:36 itojun Exp $ */
/* $NetBSD: udp6_usrreq.c,v 1.48 2001/10/24 06:04:08 itojun Exp $ */
/* $KAME: udp6_usrreq.c,v 1.86 2001/05/27 17:33:00 itojun Exp $ */
/*
@ -114,9 +114,6 @@
struct in6pcb *udp6_last_in6pcb = &udb6;
#ifdef UDP6
static int in6_mcmatch __P((struct in6pcb *, struct in6_addr *, struct ifnet *));
#endif
static void udp6_detach __P((struct in6pcb *));
static void udp6_notify __P((struct in6pcb *, int));
@ -126,329 +123,6 @@ udp6_init()
udb6.in6p_next = udb6.in6p_prev = &udb6;
}
#ifdef UDP6
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;
}
int
udp6_input(mp, offp, proto)
struct mbuf **mp;
int *offp, proto;
{
struct mbuf *m = *mp;
struct ip6_hdr *ip6;
struct udphdr *uh;
struct in6pcb *in6p;
struct mbuf *opts = 0;
int off = *offp;
u_int32_t plen, ulen;
struct sockaddr_in6 udp_in6;
ip6 = mtod(m, struct ip6_hdr *);
#if defined(NFAITH) && 0 < NFAITH
if (faithprefix(&ip6->ip6_dst)) {
/* send icmp6 host unreach? */
m_freem(m);
return IPPROTO_DONE;
}
#endif
udp6stat.udp6s_ipackets++;
/* check for jumbogram is done in ip6_input. we can trust pkthdr.len */
plen = m->m_pkthdr.len - off;
#ifndef PULLDOWN_TEST
IP6_EXTHDR_CHECK(m, off, sizeof(struct udphdr), IPPROTO_DONE);
uh = (struct udphdr *)((caddr_t)ip6 + off);
#else
IP6_EXTHDR_GET(uh, struct udphdr *, m, off, sizeof(struct udphdr));
if (uh == NULL) {
udp6stat.udp6s_hdrops++;
return IPPROTO_DONE;
}
#endif
ulen = ntohs((u_short)uh->uh_ulen);
/*
* RFC2675 section 4: jumbograms will have 0 in the UDP header field,
* iff payload length > 0xffff.
*/
if (ulen == 0 && plen > 0xffff)
ulen = plen;
if (plen != ulen) {
udp6stat.udp6s_badlen++;
goto bad;
}
/* destination port of 0 is illegal, based on RFC768. */
if (uh->uh_dport == 0)
goto bad;
/* Be proactive about malicious use of IPv4 mapped address */
if (IN6_IS_ADDR_V4MAPPED(&ip6->ip6_src) ||
IN6_IS_ADDR_V4MAPPED(&ip6->ip6_dst)) {
/* XXX stat */
goto bad;
}
/*
* Checksum extended UDP header and data.
*/
if (uh->uh_sum == 0)
udp6stat.udp6s_nosum++;
else if (in6_cksum(m, IPPROTO_UDP, off, ulen) != 0) {
udp6stat.udp6s_badsum++;
goto bad;
}
if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst)) {
struct in6pcb *last;
/*
* Deliver a multicast datagram to all sockets
* for which the local and remote addresses and ports match
* those of the incoming datagram. This allows more than
* one process to receive multicasts on the same port.
* (This really ought to be done for unicast datagrams as
* well, but that would cause problems with existing
* applications that open both address-specific sockets and
* a wildcard socket listening to the same port -- they would
* end up receiving duplicates of every unicast datagram.
* Those applications open the multiple sockets to overcome an
* inadequacy of the UDP socket interface, but for backwards
* compatibility we avoid the problem here rather than
* fixing the interface. Maybe 4.5BSD will remedy this?)
*/
/*
* In a case that laddr should be set to the link-local
* address (this happens in RIPng), the multicast address
* specified in the received packet does not match with
* laddr. To cure this situation, the matching is relaxed
* if the receiving interface is the same as one specified
* in the socket and if the destination multicast address
* matches one of the multicast groups specified in the socket.
*/
/*
* Construct sockaddr format source address.
*/
bzero(&udp_in6, sizeof(udp_in6));
udp_in6.sin6_len = sizeof(struct sockaddr_in6);
udp_in6.sin6_family = AF_INET6;
udp_in6.sin6_port = uh->uh_sport;
#if 0 /*XXX inbound flowinfo */
udp_in6.sin6_flowinfo = ip6->ip6_flow & IPV6_FLOWINFO_MASK;
#endif
/* KAME hack: recover scopeid */
(void)in6_recoverscope(&udp_in6, &ip6->ip6_src,
m->m_pkthdr.rcvif);
/*
* KAME note: traditionally we dropped udpiphdr from mbuf here.
* We need udphdr for IPsec processing so we do that later.
*/
/*
* Locate pcb(s) for datagram.
* (Algorithm copied from raw_intr().)
*/
last = NULL;
for (in6p = udb6.in6p_next;
in6p != &udb6;
in6p = in6p->in6p_next) {
if (in6p->in6p_lport != uh->uh_dport)
continue;
if (!IN6_IS_ADDR_UNSPECIFIED(&in6p->in6p_laddr)) {
if (!IN6_ARE_ADDR_EQUAL(&in6p->in6p_laddr,
&ip6->ip6_dst) &&
!in6_mcmatch(in6p, &ip6->ip6_dst,
m->m_pkthdr.rcvif))
continue;
}
if (!IN6_IS_ADDR_UNSPECIFIED(&in6p->in6p_faddr)) {
if (!IN6_ARE_ADDR_EQUAL(&in6p->in6p_faddr,
&ip6->ip6_src) ||
in6p->in6p_fport != uh->uh_sport)
continue;
}
if (last != NULL) {
struct mbuf *n;
#ifdef IPSEC
/*
* Check AH/ESP integrity.
*/
if (ipsec6_in_reject(m, last)) {
ipsec6stat.in_polvio++;
/* do not inject data into pcb */
} else
#endif /*IPSEC*/
if ((n = m_copy(m, 0, M_COPYALL)) != NULL) {
/*
* KAME NOTE: do not
* m_copy(m, offset, ...) above.
* sbappendaddr() expects M_PKTHDR,
* and m_copy() will copy M_PKTHDR
* only if offset is 0.
*/
if (last->in6p_flags & IN6P_CONTROLOPTS
|| last->in6p_socket->so_options & SO_TIMESTAMP) {
ip6_savecontrol(last, &opts,
ip6, n);
}
m_adj(n, off + sizeof(struct udphdr));
if (sbappendaddr(&last->in6p_socket->so_rcv,
(struct sockaddr *)&udp_in6,
n, opts) == 0) {
m_freem(n);
if (opts)
m_freem(opts);
udp6stat.udp6s_fullsock++;
} else
sorwakeup(last->in6p_socket);
opts = 0;
}
}
last = in6p;
/*
* Don't look for additional matches if this one does
* not have either the SO_REUSEPORT or SO_REUSEADDR
* socket options set. This heuristic avoids searching
* through all pcbs in the common case of a non-shared
* port. It assumes that an application will never
* clear these options after setting them.
*/
if ((last->in6p_socket->so_options &
(SO_REUSEPORT|SO_REUSEADDR)) == 0)
break;
}
if (last == NULL) {
/*
* No matching pcb found; discard datagram.
* (No need to send an ICMP Port Unreachable
* for a broadcast or multicast datgram.)
*/
udp6stat.udp6s_noport++;
udp6stat.udp6s_noportmcast++;
goto bad;
}
#ifdef IPSEC
/*
* Check AH/ESP integrity.
*/
if (last != NULL && ipsec6_in_reject(m, last)) {
ipsec6stat.in_polvio++;
goto bad;
}
#endif /*IPSEC*/
if (last->in6p_flags & IN6P_CONTROLOPTS
|| last->in6p_socket->so_options & SO_TIMESTAMP) {
ip6_savecontrol(last, &opts, ip6, m);
}
m_adj(m, off + sizeof(struct udphdr));
if (sbappendaddr(&last->in6p_socket->so_rcv,
(struct sockaddr *)&udp_in6,
m, opts) == 0) {
udp6stat.udp6s_fullsock++;
goto bad;
}
sorwakeup(last->in6p_socket);
return IPPROTO_DONE;
}
/*
* Locate pcb for datagram.
*/
in6p = udp6_last_in6pcb;
if (in6p->in6p_lport != uh->uh_dport ||
in6p->in6p_fport != uh->uh_sport ||
!IN6_ARE_ADDR_EQUAL(&in6p->in6p_faddr, &ip6->ip6_src) ||
!IN6_ARE_ADDR_EQUAL(&in6p->in6p_laddr, &ip6->ip6_dst)) {
in6p = in6_pcblookup(&udb6,
&ip6->ip6_src, uh->uh_sport,
&ip6->ip6_dst, uh->uh_dport,
IN6PLOOKUP_WILDCARD);
if (in6p)
udp6_last_in6pcb = in6p;
udp6stat.udp6ps_pcbcachemiss++;
}
if (in6p == 0) {
udp6stat.udp6s_noport++;
if (m->m_flags & M_MCAST) {
udp6stat.udp6s_noportmcast++;
goto bad;
}
icmp6_error(m, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_NOPORT, 0);
return IPPROTO_DONE;
}
#ifdef IPSEC
/*
* Check AH/ESP integrity.
*/
if (in6p != NULL && ipsec6_in_reject(m, in6p)) {
ipsec6stat.in_polvio++;
goto bad;
}
#endif /*IPSEC*/
/*
* Construct sockaddr format source address.
* Stuff source address and datagram in user buffer.
*/
bzero(&udp_in6, sizeof(udp_in6));
udp_in6.sin6_len = sizeof(struct sockaddr_in6);
udp_in6.sin6_family = AF_INET6;
udp_in6.sin6_port = uh->uh_sport;
/* KAME hack: recover scopeid */
(void)in6_recoverscope(&udp_in6, &ip6->ip6_src, m->m_pkthdr.rcvif);
if (in6p->in6p_flags & IN6P_CONTROLOPTS
|| in6p->in6p_socket->so_options & SO_TIMESTAMP) {
ip6_savecontrol(in6p, &opts, ip6, m);
}
m_adj(m, off + sizeof(struct udphdr));
if (sbappendaddr(&in6p->in6p_socket->so_rcv,
(struct sockaddr *)&udp_in6,
m, opts) == 0) {
udp6stat.udp6s_fullsock++;
goto bad;
}
sorwakeup(in6p->in6p_socket);
return IPPROTO_DONE;
bad:
if (m)
m_freem(m);
if (opts)
m_freem(opts);
return IPPROTO_DONE;
}
#endif
/*
* Notify a udp user of an asynchronous error;
* just wake up so that he can collect error status.