Deleted Added
full compact
udp6_usrreq.c (72650) udp6_usrreq.c (78064)
1/* $FreeBSD: head/sys/netinet6/udp6_usrreq.c 72650 2001-02-18 13:30:20Z green $ */
2/* $KAME: udp6_usrreq.c,v 1.17 2000/10/13 17:46:21 itojun Exp $ */
1/* $FreeBSD: head/sys/netinet6/udp6_usrreq.c 78064 2001-06-11 12:39:29Z ume $ */
2/* $KAME: udp6_usrreq.c,v 1.27 2001/05/21 05:45:10 jinmei Exp $ */
3
4/*
5 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:

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

102#include <netinet6/ip6protosw.h>
103
104#ifdef IPSEC
105#include <netinet6/ipsec.h>
106#include <netinet6/ipsec6.h>
107#endif /*IPSEC*/
108
109#include "faith.h"
3
4/*
5 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:

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

102#include <netinet6/ip6protosw.h>
103
104#ifdef IPSEC
105#include <netinet6/ipsec.h>
106#include <netinet6/ipsec6.h>
107#endif /*IPSEC*/
108
109#include "faith.h"
110#if defined(NFAITH) && NFAITH > 0
111#include <net/if_faith.h>
112#endif
110
111/*
112 * UDP protocol inplementation.
113 * Per RFC 768, August, 1980.
114 */
115
116extern struct protosw inetsw[];
117static int in6_mcmatch __P((struct inpcb *, struct in6_addr *, struct ifnet *));

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

