Deleted Added
sdiff udiff text old ( 62573 ) new ( 62587 )
full compact
1/* $FreeBSD: head/sys/netinet6/udp6_usrreq.c 62587 2000-07-04 16:35:15Z itojun $ */
2/* $KAME: udp6_usrreq.c,v 1.11 2000/06/18 06:23:06 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:
11 * 1. Redistributions of source code must retain the above copyright

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

58 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
59 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
60 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
61 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
62 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
63 * SUCH DAMAGE.
64 *
65 * @(#)udp_var.h 8.1 (Berkeley) 6/10/93
66 */
67
68#include "opt_inet.h"
69#include "opt_inet6.h"
70#include "opt_ipsec.h"
71
72#include <sys/param.h>
73#include <sys/kernel.h>
74#include <sys/mbuf.h>
75#include <sys/protosw.h>
76#include <sys/socket.h>
77#include <sys/socketvar.h>

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

89#include <netinet/in.h>
90#include <netinet/in_systm.h>
91#include <netinet/ip.h>
92#include <netinet/in_pcb.h>
93#include <netinet/in_var.h>
94#include <netinet/ip_var.h>
95#include <netinet/udp.h>
96#include <netinet/udp_var.h>
97#include
98#include <netinet6/ip6_var.h>
99#include <netinet6/in6_pcb.h>
100#include
101#include <netinet6/udp6_var.h>
102#include <netinet6/ip6protosw.h>
103
104#ifdef IPSEC
105#include <netinet6/ipsec.h>
106#include <netinet6/ipsec6.h>
107#endif /*IPSEC*/
108

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

401 struct sockaddr *sa;
402 void *d;
403{
404 register struct udphdr *uhp;
405 struct udphdr uh;
406 struct sockaddr_in6 sa6;
407 struct ip6_hdr *ip6;
408 struct mbuf *m;
409 int off = 0;
410 void (*notify) __P((struct inpcb *, int)) = udp_notify;
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) {
427 struct ip6ctlparam *ip6cp = (struct ip6ctlparam *)d;
428 m = ip6cp->ip6c_m;
429 ip6 = ip6cp->ip6c_ip6;
430 off = ip6cp->ip6c_off;
431 } else {
432 m = NULL;
433 ip6 = NULL;
434 }
435
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 struct in6_addr s;

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

456 * so we compromise on this copy...
457 */
458 m_copydata(m, off, sizeof(uh), (caddr_t)&uh);
459 uhp = &uh;
460 } else
461 uhp = (struct udphdr *)(mtod(m, caddr_t) + off);
462 (void) in6_pcbnotify(&udb, (struct sockaddr *)&sa6,
463 uhp->uh_dport, &s,
464 uhp->uh_sport, cmd, notify);
465 } else
466 (void) in6_pcbnotify(&udb, (struct sockaddr *)&sa6, 0,
467 &zeroin6_addr, 0, cmd, notify);
468}
469
470static int
471udp6_getcred(SYSCTL_HANDLER_ARGS)
472{
473 struct sockaddr_in6 addrs[2];
474 struct inpcb *inp;
475 int error, s;
476
477 error = suser(req->p);
478 if (error)
479 return (error);
480
481 if (req->newlen != sizeof(addrs))
482 return (EINVAL);
483 if (req->oldlen != sizeof(struct ucred))
484 return (EINVAL);
485 error = SYSCTL_IN(req, addrs, sizeof(addrs));
486 if (error)
487 return (error);
488 s = splnet();
489 inp = in6_pcblookup_hash(&udbinfo, &addrs[1].sin6_addr,
490 addrs[1].sin6_port,
491 &addrs[0].sin6_addr, addrs[0].sin6_port,
492 1, NULL);

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

501 splx(s);
502 return (error);
503}
504
505SYSCTL_PROC(_net_inet6_udp6, OID_AUTO, getcred, CTLTYPE_OPAQUE|CTLFLAG_RW,
506 0, 0,
507 udp6_getcred, "S,ucred", "Get the ucred of a UDP6 connection");
508
509static int
510udp6_abort(struct socket *so)
511{
512 struct inpcb *inp;
513 int s;
514
515 inp = sotoinpcb(so);
516 if (inp == 0)

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

626 if (error == 0) {
627 inp->inp_vflag |= INP_IPV4;
628 inp->inp_vflag &= ~INP_IPV6;
629 soisconnected(so);
630 }
631 return error;
632 }
633 }
634
635 if (!IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_faddr))
636 return EISCONN;
637 s = splnet();
638 error = in6_pcbconnect(inp, nam, p);
639 if (ip6_auto_flowlabel) {
640 inp->in6p_flowinfo &= ~IPV6_FLOWLABEL_MASK;
641 inp->in6p_flowinfo |=
642 (htonl(ip6_flow_seq++) & IPV6_FLOWLABEL_MASK);
643 }
644 splx(s);
645 if (error == 0) {
646 inp->inp_vflag &= ~INP_IPV4;
647 inp->inp_vflag |= INP_IPV6;
648 soisconnected(so);
649 }
650 return error;
651}

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

693 return 0;
694}
695
696static int
697udp6_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *addr,
698 struct mbuf *control, struct proc *p)
699{
700 struct inpcb *inp;
701 int error = 0;
702
703 inp = sotoinpcb(so);
704 if (inp == 0) {
705 error = EINVAL;
706 goto bad;
707 }
708
709 if (addr) {
710 if (addr->sa_len != sizeof(struct sockaddr_in6)) {
711 error = EINVAL;
712 goto bad;
713 }
714 if (addr->sa_family != AF_INET6) {
715 error = EAFNOSUPPORT;
716 goto bad;
717 }
718 }
719
720 if (ip6_mapped_addr_on) {
721 int hasv4addr;
722 struct sockaddr_in6 *sin6 = 0;
723
724 if (addr == 0)
725 hasv4addr = (inp->inp_vflag & INP_IPV4);
726 else {
727 sin6 = (struct sockaddr_in6 *)addr;
728 hasv4addr = IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)
729 ? 1 : 0;
730 }
731 if (hasv4addr) {
732 struct pr_usrreqs *pru;
733
734 if (sin6)
735 in6_sin6_2_sin_in_sock(addr);
736 pru = inetsw[ip_protox[IPPROTO_UDP]].pr_usrreqs;
737 error = ((*pru->pru_send)(so, flags, m, addr, control,
738 p));
739 /* addr will just be freed in sendit(). */
740 return error;
741 }
742 }
743
744 return udp6_output(inp, m, addr, control, p);
745
746 bad:
747 m_freem(m);
748 return(error);
749}
750
751struct pr_usrreqs udp6_usrreqs = {
752 udp6_abort, pru_accept_notsupp, udp6_attach, udp6_bind, udp6_connect,
753 pru_connect2_notsupp, in6_control, udp6_detach, udp6_disconnect,
754 pru_listen_notsupp, in6_mapped_peeraddr, pru_rcvd_notsupp,
755 pru_rcvoob_notsupp, udp6_send, pru_sense_null, udp_shutdown,
756 in6_mapped_sockaddr, sosend, soreceive, sopoll
757};