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 --- |