annotate packages/net/tcpip/current/src/sys/netinet/udp_usrreq.c @ 2729:74dbf4c3f2e1 after-copyright-change-20090129

Update all copyright banners to reflect FSF ownership; fix and improve licence text.
author jlarmour
date Thu, 29 Jan 2009 17:47:46 +0000
parents e0c0827131d1
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
97
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1 //==========================================================================
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2 //
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
3 // sys/netinet/udp_usrreq.c
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
4 //
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
5 //
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
6 //
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
7 //==========================================================================
2729
74dbf4c3f2e1 Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents: 208
diff changeset
8 // ####BSDALTCOPYRIGHTBEGIN####
74dbf4c3f2e1 Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents: 208
diff changeset
9 // -------------------------------------------
74dbf4c3f2e1 Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents: 208
diff changeset
10 // Portions of this software may have been derived from OpenBSD
74dbf4c3f2e1 Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents: 208
diff changeset
11 // or other sources, and if so are covered by the appropriate copyright
74dbf4c3f2e1 Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents: 208
diff changeset
12 // and license included herein.
74dbf4c3f2e1 Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents: 208
diff changeset
13 // -------------------------------------------
74dbf4c3f2e1 Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents: 208
diff changeset
14 // ####BSDALTCOPYRIGHTEND####
97
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
15 //==========================================================================
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
16 //#####DESCRIPTIONBEGIN####
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
17 //
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
18 // Author(s): gthomas
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
19 // Contributors: gthomas
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
20 // Date: 2000-01-10
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
21 // Purpose:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
22 // Description:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
23 //
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
24 //
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
25 //####DESCRIPTIONEND####
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
26 //
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
27 //==========================================================================
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
28
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
29
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
30 /* $OpenBSD: udp_usrreq.c,v 1.30 1999/12/12 10:59:41 itojun Exp $ */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
31 /* $NetBSD: udp_usrreq.c,v 1.28 1996/03/16 23:54:03 christos Exp $ */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
32
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
33 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
34 * Copyright (c) 1982, 1986, 1988, 1990, 1993
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
35 * The Regents of the University of California. All rights reserved.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
36 *
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
37 * Redistribution and use in source and binary forms, with or without
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
38 * modification, are permitted provided that the following conditions
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
39 * are met:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
40 * 1. Redistributions of source code must retain the above copyright
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
41 * notice, this list of conditions and the following disclaimer.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
42 * 2. Redistributions in binary form must reproduce the above copyright
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
43 * notice, this list of conditions and the following disclaimer in the
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
44 * documentation and/or other materials provided with the distribution.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
45 * 3. All advertising materials mentioning features or use of this software
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
46 * must display the following acknowledgement:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
47 * This product includes software developed by the University of
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
48 * California, Berkeley and its contributors.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
49 * 4. Neither the name of the University nor the names of its contributors
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
50 * may be used to endorse or promote products derived from this software
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
51 * without specific prior written permission.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
52 *
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
53 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
54 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
55 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
56 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
57 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
58 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
59 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
60 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
61 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
62 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
63 * SUCH DAMAGE.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
64 *
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
65 * @(#)udp_usrreq.c 8.4 (Berkeley) 1/21/94
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
66 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
67
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
68 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
69 %%% portions-copyright-nrl-95
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
70 Portions of this software are Copyright 1995-1998 by Randall Atkinson,
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
71 Ronald Lee, Daniel McDonald, Bao Phan, and Chris Winters. All Rights
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
72 Reserved. All rights under this copyright have been assigned to the US
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
73 Naval Research Laboratory (NRL). The NRL Copyright Notice and License
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
74 Agreement Version 1.1 (January 17, 1995) applies to these portions of the
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
75 software.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
76 You should have received a copy of the license with this software. If you
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
77 didn't get a copy, you may request one from <license@ipv6.nrl.navy.mil>.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
78 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
79
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
80 #include <sys/param.h>
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
81 #include <sys/malloc.h>
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
82 #include <sys/mbuf.h>
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
83 #include <sys/protosw.h>
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
84 #include <sys/socket.h>
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
85 #include <sys/socketvar.h>
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
86 #include <sys/errno.h>
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
87 #ifdef __ECOS
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
88 #undef errno
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
89 #endif
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
90 #ifndef __ECOS
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
91 #include <sys/stat.h>
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
92 #include <sys/systm.h>
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
93 #include <sys/proc.h>
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
94
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
95 #include <vm/vm.h>
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
96 #include <sys/sysctl.h>
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
97 #endif
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
98
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
99 #include <net/if.h>
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
100 #include <net/route.h>
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
101
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
102 #include <netinet/in.h>
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
103 #include <netinet/in_systm.h>
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
104 #include <netinet/in_var.h>
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
105 #include <netinet/ip.h>
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
106 #include <netinet/in_pcb.h>
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
107 #include <netinet/ip_var.h>
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
108 #include <netinet/ip_icmp.h>
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
109 #include <netinet/udp.h>
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
110 #include <netinet/udp_var.h>
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
111
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
112 #ifdef IPSEC
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
113 #include <netinet/ip_ipsp.h>
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
114
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
115 extern int check_ipsec_policy __P((struct inpcb *, u_int32_t));
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
116 #endif
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
117
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
118 #include <machine/stdarg.h>
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
119
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
120 #ifdef INET6
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
121 #ifndef INET
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
122 #include <netinet/in.h>
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
123 #endif
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
124 #include <netinet6/ip6.h>
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
125 #include <netinet6/in6_var.h>
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
126 #include <netinet6/ip6_var.h>
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
127 #include <netinet6/icmp6.h>
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
128 #include <netinet6/ip6protosw.h>
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
129
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
130 #ifndef CREATE_IPV6_MAPPED
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
131 #define CREATE_IPV6_MAPPED(a6, a4) \
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
132 do { \
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
133 bzero(&(a6), sizeof(a6)); \
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
134 (a6).s6_addr[10] = (a6).s6_addr[11] = 0xff; \
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
135 *(u_int32_t *)&(a6).s6_addr[12] = (a4); \
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
136 } while (0)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
137 #endif
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
138
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
139 extern int ip6_defhlim;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
140
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
141 #endif /* INET6 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
142
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
143 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
144 * UDP protocol implementation.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
145 * Per RFC 768, August, 1980.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
146 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
147 int udpcksum = 1;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
148
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
149
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
150 static void udp_detach __P((struct inpcb *));
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
151 static void udp_notify __P((struct inpcb *, int));
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
152 static struct mbuf *udp_saveopt __P((caddr_t, int, int));
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
153
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
154 #ifndef UDBHASHSIZE
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
155 #define UDBHASHSIZE 128
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
156 #endif
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
157 int udbhashsize = UDBHASHSIZE;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
158
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
159 /* from in_pcb.c */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
160 extern struct baddynamicports baddynamicports;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
161
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
162 void
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
163 udp_init()
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
164 {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
165
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
166 in_pcbinit(&udbtable, udbhashsize);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
167 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
168
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
169 #if defined(INET6) && !defined(TCP6)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
170 int
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
171 udp6_input(mp, offp, proto)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
172 struct mbuf **mp;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
173 int *offp, proto;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
174 {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
175 struct mbuf *m = *mp;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
176
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
177 #if defined(NFAITH) && 0 < NFAITH
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
178 if (m->m_pkthdr.rcvif) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
179 if (m->m_pkthdr.rcvif->if_type == IFT_FAITH) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
180 /* XXX send icmp6 host/port unreach? */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
181 m_freem(m);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
182 return IPPROTO_DONE;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
183 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
184 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
185 #endif
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
186
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
187 udp_input(m, *offp, proto);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
188 return IPPROTO_DONE;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
189 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
190 #endif
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
191
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
192 void
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
193 #if __STDC__
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
194 udp_input(struct mbuf *m, ...)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
195 #else
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
196 udp_input(m, va_alist)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
197 struct mbuf *m;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
198 va_dcl
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
199 #endif
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
200 {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
201 register struct ip *ip;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
202 register struct udphdr *uh;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
203 register struct inpcb *inp;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
204 struct mbuf *opts = 0;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
205 int len;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
206 struct ip save_ip;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
207 int iphlen;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
208 va_list ap;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
209 u_int16_t savesum;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
210 union {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
211 struct sockaddr sa;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
212 struct sockaddr_in sin;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
213 #ifdef INET6
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
214 struct sockaddr_in6 sin6;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
215 #endif /* INET6 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
216 } srcsa, dstsa;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
217 #ifdef INET6
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
218 struct ip6_hdr *ipv6;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
219 struct sockaddr_in6 src_v4mapped;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
220 #endif /* INET6 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
221 #ifdef IPSEC
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
222 struct tdb *tdb = NULL;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
223 #endif /* IPSEC */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
224
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
225 va_start(ap, m);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
226 iphlen = va_arg(ap, int);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
227 va_end(ap);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
228
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
229 udpstat.udps_ipackets++;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
230
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
231 #ifdef IPSEC
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
232 /* Save the last SA which was used to process the mbuf */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
233 if ((m->m_flags & (M_CONF|M_AUTH)) && m->m_pkthdr.tdbi) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
234 struct tdb_ident *tdbi = m->m_pkthdr.tdbi;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
235 /* XXX gettdb() should really be called at spltdb(). */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
236 /* XXX this is splsoftnet(), currently they are the same. */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
237 tdb = gettdb(tdbi->spi, &tdbi->dst, tdbi->proto);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
238 free(m->m_pkthdr.tdbi, M_TEMP);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
239 m->m_pkthdr.tdbi = NULL;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
240 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
241 #endif /* IPSEC */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
242
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
243 switch (mtod(m, struct ip *)->ip_v) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
244 case 4:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
245 ip = mtod(m, struct ip *);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
246 #ifdef INET6
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
247 ipv6 = NULL;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
248 #endif /* INET6 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
249 srcsa.sa.sa_family = AF_INET;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
250 break;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
251 #ifdef INET6
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
252 case 6:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
253 ip = NULL;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
254 ipv6 = mtod(m, struct ip6_hdr *);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
255 srcsa.sa.sa_family = AF_INET6;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
256 break;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
257 #endif /* INET6 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
258 default:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
259 #ifdef __ECOS
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
260 diag_printf("udp_input: received unknown IP version %d",
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
261 mtod(m, struct ip *)->ip_v);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
262 #else
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
263 printf("udp_input: received unknown IP version %d",
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
264 mtod(m, struct ip *)->ip_v);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
265 #endif
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
266 goto bad;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
267 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
268
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
269 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
270 * Strip IP options, if any; should skip this,
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
271 * make available to user, and use on returned packets,
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
272 * but we don't yet have a way to check the checksum
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
273 * with options still present.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
274 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
275 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
276 * (contd. from above...) Furthermore, we may want to strip options
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
277 * for such things as ICMP errors, where options just get in the way.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
278 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
279 if (ip && iphlen > sizeof (struct ip)) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
280 ip_stripoptions(m, (struct mbuf *)0);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
281 iphlen = sizeof(struct ip);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
282 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
283
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
284 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
285 * Get IP and UDP header together in first mbuf.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
286 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
287 if (m->m_len < iphlen + sizeof(struct udphdr)) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
288 if ((m = m_pullup2(m, iphlen + sizeof(struct udphdr))) == 0) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
289 udpstat.udps_hdrops++;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
290 return;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
291 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
292 #ifdef INET6
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
293 if (ipv6)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
294 ipv6 = mtod(m, struct ip6_hdr *);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
295 else
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
296 #endif /* INET6 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
297 ip = mtod(m, struct ip *);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
298 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
299 uh = (struct udphdr *)(mtod(m, caddr_t) + iphlen);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
300
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
301 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
302 * Make mbuf data length reflect UDP length.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
303 * If not enough data to reflect UDP length, drop.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
304 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
305 len = ntohs((u_int16_t)uh->uh_ulen);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
306 if (m->m_pkthdr.len - iphlen != len) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
307 if (len > (m->m_pkthdr.len - iphlen) ||
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
308 len < sizeof(struct udphdr)) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
309 udpstat.udps_badlen++;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
310 goto bad;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
311 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
312 m_adj(m, len - (m->m_pkthdr.len - iphlen));
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
313 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
314 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
315 * Save a copy of the IP header in case we want restore it
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
316 * for sending an ICMP error message in response.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
317 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
318 if (ip)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
319 save_ip = *ip;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
320
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
321 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
322 * Checksum extended UDP header and data.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
323 * from W.R.Stevens: check incoming udp cksums even if
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
324 * udpcksum is not set.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
325 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
326 savesum = uh->uh_sum;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
327 #ifdef INET6
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
328 if (ipv6) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
329 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
330 * In IPv6, the UDP checksum is ALWAYS used.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
331 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
332 if ((uh->uh_sum = in6_cksum(m, IPPROTO_UDP, iphlen, len))) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
333 udpstat.udps_badsum++;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
334 goto bad;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
335 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
336 } else
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
337 #endif /* INET6 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
338 if (uh->uh_sum) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
339 bzero(((struct ipovly *)ip)->ih_x1,
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
340 sizeof ((struct ipovly *)ip)->ih_x1);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
341 ((struct ipovly *)ip)->ih_len = uh->uh_ulen;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
342 if ((uh->uh_sum = in_cksum(m, len + sizeof (struct ip))) != 0) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
343 udpstat.udps_badsum++;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
344 m_freem(m);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
345 return;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
346 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
347 } else
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
348 udpstat.udps_nosum++;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
349
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
350 switch (srcsa.sa.sa_family) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
351 case AF_INET:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
352 bzero(&srcsa, sizeof(struct sockaddr_in));
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
353 srcsa.sin.sin_len = sizeof(struct sockaddr_in);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
354 srcsa.sin.sin_family = AF_INET;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
355 srcsa.sin.sin_port = uh->uh_sport;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
356 srcsa.sin.sin_addr = ip->ip_src;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
357
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
358 #ifdef INET6
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
359 bzero(&src_v4mapped, sizeof(struct sockaddr_in6));
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
360 src_v4mapped.sin6_len = sizeof(struct sockaddr_in6);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
361 src_v4mapped.sin6_family = AF_INET6;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
362 src_v4mapped.sin6_port = uh->uh_sport;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
363 CREATE_IPV6_MAPPED(src_v4mapped.sin6_addr, ip->ip_src.s_addr);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
364 #endif /* INET6 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
365
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
366 bzero(&dstsa, sizeof(struct sockaddr_in));
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
367 dstsa.sin.sin_len = sizeof(struct sockaddr_in);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
368 dstsa.sin.sin_family = AF_INET;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
369 dstsa.sin.sin_port = uh->uh_dport;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
370 dstsa.sin.sin_addr = ip->ip_dst;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
371 break;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
372 #ifdef INET6
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
373 case AF_INET6:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
374 bzero(&srcsa, sizeof(struct sockaddr_in6));
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
375 srcsa.sin6.sin6_len = sizeof(struct sockaddr_in6);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
376 srcsa.sin6.sin6_family = AF_INET6;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
377 srcsa.sin6.sin6_port = uh->uh_sport;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
378 srcsa.sin6.sin6_flowinfo = htonl(0x0fffffff) & ipv6->ip6_flow;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
379 srcsa.sin6.sin6_addr = ipv6->ip6_src;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
380 if (IN6_IS_SCOPE_LINKLOCAL(&srcsa.sin6.sin6_addr))
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
381 srcsa.sin6.sin6_addr.s6_addr16[1] = 0;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
382 if (m->m_pkthdr.rcvif) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
383 if (IN6_IS_SCOPE_LINKLOCAL(&srcsa.sin6.sin6_addr)) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
384 srcsa.sin6.sin6_scope_id =
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
385 m->m_pkthdr.rcvif->if_index;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
386 } else
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
387 srcsa.sin6.sin6_scope_id = 0;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
388 } else
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
389 srcsa.sin6.sin6_scope_id = 0;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
390
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
391 bzero(&dstsa, sizeof(struct sockaddr_in6));
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
392 dstsa.sin6.sin6_len = sizeof(struct sockaddr_in6);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
393 dstsa.sin6.sin6_family = AF_INET6;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
394 dstsa.sin6.sin6_port = uh->uh_dport;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
395 dstsa.sin6.sin6_addr = ipv6->ip6_dst;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
396 break;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
397 #endif /* INET6 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
398 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
399
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
400 #ifdef INET6
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
401 if ((ipv6 && IN6_IS_ADDR_MULTICAST(&ipv6->ip6_dst)) ||
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
402 (ip && IN_MULTICAST(ip->ip_dst.s_addr)) ||
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
403 (ip && in_broadcast(ip->ip_dst, m->m_pkthdr.rcvif))) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
404 #else /* INET6 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
405 if (IN_MULTICAST(ip->ip_dst.s_addr) ||
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
406 in_broadcast(ip->ip_dst, m->m_pkthdr.rcvif)) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
407 #endif /* INET6 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
408 struct socket *last;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
409 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
410 * Deliver a multicast or broadcast datagram to *all* sockets
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
411 * for which the local and remote addresses and ports match
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
412 * those of the incoming datagram. This allows more than
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
413 * one process to receive multi/broadcasts on the same port.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
414 * (This really ought to be done for unicast datagrams as
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
415 * well, but that would cause problems with existing
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
416 * applications that open both address-specific sockets and
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
417 * a wildcard socket listening to the same port -- they would
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
418 * end up receiving duplicates of every unicast datagram.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
419 * Those applications open the multiple sockets to overcome an
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
420 * inadequacy of the UDP socket interface, but for backwards
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
421 * compatibility we avoid the problem here rather than
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
422 * fixing the interface. Maybe 4.5BSD will remedy this?)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
423 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
424
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
425 iphlen += sizeof(struct udphdr);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
426
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
427 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
428 * Locate pcb(s) for datagram.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
429 * (Algorithm copied from raw_intr().)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
430 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
431 last = NULL;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
432 for (inp = udbtable.inpt_queue.cqh_first;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
433 inp != (struct inpcb *)&udbtable.inpt_queue;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
434 inp = inp->inp_queue.cqe_next) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
435 if (inp->inp_lport != uh->uh_dport)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
436 continue;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
437 #ifdef INET6
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
438 if (ipv6) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
439 if (!(inp->inp_flags & INP_IPV6))
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
440 continue;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
441 if (!IN6_IS_ADDR_UNSPECIFIED(&inp->inp_laddr6))
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
442 if (!IN6_ARE_ADDR_EQUAL(&inp->inp_laddr6,
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
443 &ipv6->ip6_dst))
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
444 continue;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
445 } else
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
446 #endif /* INET6 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
447 if (inp->inp_laddr.s_addr != INADDR_ANY) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
448 if (inp->inp_laddr.s_addr !=
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
449 ip->ip_dst.s_addr)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
450 continue;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
451 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
452 #ifdef INET6
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
453 if (ipv6) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
454 if (!IN6_IS_ADDR_UNSPECIFIED(&inp->inp_faddr6))
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
455 if (!IN6_ARE_ADDR_EQUAL(&inp->inp_faddr6,
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
456 &ipv6->ip6_src) ||
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
457 inp->inp_fport != uh->uh_sport)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
458 continue;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
459 } else
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
460 #endif /* INET6 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
461 if (inp->inp_faddr.s_addr != INADDR_ANY) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
462 if (inp->inp_faddr.s_addr !=
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
463 ip->ip_src.s_addr ||
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
464 inp->inp_fport != uh->uh_sport)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
465 continue;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
466 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
467
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
468 if (last != NULL) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
469 struct mbuf *n;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
470
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
471 if ((n = m_copy(m, 0, M_COPYALL)) != NULL) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
472 opts = NULL;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
473 #ifdef INET6
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
474 if (ipv6 && (inp->inp_flags & IN6P_CONTROLOPTS))
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
475 ip6_savecontrol(inp, &opts, ipv6, n);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
476 #endif /* INET6 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
477 m_adj(n, iphlen);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
478 if (sbappendaddr(&last->so_rcv,
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
479 #ifdef INET6
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
480 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
481 * This cruft is needed in (the rare)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
482 * case I deliver a {multi,broad}cast
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
483 * IPv4 packet to an AF_INET6 socket.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
484 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
485 ((((struct inpcb *)last->so_pcb)->inp_flags
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
486 & INP_IPV6) && ip) ?
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
487 (struct sockaddr *)&src_v4mapped :
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
488 #endif /* INET6 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
489 &srcsa.sa, n, opts) == 0) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
490 m_freem(n);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
491 udpstat.udps_fullsock++;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
492 } else
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
493 sorwakeup(last);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
494 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
495 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
496 last = inp->inp_socket;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
497 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
498 * Don't look for additional matches if this one does
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
499 * not have either the SO_REUSEPORT or SO_REUSEADDR
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
500 * socket options set. This heuristic avoids searching
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
501 * through all pcbs in the common case of a non-shared
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
502 * port. It * assumes that an application will never
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
503 * clear these options after setting them.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
504 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
505 if ((last->so_options&(SO_REUSEPORT|SO_REUSEADDR)) == 0)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
506 break;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
507 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
508
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
509 if (last == NULL) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
510 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
511 * No matching pcb found; discard datagram.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
512 * (No need to send an ICMP Port Unreachable
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
513 * for a broadcast or multicast datgram.)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
514 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
515 udpstat.udps_noportbcast++;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
516 goto bad;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
517 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
518
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
519 opts = NULL;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
520 #ifdef INET6
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
521 if (ipv6 && (inp->inp_flags & IN6P_CONTROLOPTS))
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
522 ip6_savecontrol(inp, &opts, ipv6, m);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
523 #endif /* INET6 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
524 m_adj(m, iphlen);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
525 if (sbappendaddr(&last->so_rcv,
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
526 #ifdef INET6
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
527 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
528 * This cruft is needed in (the rare) case I
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
529 * deliver a {multi,broad}cast IPv4 packet to
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
530 * an AF_INET6 socket.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
531 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
532 ((((struct inpcb *)last->so_pcb)->inp_flags & INP_IPV6) && ip) ?
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
533 (struct sockaddr *)&src_v4mapped :
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
534 #endif /* INET6 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
535 &srcsa.sa, m, opts) == 0) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
536 udpstat.udps_fullsock++;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
537 goto bad;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
538 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
539 sorwakeup(last);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
540 return;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
541 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
542 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
543 * Locate pcb for datagram.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
544 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
545 #ifdef INET6
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
546 if (ipv6)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
547 inp = in6_pcbhashlookup(&udbtable, &ipv6->ip6_src, uh->uh_sport,
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
548 &ipv6->ip6_dst, uh->uh_dport);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
549 else
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
550 #endif /* INET6 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
551 inp = in_pcbhashlookup(&udbtable, ip->ip_src, uh->uh_sport,
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
552 ip->ip_dst, uh->uh_dport);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
553 if (inp == 0) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
554 ++udpstat.udps_pcbhashmiss;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
555 #ifdef INET6
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
556 if (ipv6) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
557 inp = in_pcblookup(&udbtable,
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
558 (struct in_addr *)&(ipv6->ip6_src),
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
559 uh->uh_sport, (struct in_addr *)&(ipv6->ip6_dst),
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
560 uh->uh_dport, INPLOOKUP_WILDCARD | INPLOOKUP_IPV6);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
561 } else
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
562 #endif /* INET6 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
563 inp = in_pcblookup(&udbtable, &ip->ip_src, uh->uh_sport,
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
564 &ip->ip_dst, uh->uh_dport, INPLOOKUP_WILDCARD);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
565 if (inp == 0) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
566 udpstat.udps_noport++;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
567 if (m->m_flags & (M_BCAST | M_MCAST)) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
568 udpstat.udps_noportbcast++;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
569 goto bad;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
570 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
571 #ifdef INET6
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
572 if (ipv6) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
573 icmp6_error(m, ICMP6_DST_UNREACH,
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
574 ICMP6_DST_UNREACH_NOPORT,0);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
575 } else
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
576 #endif /* INET6 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
577 {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
578 *ip = save_ip;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
579 HTONS(ip->ip_len);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
580 HTONS(ip->ip_id);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
581 HTONS(ip->ip_off);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
582 uh->uh_sum = savesum;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
583 icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_PORT,
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
584 0, 0);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
585 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
586 return;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
587 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
588 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
589
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
590 #ifdef IPSEC
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
591 /* Check if this socket requires security for incoming packets */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
592 if ((inp->inp_seclevel[SL_AUTH] >= IPSEC_LEVEL_REQUIRE &&
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
593 !(m->m_flags & M_AUTH)) ||
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
594 (inp->inp_seclevel[SL_ESP_TRANS] >= IPSEC_LEVEL_REQUIRE &&
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
595 !(m->m_flags & M_CONF))) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
596 #ifdef notyet
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
597 #ifdef INET6
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
598 if (ipv6)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
599 ipv6_icmp_error(m, ICMPV6_BLAH, ICMPV6_BLAH, 0);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
600 else
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
601 #endif /* INET6 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
602 icmp_error(m, ICMP_BLAH, ICMP_BLAH, 0, 0);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
603 m = NULL;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
604 #endif /* notyet */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
605 udpstat.udps_nosec++;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
606 goto bad;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
607 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
608 /* Use tdb_bind_out for this inp's outbound communication */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
609 if (tdb)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
610 tdb_add_inp(tdb, inp);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
611 #endif /*IPSEC */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
612
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
613 opts = NULL;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
614 #ifdef INET6
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
615 if (ipv6 && (inp->inp_flags & IN6P_CONTROLOPTS))
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
616 ip6_savecontrol(inp, &opts, ipv6, m);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
617 #endif /* INET6 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
618 if (ip && (inp->inp_flags & INP_CONTROLOPTS)) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
619 struct mbuf **mp = &opts;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
620
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
621 if (inp->inp_flags & INP_RECVDSTADDR) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
622 *mp = udp_saveopt((caddr_t) &ip->ip_dst,
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
623 sizeof(struct in_addr), IP_RECVDSTADDR);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
624 if (*mp)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
625 mp = &(*mp)->m_next;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
626 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
627 #ifdef notyet
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
628 /* options were tossed above */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
629 if (inp->inp_flags & INP_RECVOPTS) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
630 *mp = udp_saveopt((caddr_t) opts_deleted_above,
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
631 sizeof(struct in_addr), IP_RECVOPTS);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
632 if (*mp)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
633 mp = &(*mp)->m_next;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
634 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
635 /* ip_srcroute doesn't do what we want here, need to fix */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
636 if (inp->inp_flags & INP_RECVRETOPTS) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
637 *mp = udp_saveopt((caddr_t) ip_srcroute(),
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
638 sizeof(struct in_addr), IP_RECVRETOPTS);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
639 if (*mp)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
640 mp = &(*mp)->m_next;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
641 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
642 #endif
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
643 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
644 iphlen += sizeof(struct udphdr);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
645 m_adj(m, iphlen);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
646 if (sbappendaddr(&inp->inp_socket->so_rcv,
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
647 #ifdef INET6
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
648 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
649 * This cruft is needed to deliver a IPv4 packet to
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
650 * an AF_INET6 socket.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
651 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
652 ((((struct inpcb *)inp->inp_socket->so_pcb)->inp_flags & INP_IPV6)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
653 && ip) ? (struct sockaddr *)&src_v4mapped :
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
654 #endif /* INET6 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
655 &srcsa.sa, m, opts) == 0) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
656 udpstat.udps_fullsock++;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
657 goto bad;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
658 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
659 sorwakeup(inp->inp_socket);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
660 return;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
661 bad:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
662 m_freem(m);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
663 if (opts)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
664 m_freem(opts);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
665 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
666
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
667 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
668 * Create a "control" mbuf containing the specified data
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
669 * with the specified type for presentation with a datagram.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
670 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
671 struct mbuf *
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
672 udp_saveopt(p, size, type)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
673 caddr_t p;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
674 register int size;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
675 int type;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
676 {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
677 register struct cmsghdr *cp;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
678 struct mbuf *m;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
679
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
680 if ((m = m_get(M_DONTWAIT, MT_CONTROL)) == NULL)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
681 return ((struct mbuf *) NULL);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
682 cp = (struct cmsghdr *) mtod(m, struct cmsghdr *);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
683 bcopy(p, CMSG_DATA(cp), size);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
684 size += sizeof(*cp);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
685 m->m_len = size;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
686 cp->cmsg_len = size;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
687 cp->cmsg_level = IPPROTO_IP;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
688 cp->cmsg_type = type;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
689 return (m);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
690 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
691
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
692 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
693 * Notify a udp user of an asynchronous error;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
694 * just wake up so that he can collect error status.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
695 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
696 static void
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
697 udp_notify(inp, errno)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
698 register struct inpcb *inp;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
699 int errno;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
700 {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
701 inp->inp_socket->so_error = errno;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
702 sorwakeup(inp->inp_socket);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
703 sowwakeup(inp->inp_socket);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
704 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
705
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
706 #if defined(INET6) && !defined(TCP6)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
707 void
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
708 udp6_ctlinput(cmd, sa, d)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
709 int cmd;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
710 struct sockaddr *sa;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
711 void *d;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
712 {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
713 struct sockaddr_in6 sa6;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
714 struct ip6_hdr *ip6;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
715 struct mbuf *m;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
716 int off;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
717
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
718 if (sa == NULL)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
719 return;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
720 if (sa->sa_family != AF_INET6)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
721 return;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
722
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
723 /* decode parameter from icmp6. */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
724 if (d != NULL) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
725 struct ip6ctlparam *ip6cp = (struct ip6ctlparam *)d;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
726 ip6 = ip6cp->ip6c_ip6;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
727 m = ip6cp->ip6c_m;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
728 off = ip6cp->ip6c_off;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
729 } else
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
730 return;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
731
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
732 /* translate addresses into internal form */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
733 sa6 = *(struct sockaddr_in6 *)sa;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
734 if (IN6_IS_ADDR_LINKLOCAL(&sa6.sin6_addr) && m && m->m_pkthdr.rcvif)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
735 sa6.sin6_addr.s6_addr16[1] = htons(m->m_pkthdr.rcvif->if_index);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
736 sa = (struct sockaddr *)&sa6;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
737
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
738 (void)udp_ctlinput(cmd, sa, (void *)ip6);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
739 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
740 #endif
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
741
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
742 void *
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
743 udp_ctlinput(cmd, sa, v)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
744 int cmd;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
745 struct sockaddr *sa;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
746 void *v;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
747 {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
748 register struct ip *ip = v;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
749 register struct udphdr *uh;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
750 extern int inetctlerrmap[];
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
751 void (*notify) __P((struct inpcb *, int)) = udp_notify;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
752 int errno;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
753
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
754 if ((unsigned)cmd >= PRC_NCMDS)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
755 return NULL;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
756 errno = inetctlerrmap[cmd];
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
757 if (PRC_IS_REDIRECT(cmd))
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
758 notify = in_rtchange, ip = 0;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
759 else if (cmd == PRC_HOSTDEAD)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
760 ip = 0;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
761 else if (errno == 0)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
762 return NULL;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
763 if (sa == NULL)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
764 return NULL;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
765 #ifdef INET6
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
766 if (sa->sa_family == AF_INET6) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
767 if (ip) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
768 struct ip6_hdr *ipv6 = (struct ip6_hdr *)ip;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
769
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
770 uh = (struct udphdr *)((caddr_t)ipv6 + sizeof(struct ip6_hdr));
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
771 #if 0 /*XXX*/
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
772 in6_pcbnotify(&udbtable, sa, uh->uh_dport,
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
773 &(ipv6->ip6_src), uh->uh_sport, cmd, udp_notify);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
774 #endif
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
775 } else {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
776 #if 0 /*XXX*/
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
777 in6_pcbnotify(&udbtable, sa, 0,
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
778 (struct in6_addr *)&in6addr_any, 0, cmd, udp_notify);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
779 #endif
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
780 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
781 } else
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
782 #endif /* INET6 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
783 if (ip) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
784 uh = (struct udphdr *)((caddr_t)ip + (ip->ip_hl << 2));
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
785 in_pcbnotify(&udbtable, sa, uh->uh_dport, ip->ip_src,
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
786 uh->uh_sport, errno, notify);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
787 } else
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
788 in_pcbnotifyall(&udbtable, sa, errno, notify);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
789 return NULL;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
790 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
791
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
792 int
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
793 #if __STDC__
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
794 udp_output(struct mbuf *m, ...)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
795 #else
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
796 udp_output(m, va_alist)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
797 struct mbuf *m;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
798 va_dcl
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
799 #endif
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
800 {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
801 register struct inpcb *inp;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
802 struct mbuf *addr, *control;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
803 register struct udpiphdr *ui;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
804 register int len = m->m_pkthdr.len;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
805 struct in_addr laddr;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
806 int s = 0, error = 0;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
807 va_list ap;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
808 #ifdef INET6
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
809 register struct in6_addr laddr6;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
810 int v6packet = 0;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
811 struct sockaddr_in6 *sin6 = NULL;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
812 struct ip6_pktopts opt, *stickyopt = NULL;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
813 #endif /* INET6 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
814 int pcbflags = 0;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
815
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
816 va_start(ap, m);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
817 inp = va_arg(ap, struct inpcb *);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
818 addr = va_arg(ap, struct mbuf *);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
819 control = va_arg(ap, struct mbuf *);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
820 va_end(ap);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
821
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
822 #ifdef INET6
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
823 v6packet = ((inp->inp_flags & INP_IPV6) &&
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
824 !(inp->inp_flags & INP_IPV6_MAPPED));
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
825 #endif
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
826
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
827 #ifdef INET6
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
828 stickyopt = inp->inp_outputopts6;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
829 if (control && v6packet) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
830 error = ip6_setpktoptions(control, &opt,
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
831 ((inp->inp_socket->so_state & SS_PRIV) != 0));
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
832 if (error != 0)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
833 goto release;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
834 inp->inp_outputopts6 = &opt;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
835 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
836 #endif
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
837
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
838 if (addr) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
839 #ifdef INET6
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
840 sin6 = mtod(addr, struct sockaddr_in6 *);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
841 #endif
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
842
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
843 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
844 * Save current PCB flags because they may change during
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
845 * temporary connection, particularly the INP_IPV6_UNDEC
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
846 * flag.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
847 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
848 pcbflags = inp->inp_flags;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
849
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
850 #ifdef INET6
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
851 if (inp->inp_flags & INP_IPV6)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
852 laddr6 = inp->inp_laddr6;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
853 else
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
854 #endif /* INET6 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
855 laddr = inp->inp_laddr;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
856 #ifdef INET6
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
857 if (((inp->inp_flags & INP_IPV6) &&
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
858 !IN6_IS_ADDR_UNSPECIFIED(&inp->inp_faddr6)) ||
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
859 (inp->inp_faddr.s_addr != INADDR_ANY))
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
860 #else /* INET6 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
861 if (inp->inp_faddr.s_addr != INADDR_ANY)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
862 #endif /* INET6 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
863 {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
864 error = EISCONN;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
865 goto release;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
866 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
867 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
868 * Must block input while temporarily connected.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
869 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
870 s = splsoftnet();
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
871 error = in_pcbconnect(inp, addr);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
872 if (error) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
873 splx(s);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
874 goto release;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
875 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
876 } else {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
877 #ifdef INET6
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
878 if (((inp->inp_flags & INP_IPV6) &&
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
879 IN6_IS_ADDR_UNSPECIFIED(&inp->inp_faddr6)) ||
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
880 (inp->inp_faddr.s_addr == INADDR_ANY))
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
881 #else /* INET6 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
882 if (inp->inp_faddr.s_addr == INADDR_ANY)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
883 #endif /* INET6 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
884 {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
885 error = ENOTCONN;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
886 goto release;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
887 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
888 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
889 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
890 * Calculate data length and get a mbuf
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
891 * for UDP and IP headers.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
892 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
893 #ifdef INET6
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
894 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
895 * Handles IPv4-mapped IPv6 address because temporary connect sets
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
896 * the right flag.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
897 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
898 M_PREPEND(m, v6packet ? (sizeof(struct udphdr) +
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
899 sizeof(struct ip6_hdr)) : sizeof(struct udpiphdr), M_DONTWAIT);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
900 #else /* INET6 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
901 M_PREPEND(m, sizeof(struct udpiphdr), M_DONTWAIT);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
902 #endif /* INET6 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
903 if (m == 0) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
904 error = ENOBUFS;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
905 goto bail;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
906 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
907
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
908 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
909 * Compute the packet length of the IP header, and
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
910 * punt if the length looks bogus.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
911 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
912 if ((len + sizeof(struct udpiphdr)) > IP_MAXPACKET) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
913 error = EMSGSIZE;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
914 goto release;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
915 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
916
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
917 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
918 * Fill in mbuf with extended UDP header
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
919 * and addresses and length put into network format.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
920 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
921 #ifdef INET6
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
922 if (v6packet) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
923 struct ip6_hdr *ipv6 = mtod(m, struct ip6_hdr *);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
924 struct udphdr *uh = (struct udphdr *)(mtod(m, caddr_t) +
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
925 sizeof(struct ip6_hdr));
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
926 int payload = sizeof(struct ip6_hdr);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
927 struct in6_addr *faddr;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
928 struct in6_addr *laddr;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
929 struct ifnet *oifp = NULL;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
930
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
931 ipv6->ip6_flow = htonl(0x60000000) |
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
932 (inp->inp_ipv6.ip6_flow & htonl(0x0fffffff));
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
933
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
934 ipv6->ip6_nxt = IPPROTO_UDP;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
935 ipv6->ip6_dst = inp->inp_faddr6;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
936 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
937 * If the scope of the destination is link-local,
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
938 * embed the interface
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
939 * index in the address.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
940 *
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
941 * XXX advanced-api value overrides sin6_scope_id
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
942 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
943 faddr = &ipv6->ip6_dst;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
944 if (IN6_IS_ADDR_LINKLOCAL(faddr) ||
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
945 IN6_IS_ADDR_MC_LINKLOCAL(faddr)) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
946 struct ip6_pktopts *optp = inp->inp_outputopts6;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
947 struct in6_pktinfo *pi = NULL;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
948 struct ip6_moptions *mopt = NULL;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
949
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
950 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
951 * XXX Boundary check is assumed to be already done in
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
952 * ip6_setpktoptions().
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
953 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
954 if (optp && (pi = optp->ip6po_pktinfo) &&
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
955 pi->ipi6_ifindex) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
956 faddr->s6_addr16[1] = htons(pi->ipi6_ifindex);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
957 oifp = ifindex2ifnet[pi->ipi6_ifindex];
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
958 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
959 else if (IN6_IS_ADDR_MULTICAST(faddr) &&
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
960 (mopt = inp->inp_moptions6) &&
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
961 mopt->im6o_multicast_ifp) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
962 oifp = mopt->im6o_multicast_ifp;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
963 faddr->s6_addr16[1] = oifp->if_index;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
964 } else if (sin6 && sin6->sin6_scope_id) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
965 /* boundary check */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
966 if (sin6->sin6_scope_id < 0
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
967 || if_index < sin6->sin6_scope_id) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
968 error = ENXIO; /* XXX EINVAL? */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
969 goto release;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
970 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
971 /* XXX */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
972 faddr->s6_addr16[1] =
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
973 htons(sin6->sin6_scope_id & 0xffff);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
974 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
975 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
976 ipv6->ip6_hlim = in6_selecthlim(inp, oifp);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
977 if (sin6) { /*XXX*/
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
978 laddr = in6_selectsrc(sin6, inp->inp_outputopts6,
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
979 inp->inp_moptions6,
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
980 &inp->inp_route6,
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
981 &inp->inp_laddr6, &error);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
982 if (laddr == NULL) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
983 if (error == 0)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
984 error = EADDRNOTAVAIL;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
985 goto release;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
986 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
987 } else
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
988 laddr = &inp->inp_laddr6;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
989
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
990 ipv6->ip6_src = *laddr;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
991
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
992 ipv6->ip6_plen = (u_short)len + sizeof(struct udphdr);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
993
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
994 uh->uh_sport = inp->inp_lport;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
995 uh->uh_dport = inp->inp_fport;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
996 uh->uh_ulen = htons(ipv6->ip6_plen);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
997 uh->uh_sum = 0;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
998
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
999 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1000 * Always calculate udp checksum for IPv6 datagrams
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1001 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1002 if (!(uh->uh_sum = in6_cksum(m, IPPROTO_UDP,
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1003 payload, len + sizeof(struct udphdr))))
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1004 uh->uh_sum = 0xffff;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1005
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1006 error = ip6_output(m, inp->inp_outputopts6, &inp->inp_route6,
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1007 inp->inp_socket->so_options & SO_DONTROUTE,
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1008 (inp->inp_flags & INP_IPV6_MCAST)?inp->inp_moptions6:NULL,
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1009 NULL);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1010 } else
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1011 #endif /* INET6 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1012 {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1013 ui = mtod(m, struct udpiphdr *);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1014 bzero(ui->ui_x1, sizeof ui->ui_x1);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1015 ui->ui_pr = IPPROTO_UDP;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1016 ui->ui_len = htons((u_int16_t)len + sizeof (struct udphdr));
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1017 ui->ui_src = inp->inp_laddr;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1018 ui->ui_dst = inp->inp_faddr;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1019 ui->ui_sport = inp->inp_lport;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1020 ui->ui_dport = inp->inp_fport;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1021 ui->ui_ulen = ui->ui_len;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1022
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1023 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1024 * Stuff checksum and output datagram.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1025 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1026
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1027 ui->ui_sum = 0;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1028 if (udpcksum) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1029 if ((ui->ui_sum = in_cksum(m, sizeof (struct udpiphdr) +
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1030 len)) == 0)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1031 ui->ui_sum = 0xffff;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1032 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1033 ((struct ip *)ui)->ip_len = sizeof (struct udpiphdr) + len;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1034 #ifdef INET6
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1035 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1036 * For now, we use the default values for ttl and tos for
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1037 * v4 packets sent using a v6 pcb. We probably want to
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1038 * later allow v4 setsockopt operations on a v6 socket to
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1039 * modify the ttl and tos for v4 packets sent using
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1040 * the mapped address format. We really ought to
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1041 * save the v4 ttl and v6 hoplimit in separate places
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1042 * instead of craming both in the inp_hu union.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1043 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1044 if (inp->inp_flags & INP_IPV6) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1045 ((struct ip *)ui)->ip_ttl = ip_defttl;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1046 ((struct ip *)ui)->ip_tos = 0;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1047 } else
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1048 #endif /* INET6 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1049 {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1050 ((struct ip *)ui)->ip_ttl = inp->inp_ip.ip_ttl;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1051 ((struct ip *)ui)->ip_tos = inp->inp_ip.ip_tos;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1052 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1053
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1054 udpstat.udps_opackets++;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1055 #ifdef INET6
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1056 if (inp->inp_flags & INP_IPV6_MCAST) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1057 error = ip_output(m, inp->inp_options, &inp->inp_route,
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1058 inp->inp_socket->so_options &
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1059 (SO_DONTROUTE | SO_BROADCAST),
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1060 NULL, NULL, inp->inp_socket);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1061 } else
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1062 #endif /* INET6 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1063 {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1064 error = ip_output(m, inp->inp_options, &inp->inp_route,
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1065 inp->inp_socket->so_options &
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1066 (SO_DONTROUTE | SO_BROADCAST),
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1067 inp->inp_moptions, inp, NULL);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1068 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1069 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1070
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1071 bail:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1072 if (addr) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1073 in_pcbdisconnect(inp);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1074 inp->inp_flags = pcbflags;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1075 #ifdef INET6
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1076 if (inp->inp_flags & INP_IPV6)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1077 inp->inp_laddr6 = laddr6;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1078 else
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1079 #endif
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1080 inp->inp_laddr = laddr;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1081 splx(s);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1082 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1083 if (control) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1084 #ifdef INET6
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1085 if (v6packet)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1086 inp->inp_outputopts6 = stickyopt;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1087 #endif
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1088 m_freem(control);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1089 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1090 return (error);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1091
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1092 release:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1093 m_freem(m);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1094 if (control) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1095 #ifdef INET6
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1096 if (v6packet)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1097 inp->inp_outputopts6 = stickyopt;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1098 #endif
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1099 m_freem(control);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1100 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1101 return (error);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1102 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1103
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1104 u_int udp_sendspace = 9216; /* really max datagram size */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1105 u_int udp_recvspace = 40 * (1024 + sizeof(struct sockaddr_in));
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1106 /* 40 1K datagrams */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1107
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1108 #if defined(INET6) && !defined(TCP6)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1109 /*ARGSUSED*/
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1110 int
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1111 udp6_usrreq(so, req, m, addr, control, p)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1112 struct socket *so;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1113 int req;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1114 struct mbuf *m, *addr, *control;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1115 struct proc *p;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1116 {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1117 return udp_usrreq(so, req, m, addr, control);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1118 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1119 #endif
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1120
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1121 /*ARGSUSED*/
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1122 int
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1123 udp_usrreq(so, req, m, addr, control)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1124 struct socket *so;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1125 int req;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1126 struct mbuf *m, *addr, *control;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1127 {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1128 struct inpcb *inp = sotoinpcb(so);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1129 int error = 0;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1130 int s;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1131
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1132 if (req == PRU_CONTROL) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1133 #ifdef INET6
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1134 if (inp->inp_flags & INP_IPV6)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1135 return (in6_control(so, (u_long)m, (caddr_t)addr,
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1136 (struct ifnet *)control, 0));
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1137 else
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1138 #endif /* INET6 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1139 return (in_control(so, (u_long)m, (caddr_t)addr,
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1140 (struct ifnet *)control));
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1141 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1142 if (inp == NULL && req != PRU_ATTACH) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1143 error = EINVAL;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1144 goto release;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1145 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1146 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1147 * Note: need to block udp_input while changing
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1148 * the udp pcb queue and/or pcb addresses.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1149 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1150 switch (req) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1151
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1152 case PRU_ATTACH:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1153 if (inp != NULL) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1154 error = EINVAL;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1155 break;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1156 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1157 s = splsoftnet();
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1158 error = in_pcballoc(so, &udbtable);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1159 splx(s);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1160 if (error)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1161 break;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1162 error = soreserve(so, udp_sendspace, udp_recvspace);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1163 if (error)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1164 break;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1165 #ifdef INET6
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1166 if (((struct inpcb *)so->so_pcb)->inp_flags & INP_IPV6)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1167 ((struct inpcb *) so->so_pcb)->inp_ipv6.ip6_hlim =
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1168 ip6_defhlim;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1169 else
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1170 #endif /* INET6 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1171 ((struct inpcb *) so->so_pcb)->inp_ip.ip_ttl = ip_defttl;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1172 break;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1173
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1174 case PRU_DETACH:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1175 udp_detach(inp);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1176 break;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1177
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1178 case PRU_BIND:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1179 s = splsoftnet();
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1180 #ifdef INET6
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1181 if (inp->inp_flags & INP_IPV6)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1182 error = in6_pcbbind(inp, addr);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1183 else
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1184 #endif
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1185 error = in_pcbbind(inp, addr);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1186 splx(s);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1187 break;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1188
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1189 case PRU_LISTEN:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1190 error = EOPNOTSUPP;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1191 break;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1192
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1193 case PRU_CONNECT:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1194 #ifdef INET6
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1195 if (inp->inp_flags & INP_IPV6) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1196 if (!IN6_IS_ADDR_UNSPECIFIED(&inp->inp_faddr6)) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1197 error = EISCONN;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1198 break;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1199 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1200 s = splsoftnet();
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1201 error = in6_pcbconnect(inp, addr);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1202 splx(s);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1203 } else
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1204 #endif /* INET6 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1205 {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1206 if (inp->inp_faddr.s_addr != INADDR_ANY) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1207 error = EISCONN;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1208 break;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1209 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1210 s = splsoftnet();
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1211 error = in_pcbconnect(inp, addr);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1212 splx(s);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1213 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1214
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1215 if (error == 0)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1216 soisconnected(so);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1217 break;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1218
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1219 case PRU_CONNECT2:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1220 error = EOPNOTSUPP;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1221 break;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1222
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1223 case PRU_ACCEPT:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1224 error = EOPNOTSUPP;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1225 break;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1226
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1227 case PRU_DISCONNECT:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1228 #ifdef INET6
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1229 if (inp->inp_flags & INP_IPV6) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1230 if (IN6_IS_ADDR_UNSPECIFIED(&inp->inp_faddr6)) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1231 error = ENOTCONN;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1232 break;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1233 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1234 } else
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1235 #endif /* INET6 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1236 if (inp->inp_faddr.s_addr == INADDR_ANY) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1237 error = ENOTCONN;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1238 break;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1239 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1240
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1241 s = splsoftnet();
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1242 in_pcbdisconnect(inp);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1243 #ifdef INET6
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1244 if (inp->inp_flags & INP_IPV6)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1245 inp->inp_laddr6 = in6addr_any;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1246 else
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1247 #endif /* INET6 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1248 inp->inp_laddr.s_addr = INADDR_ANY;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1249
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1250 splx(s);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1251 so->so_state &= ~SS_ISCONNECTED; /* XXX */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1252 break;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1253
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1254 case PRU_SHUTDOWN:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1255 socantsendmore(so);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1256 break;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1257
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1258 case PRU_SEND:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1259 #ifdef IPSEC
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1260 error = check_ipsec_policy(inp,0);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1261 if (error)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1262 return (error);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1263 #endif
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1264 return (udp_output(m, inp, addr, control));
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1265
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1266 case PRU_ABORT:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1267 soisdisconnected(so);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1268 udp_detach(inp);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1269 break;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1270
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1271 case PRU_SOCKADDR:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1272 #ifdef INET6
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1273 if (inp->inp_flags & INP_IPV6)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1274 in6_setsockaddr(inp, addr);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1275 else
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1276 #endif /* INET6 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1277 in_setsockaddr(inp, addr);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1278 break;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1279
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1280 case PRU_PEERADDR:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1281 #ifdef INET6
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1282 if (inp->inp_flags & INP_IPV6)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1283 in6_setpeeraddr(inp, addr);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1284 else
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1285 #endif /* INET6 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1286 in_setpeeraddr(inp, addr);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1287 break;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1288
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1289 case PRU_SENSE:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1290 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1291 * stat: don't bother with a blocksize.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1292 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1293 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1294 * Perhaps Path MTU might be returned for a connected
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1295 * UDP socket in this case.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1296 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1297 return (0);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1298
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1299 case PRU_SENDOOB:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1300 case PRU_FASTTIMO:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1301 case PRU_SLOWTIMO:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1302 case PRU_PROTORCV:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1303 case PRU_PROTOSEND:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1304 error = EOPNOTSUPP;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1305 break;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1306
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1307 case PRU_RCVD:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1308 case PRU_RCVOOB:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1309 return (EOPNOTSUPP); /* do not free mbuf's */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1310
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1311 default:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1312 panic("udp_usrreq");
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1313 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1314
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1315 release:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1316 if (control) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1317 #ifdef __ECOS
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1318 diag_printf("udp control data unexpectedly retained\n");
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1319 #else
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1320 printf("udp control data unexpectedly retained\n");
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1321 #endif
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1322 m_freem(control);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1323 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1324 if (m)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1325 m_freem(m);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1326 return (error);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1327 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1328
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1329 static void
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1330 udp_detach(inp)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1331 struct inpcb *inp;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1332 {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1333 int s = splsoftnet();
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1334
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1335 in_pcbdetach(inp);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1336 splx(s);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1337 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1338
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1339 #ifdef CYGPKG_NET_SYSCTL
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1340 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1341 * Sysctl for udp variables.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1342 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1343 int
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1344 udp_sysctl(name, namelen, oldp, oldlenp, newp, newlen)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1345 int *name;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1346 u_int namelen;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1347 void *oldp;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1348 size_t *oldlenp;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1349 void *newp;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1350 size_t newlen;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1351 {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1352 /* All sysctl names at this level are terminal. */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1353 if (namelen != 1)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1354 return (ENOTDIR);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1355
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1356 switch (name[0]) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1357 case UDPCTL_CHECKSUM:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1358 return (sysctl_int(oldp, oldlenp, newp, newlen, &udpcksum));
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1359 case UDPCTL_BADDYNAMIC:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1360 return (sysctl_struct(oldp, oldlenp, newp, newlen,
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1361 baddynamicports.udp, sizeof(baddynamicports.udp)));
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1362 case UDPCTL_RECVSPACE:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1363 return (sysctl_int(oldp, oldlenp, newp, newlen,&udp_recvspace));
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1364 case UDPCTL_SENDSPACE:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1365 return (sysctl_int(oldp, oldlenp, newp, newlen,&udp_sendspace));
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1366 default:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1367 return (ENOPROTOOPT);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1368 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1369 /* NOTREACHED */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1370 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1371 #endif // CYGPKG_NET_SYSCTL