144udp6_input(mp, offp, proto)
145 struct mbuf **mp;
146 int *offp, proto;
147{
148 struct mbuf *m = *mp;
149 register struct ip6_hdr *ip6;
150 register struct udphdr *uh;
151 register struct inpcb *in6p;
113
114/*
115 * UDP protocol inplementation.
116 * Per RFC 768, August, 1980.
117 */
118
119extern struct protosw inetsw[];
120static int in6_mcmatch __P((struct inpcb *, struct in6_addr *, struct ifnet *));

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

147udp6_input(mp, offp, proto)
148 struct mbuf **mp;
149 int *offp, proto;
150{
151 struct mbuf *m = *mp;
152 register struct ip6_hdr *ip6;
153 register struct udphdr *uh;
154 register struct inpcb *in6p;
152 struct mbuf *opts = 0;
155 struct mbuf *opts = NULL;
153 int off = *offp;
154 int plen, ulen;
155 struct sockaddr_in6 udp_in6;
156
156 int off = *offp;
157 int plen, ulen;
158 struct sockaddr_in6 udp_in6;
159
160 IP6_EXTHDR_CHECK(m, off, sizeof(struct udphdr), IPPROTO_DONE);
161
162 ip6 = mtod(m, struct ip6_hdr *);
163
157#if defined(NFAITH) && 0 < NFAITH
164#if defined(NFAITH) && 0 < NFAITH
158 if (m->m_pkthdr.rcvif) {
159 if (m->m_pkthdr.rcvif->if_type == IFT_FAITH) {
160 /* XXX send icmp6 host/port unreach? */
161 m_freem(m);
162 return IPPROTO_DONE;
163 }
165 if (faithprefix(&ip6->ip6_dst)) {
166 /* XXX send icmp6 host/port unreach? */
167 m_freem(m);
168 return IPPROTO_DONE;
164 }
165#endif
169 }
170#endif
171
166 udpstat.udps_ipackets++;
167
172 udpstat.udps_ipackets++;
173
168 IP6_EXTHDR_CHECK(m, off, sizeof(struct udphdr), IPPROTO_DONE);
169
170 ip6 = mtod(m, struct ip6_hdr *);
171 plen = ntohs(ip6->ip6_plen) - off + sizeof(*ip6);
172 uh = (struct udphdr *)((caddr_t)ip6 + off);
173 ulen = ntohs((u_short)uh->uh_ulen);
174
175 if (plen != ulen) {
176 udpstat.udps_badlen++;
177 goto bad;
178 }

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

269 * sbappendaddr() expects M_PKTHDR,
270 * and m_copy() will copy M_PKTHDR
271 * only if offset is 0.
272 */
273 if (last->in6p_flags & IN6P_CONTROLOPTS
274 || last->in6p_socket->so_options & SO_TIMESTAMP)
275 ip6_savecontrol(last, &opts,
276 ip6, n);
174 plen = ntohs(ip6->ip6_plen) - off + sizeof(*ip6);
175 uh = (struct udphdr *)((caddr_t)ip6 + off);
176 ulen = ntohs((u_short)uh->uh_ulen);
177
178 if (plen != ulen) {
179 udpstat.udps_badlen++;
180 goto bad;
181 }

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

272 * sbappendaddr() expects M_PKTHDR,
273 * and m_copy() will copy M_PKTHDR
274 * only if offset is 0.
275 */
276 if (last->in6p_flags & IN6P_CONTROLOPTS
277 || last->in6p_socket->so_options & SO_TIMESTAMP)
278 ip6_savecontrol(last, &opts,
279 ip6, n);
280
277 m_adj(n, off + sizeof(struct udphdr));
278 if (sbappendaddr(&last->in6p_socket->so_rcv,
279 (struct sockaddr *)&udp_in6,
280 n, opts) == 0) {
281 m_freem(n);
282 if (opts)
283 m_freem(opts);
284 udpstat.udps_fullsock++;
285 } else
286 sorwakeup(last->in6p_socket);
281 m_adj(n, off + sizeof(struct udphdr));
282 if (sbappendaddr(&last->in6p_socket->so_rcv,
283 (struct sockaddr *)&udp_in6,
284 n, opts) == 0) {
285 m_freem(n);
286 if (opts)
287 m_freem(opts);
288 udpstat.udps_fullsock++;
289 } else
290 sorwakeup(last->in6p_socket);
287 opts = 0;
291 opts = NULL;
288 }
289 }
290 last = in6p;
291 /*
292 * Don't look for additional matches if this one does
293 * not have either the SO_REUSEPORT or SO_REUSEADDR
294 * socket options set. This heuristic avoids searching
295 * through all pcbs in the common case of a non-shared

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

396}
397
398void
399udp6_ctlinput(cmd, sa, d)
400 int cmd;
401 struct sockaddr *sa;
402 void *d;
403{
292 }
293 }
294 last = in6p;
295 /*
296 * Don't look for additional matches if this one does
297 * not have either the SO_REUSEPORT or SO_REUSEADDR
298 * socket options set. This heuristic avoids searching
299 * through all pcbs in the common case of a non-shared

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

400}
401
402void
403udp6_ctlinput(cmd, sa, d)
404 int cmd;
405 struct sockaddr *sa;
406 void *d;
407{
404 register struct udphdr *uhp;
405 struct udphdr uh;
408 struct udphdr uh;
406 struct sockaddr_in6 sa6;
407 struct ip6_hdr *ip6;
408 struct mbuf *m;
409 int off = 0;
409 struct ip6_hdr *ip6;
410 struct mbuf *m;
411 int off = 0;
412 struct ip6ctlparam *ip6cp = NULL;
413 const struct sockaddr_in6 *sa6_src = NULL;
410 void (*notify) __P((struct inpcb *, int)) = udp_notify;
414 void (*notify) __P((struct inpcb *, int)) = udp_notify;
415 struct udp_portonly {
416 u_int16_t uh_sport;
417 u_int16_t uh_dport;
418 } *uhp;
411
412 if (sa->sa_family != AF_INET6 ||
413 sa->sa_len != sizeof(struct sockaddr_in6))
414 return;
415
416 if ((unsigned)cmd >= PRC_NCMDS)
417 return;
418 if (PRC_IS_REDIRECT(cmd))
419 notify = in6_rtchange, d = NULL;
420 else if (cmd == PRC_HOSTDEAD)
421 d = NULL;
422 else if (inet6ctlerrmap[cmd] == 0)
423 return;
424
425 /* if the parameter is from icmp6, decode it. */
426 if (d != NULL) {
419
420 if (sa->sa_family != AF_INET6 ||
421 sa->sa_len != sizeof(struct sockaddr_in6))
422 return;
423
424 if ((unsigned)cmd >= PRC_NCMDS)
425 return;
426 if (PRC_IS_REDIRECT(cmd))
427 notify = in6_rtchange, d = NULL;
428 else if (cmd == PRC_HOSTDEAD)
429 d = NULL;
430 else if (inet6ctlerrmap[cmd] == 0)
431 return;
432
433 /* if the parameter is from icmp6, decode it. */
434 if (d != NULL) {
427 struct ip6ctlparam *ip6cp = (struct ip6ctlparam *)d;
435 ip6cp = (struct ip6ctlparam *)d;
428 m = ip6cp->ip6c_m;
429 ip6 = ip6cp->ip6c_ip6;
430 off = ip6cp->ip6c_off;
436 m = ip6cp->ip6c_m;
437 ip6 = ip6cp->ip6c_ip6;
438 off = ip6cp->ip6c_off;
439 sa6_src = ip6cp->ip6c_src;
431 } else {
432 m = NULL;
433 ip6 = NULL;
440 } else {
441 m = NULL;
442 ip6 = NULL;
443 sa6_src = &sa6_any;
434 }
435
444 }
445
436 /* translate addresses into internal form */
437 sa6 = *(struct sockaddr_in6 *)sa;
438 if (IN6_IS_ADDR_LINKLOCAL(&sa6.sin6_addr) && m && m->m_pkthdr.rcvif)
439 sa6.sin6_addr.s6_addr16[1] = htons(m->m_pkthdr.rcvif->if_index);
440
441 if (ip6) {
442 /*
443 * XXX: We assume that when IPV6 is non NULL,
444 * M and OFF are valid.
445 */
446 if (ip6) {
447 /*
448 * XXX: We assume that when IPV6 is non NULL,
449 * M and OFF are valid.
450 */
446 struct in6_addr s;
447
451
448 /* translate addresses into internal form */
449 memcpy(&s, &ip6->ip6_src, sizeof(s));
450 if (IN6_IS_ADDR_LINKLOCAL(&s))
451 s.s6_addr16[1] = htons(m->m_pkthdr.rcvif->if_index);
452
453 /* check if we can safely examine src and dst ports */
452 /* check if we can safely examine src and dst ports */
454 if (m->m_pkthdr.len < off + sizeof(uh))
453 if (m->m_pkthdr.len < off + sizeof(*uhp))
455 return;
456
454 return;
455
457 if (m->m_len < off + sizeof(uh)) {
458 /*
459 * this should be rare case,
460 * so we compromise on this copy...
461 */
462 m_copydata(m, off, sizeof(uh), (caddr_t)&uh);
463 uhp = &uh;
464 } else
465 uhp = (struct udphdr *)(mtod(m, caddr_t) + off);
466 (void) in6_pcbnotify(&udb, (struct sockaddr *)&sa6,
467 uhp->uh_dport, &s,
468 uhp->uh_sport, cmd, notify);
456 bzero(&uh, sizeof(uh));
457 m_copydata(m, off, sizeof(*uhp), (caddr_t)&uh);
458
459 (void) in6_pcbnotify(&udb, sa, uh.uh_dport, ip6cp->ip6c_src,
460 uh.uh_sport, cmd, notify);
469 } else
461 } else
470 (void) in6_pcbnotify(&udb, (struct sockaddr *)&sa6, 0,
471 &zeroin6_addr, 0, cmd, notify);
462 (void) in6_pcbnotify(&udb, sa, 0, (struct sockaddr *)&sa6_src,
463 0, cmd, notify);
472}
473
474static int
475udp6_getcred(SYSCTL_HANDLER_ARGS)
476{
477 struct xucred xuc;
478 struct sockaddr_in6 addrs[2];
479 struct inpcb *inp;

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

578 int s, error;
579
580 inp = sotoinpcb(so);
581 if (inp == 0)
582 return EINVAL;
583
584 inp->inp_vflag &= ~INP_IPV4;
585 inp->inp_vflag |= INP_IPV6;
464}
465
466static int
467udp6_getcred(SYSCTL_HANDLER_ARGS)
468{
469 struct xucred xuc;
470 struct sockaddr_in6 addrs[2];
471 struct inpcb *inp;

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

570 int s, error;
571
572 inp = sotoinpcb(so);
573 if (inp == 0)
574 return EINVAL;
575
576 inp->inp_vflag &= ~INP_IPV4;
577 inp->inp_vflag |= INP_IPV6;
586 if ((inp->inp_flags & IN6P_BINDV6ONLY) == 0) {
578 if ((inp->inp_flags & IN6P_IPV6_V6ONLY) == 0) {
587 struct sockaddr_in6 *sin6_p;
588
589 sin6_p = (struct sockaddr_in6 *)nam;
590
591 if (IN6_IS_ADDR_UNSPECIFIED(&sin6_p->sin6_addr))
592 inp->inp_vflag |= INP_IPV4;
593 else if (IN6_IS_ADDR_V4MAPPED(&sin6_p->sin6_addr)) {
594 struct sockaddr_in sin;

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

613udp6_connect(struct socket *so, struct sockaddr *nam, struct proc *p)
614{
615 struct inpcb *inp;
616 int s, error;
617
618 inp = sotoinpcb(so);
619 if (inp == 0)
620 return EINVAL;
579 struct sockaddr_in6 *sin6_p;
580
581 sin6_p = (struct sockaddr_in6 *)nam;
582
583 if (IN6_IS_ADDR_UNSPECIFIED(&sin6_p->sin6_addr))
584 inp->inp_vflag |= INP_IPV4;
585 else if (IN6_IS_ADDR_V4MAPPED(&sin6_p->sin6_addr)) {
586 struct sockaddr_in sin;

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

605udp6_connect(struct socket *so, struct sockaddr *nam, struct proc *p)
606{
607 struct inpcb *inp;
608 int s, error;
609
610 inp = sotoinpcb(so);
611 if (inp == 0)
612 return EINVAL;
621 if ((inp->inp_flags & IN6P_BINDV6ONLY) == 0) {
613
614 if ((inp->inp_flags & IN6P_IPV6_V6ONLY) == 0) {
622 struct sockaddr_in6 *sin6_p;
623
624 sin6_p = (struct sockaddr_in6 *)nam;
625 if (IN6_IS_ADDR_V4MAPPED(&sin6_p->sin6_addr)) {
626 struct sockaddr_in sin;
627
628 if (inp->inp_faddr.s_addr != INADDR_ANY)
629 return EISCONN;

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

639 return error;
640 }
641 }
642
643 if (!IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_faddr))
644 return EISCONN;
645 s = splnet();
646 error = in6_pcbconnect(inp, nam, p);
615 struct sockaddr_in6 *sin6_p;
616
617 sin6_p = (struct sockaddr_in6 *)nam;
618 if (IN6_IS_ADDR_V4MAPPED(&sin6_p->sin6_addr)) {
619 struct sockaddr_in sin;
620
621 if (inp->inp_faddr.s_addr != INADDR_ANY)
622 return EISCONN;

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

632 return error;
633 }
634 }
635
636 if (!IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_faddr))
637 return EISCONN;
638 s = splnet();
639 error = in6_pcbconnect(inp, nam, p);
647 if (ip6_auto_flowlabel) {
648 inp->in6p_flowinfo &= ~IPV6_FLOWLABEL_MASK;
649 inp->in6p_flowinfo |=
650 (htonl(ip6_flow_seq++) & IPV6_FLOWLABEL_MASK);
651 }
652 splx(s);
653 if (error == 0) {
640 splx(s);
641 if (error == 0) {
654 inp->inp_vflag &= ~INP_IPV4;
655 inp->inp_vflag |= INP_IPV6;
642 if (ip6_mapped_addr_on) { /* should be non mapped addr */
643 inp->inp_vflag &= ~INP_IPV4;
644 inp->inp_vflag |= INP_IPV6;
645 }
656 soisconnected(so);
657 }
658 return error;
659}
660
661static int
662udp6_detach(struct socket *so)
663{

--- 102 unchanged lines hidden ---
646 soisconnected(so);
647 }
648 return error;
649}
650
651static int
652udp6_detach(struct socket *so)
653{

--- 102 unchanged lines hidden ---