annotate packages/net/tcpip/current/src/sys/netinet/ip_output.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/ip_output.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: ip_output.c,v 1.57 1999/12/10 08:55:23 angelos Exp $ */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
31 /* $NetBSD: ip_output.c,v 1.28 1996/02/13 23:43:07 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 * @(#)ip_output.c 8.3 (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 #include <sys/param.h>
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
69 #include <sys/malloc.h>
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
70 #include <sys/mbuf.h>
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
71 #include <sys/errno.h>
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
72 #include <sys/protosw.h>
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
73 #include <sys/socket.h>
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
74 #include <sys/socketvar.h>
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
75 #ifndef __ECOS
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
76 #include <sys/systm.h>
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
77 #endif
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
78 #include <sys/kernel.h>
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
79 #ifndef __ECOS
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
80 #include <sys/proc.h>
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
81
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
82 #include <vm/vm.h>
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
83 #include <sys/proc.h>
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
84 #endif
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
85
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
86 #include <net/if.h>
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
87 #include <net/route.h>
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
88
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
89 #include <netinet/in.h>
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
90 #include <netinet/in_systm.h>
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
91 #include <netinet/ip.h>
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
92 #include <netinet/in_pcb.h>
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
93 #include <netinet/in_var.h>
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
94 #include <netinet/ip_var.h>
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
95
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
96 #ifdef vax
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
97 #include <machine/mtpr.h>
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
98 #endif
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
99
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
100 #include <machine/stdarg.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 #ifdef IPSEC
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
103 #include <netinet/ip_ah.h>
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
104 #include <netinet/ip_esp.h>
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
105 #include <netinet/udp.h>
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
106 #include <netinet/tcp.h>
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
107 #include <net/pfkeyv2.h>
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
108
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
109 #ifdef ENCDEBUG
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
110 #define DPRINTF(x) do { if (encdebug) printf x ; } while (0)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
111 #else
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
112 #define DPRINTF(x)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
113 #endif
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 #ifndef offsetof
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
116 #define offsetof(s, e) ((int)&((s *)0)->e)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
117 #endif
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
118
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
119 extern u_int8_t get_sa_require __P((struct inpcb *));
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
120
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
121 #endif /* IPSEC */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
122
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
123 static struct mbuf *ip_insertoptions __P((struct mbuf *, struct mbuf *, int *));
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
124 static void ip_mloopback
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
125 __P((struct ifnet *, struct mbuf *, struct sockaddr_in *));
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
126 #if defined(IPFILTER) || defined(IPFILTER_LKM)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
127 int (*fr_checkp) __P((struct ip *, int, struct ifnet *, int, struct mbuf **));
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
128 #endif
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 #ifdef IPSEC
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
131 extern int ipsec_auth_default_level;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
132 extern int ipsec_esp_trans_default_level;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
133 extern int ipsec_esp_network_default_level;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
134
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
135 extern int pfkeyv2_acquire(struct tdb *, int);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
136 #endif
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
137
208
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents: 97
diff changeset
138 #ifndef RAMDOM_IP_ID
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents: 97
diff changeset
139 u_short ip_id;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents: 97
diff changeset
140 #endif
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents: 97
diff changeset
141
97
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 * IP output. The packet in mbuf chain m contains a skeletal IP
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
144 * header (with len, off, ttl, proto, tos, src, dst).
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
145 * The mbuf chain containing the packet will be freed.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
146 * The mbuf opt, if present, will not be freed.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
147 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
148 int
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
149 #if __STDC__
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
150 ip_output(struct mbuf *m0, ...)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
151 #else
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
152 ip_output(m0, va_alist)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
153 struct mbuf *m0;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
154 va_dcl
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
155 #endif
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
156 {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
157 register struct ip *ip, *mhip;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
158 register struct ifnet *ifp;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
159 register struct mbuf *m = m0;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
160 register int hlen = sizeof (struct ip);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
161 int len, off, error = 0;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
162 struct route iproute;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
163 struct sockaddr_in *dst;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
164 struct in_ifaddr *ia;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
165 struct mbuf *opt;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
166 struct route *ro;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
167 int flags;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
168 struct ip_moptions *imo;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
169 va_list ap;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
170 #ifdef IPSEC
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
171 union sockaddr_union sunion;
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 struct udphdr *udp;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
174 struct tcphdr *tcp;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
175 struct inpcb *inp;
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 struct route_enc re0, *re = &re0;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
178 struct sockaddr_encap *ddst, *gw;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
179 u_int8_t sa_require, sa_have = 0;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
180 struct tdb *tdb, *t;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
181 int s, ip6flag;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
182
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
183 #ifdef INET6
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
184 struct ip6_hdr *ip6;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
185 #endif /* INET6 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
186 #endif /* IPSEC */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
187
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
188 va_start(ap, m0);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
189 opt = va_arg(ap, struct mbuf *);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
190 ro = va_arg(ap, struct route *);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
191 flags = va_arg(ap, int);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
192 imo = va_arg(ap, struct ip_moptions *);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
193 #ifdef IPSEC
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
194 inp = va_arg(ap, struct inpcb *);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
195 #endif /* IPSEC */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
196 va_end(ap);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
197
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
198 #ifdef DIAGNOSTIC
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
199 if ((m->m_flags & M_PKTHDR) == 0)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
200 panic("ip_output no HDR");
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
201 #endif
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
202 if (opt) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
203 m = ip_insertoptions(m, opt, &len);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
204 hlen = len;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
205 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
206 ip = mtod(m, struct ip *);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
207 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
208 * Fill in IP header.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
209 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
210 if ((flags & (IP_FORWARDING|IP_RAWOUTPUT)) == 0) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
211 ip->ip_v = IPVERSION;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
212 ip->ip_off &= IP_DF;
208
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents: 97
diff changeset
213 #ifdef RANDOM_IP_ID
97
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
214 ip->ip_id = ip_randomid();
208
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents: 97
diff changeset
215 #else
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents: 97
diff changeset
216 ip->ip_id = htons(ip_id++);
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents: 97
diff changeset
217 #endif
97
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
218 ip->ip_hl = hlen >> 2;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
219 ipstat.ips_localout++;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
220 } else {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
221 hlen = ip->ip_hl << 2;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
222 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
223
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 * Route packet.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
226 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
227 if (ro == 0) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
228 ro = &iproute;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
229 bzero((caddr_t)ro, sizeof (*ro));
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 dst = satosin(&ro->ro_dst);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
232 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
233 * If there is a cached route,
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
234 * check that it is to the same destination
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
235 * and is still up. If not, free it and try again.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
236 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
237 if (ro->ro_rt && ((ro->ro_rt->rt_flags & RTF_UP) == 0 ||
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
238 dst->sin_addr.s_addr != ip->ip_dst.s_addr)) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
239 RTFREE(ro->ro_rt);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
240 ro->ro_rt = (struct rtentry *)0;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
241 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
242 if (ro->ro_rt == 0) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
243 dst->sin_family = AF_INET;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
244 dst->sin_len = sizeof(*dst);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
245 dst->sin_addr = ip->ip_dst;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
246 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
247 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
248 * If routing to interface only,
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
249 * short circuit routing lookup.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
250 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
251 if (flags & IP_ROUTETOIF) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
252 if ((ia = ifatoia(ifa_ifwithdstaddr(sintosa(dst)))) == 0 &&
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
253 (ia = ifatoia(ifa_ifwithnet(sintosa(dst)))) == 0) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
254 ipstat.ips_noroute++;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
255 error = ENETUNREACH;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
256 goto bad;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
257 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
258 ifp = ia->ia_ifp;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
259 ip->ip_ttl = 1;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
260 } else {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
261 if (ro->ro_rt == 0)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
262 rtalloc(ro);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
263 if (ro->ro_rt == 0) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
264 ipstat.ips_noroute++;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
265 error = EHOSTUNREACH;
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 ia = ifatoia(ro->ro_rt->rt_ifa);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
269 ifp = ro->ro_rt->rt_ifp;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
270 ro->ro_rt->rt_use++;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
271 if (ro->ro_rt->rt_flags & RTF_GATEWAY)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
272 dst = satosin(ro->ro_rt->rt_gateway);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
273 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
274 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
275 struct in_multi *inm;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
276
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
277 m->m_flags |= M_MCAST;
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 * IP destination address is multicast. Make sure "dst"
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
280 * still points to the address in "ro". (It may have been
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
281 * changed to point to a gateway address, above.)
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 dst = satosin(&ro->ro_dst);
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 * See if the caller provided any multicast options
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 (imo != NULL) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
288 ip->ip_ttl = imo->imo_multicast_ttl;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
289 if (imo->imo_multicast_ifp != NULL)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
290 ifp = imo->imo_multicast_ifp;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
291 } else
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
292 ip->ip_ttl = IP_DEFAULT_MULTICAST_TTL;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
293 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
294 * Confirm that the outgoing interface supports multicast.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
295 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
296 if ((ifp->if_flags & IFF_MULTICAST) == 0) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
297 ipstat.ips_noroute++;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
298 error = ENETUNREACH;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
299 goto bad;
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 * If source address not specified yet, use address
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
303 * of outgoing interface.
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 if (ip->ip_src.s_addr == INADDR_ANY) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
306 register struct in_ifaddr *ia;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
307
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
308 for (ia = in_ifaddr.tqh_first; ia; ia = ia->ia_list.tqe_next)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
309 if (ia->ia_ifp == ifp) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
310 ip->ip_src = ia->ia_addr.sin_addr;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
311 break;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
312 }
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 IN_LOOKUP_MULTI(ip->ip_dst, ifp, inm);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
316 if (inm != NULL &&
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
317 (imo == NULL || imo->imo_multicast_loop)) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
318 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
319 * If we belong to the destination multicast group
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
320 * on the outgoing interface, and the caller did not
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
321 * forbid loopback, loop back a copy.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
322 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
323 ip_mloopback(ifp, m, dst);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
324 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
325 #ifdef MROUTING
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
326 else {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
327 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
328 * If we are acting as a multicast router, perform
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
329 * multicast forwarding as if the packet had just
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
330 * arrived on the interface to which we are about
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
331 * to send. The multicast forwarding function
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
332 * recursively calls this function, using the
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
333 * IP_FORWARDING flag to prevent infinite recursion.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
334 *
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
335 * Multicasts that are looped back by ip_mloopback(),
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
336 * above, will be forwarded by the ip_input() routine,
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
337 * if necessary.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
338 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
339 extern struct socket *ip_mrouter;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
340
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
341 if (ip_mrouter && (flags & IP_FORWARDING) == 0) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
342 if (ip_mforward(m, ifp) != 0) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
343 m_freem(m);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
344 goto done;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
345 }
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 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
348 #endif
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 * Multicasts with a time-to-live of zero may be looped-
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
351 * back, above, but must not be transmitted on a network.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
352 * Also, multicasts addressed to the loopback interface
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
353 * are not sent -- the above call to ip_mloopback() will
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
354 * loop back a copy if this host actually belongs to the
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
355 * destination group on the loopback interface.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
356 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
357 if (ip->ip_ttl == 0 || (ifp->if_flags & IFF_LOOPBACK) != 0) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
358 m_freem(m);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
359 goto done;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
360 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
361
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
362 goto sendit;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
363 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
364 #ifndef notdef
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 * If source address not specified yet, use address
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
367 * of outgoing interface.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
368 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
369 if (ip->ip_src.s_addr == INADDR_ANY)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
370 ip->ip_src = ia->ia_addr.sin_addr;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
371 #endif
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
372 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
373 * Look for broadcast address and
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
374 * and verify user is allowed to send
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
375 * such a packet.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
376 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
377 if (in_broadcast(dst->sin_addr, ifp)) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
378 if ((ifp->if_flags & IFF_BROADCAST) == 0) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
379 error = EADDRNOTAVAIL;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
380 goto bad;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
381 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
382 if ((flags & IP_ALLOWBROADCAST) == 0) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
383 error = EACCES;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
384 goto bad;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
385 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
386 /* don't allow broadcast messages to be fragmented */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
387 if ((u_int16_t)ip->ip_len > ifp->if_mtu) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
388 error = EMSGSIZE;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
389 goto bad;
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 m->m_flags |= M_BCAST;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
392 } else
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
393 m->m_flags &= ~M_BCAST;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
394
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
395 sendit:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
396 #ifdef IPSEC
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
397 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
398 * Check if the packet needs encapsulation.
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 if (!(flags & IP_ENCAPSULATED) &&
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
401 (inp == NULL ||
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
402 inp->inp_seclevel[SL_AUTH] != IPSEC_LEVEL_BYPASS ||
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
403 inp->inp_seclevel[SL_ESP_TRANS] != IPSEC_LEVEL_BYPASS ||
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
404 inp->inp_seclevel[SL_ESP_NETWORK] != IPSEC_LEVEL_BYPASS)) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
405 if (inp == NULL)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
406 sa_require = get_sa_require(inp);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
407 else
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
408 sa_require = inp->inp_secrequire;
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 bzero((caddr_t) re, sizeof(*re));
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
411
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
412 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
413 * splnet is chosen over spltdb because we are not allowed to
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
414 * lower the level, and udp_output calls us in splnet().
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
415 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
416 s = splnet();
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
417
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
418 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
419 * Check if there was an outgoing SA bound to the flow
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
420 * from a transport protocol.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
421 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
422 if (inp && inp->inp_tdb &&
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
423 (inp->inp_tdb->tdb_dst.sin.sin_addr.s_addr == INADDR_ANY ||
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
424 !bcmp(&inp->inp_tdb->tdb_dst.sin.sin_addr,
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
425 &ip->ip_dst, sizeof(ip->ip_dst)))) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
426 tdb = inp->inp_tdb;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
427 goto have_tdb;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
428 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
429
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
430 if (!ipsec_in_use) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
431 splx(s);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
432 goto no_encap;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
433 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
434
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
435 ddst = (struct sockaddr_encap *) &re->re_dst;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
436 ddst->sen_family = PF_KEY;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
437 ddst->sen_len = SENT_IP4_LEN;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
438 ddst->sen_type = SENT_IP4;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
439 ddst->sen_ip_src = ip->ip_src;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
440 ddst->sen_ip_dst = ip->ip_dst;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
441 ddst->sen_proto = ip->ip_p;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
442
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
443 switch (ip->ip_p) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
444 case IPPROTO_UDP:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
445 if (m->m_len < hlen + 2 * sizeof(u_int16_t)) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
446 if ((m = m_pullup(m, hlen + 2 *
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
447 sizeof(u_int16_t))) == 0)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
448 return ENOBUFS;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
449 ip = mtod(m, struct ip *);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
450 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
451 udp = (struct udphdr *) (mtod(m, u_char *) + hlen);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
452 ddst->sen_sport = ntohs(udp->uh_sport);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
453 ddst->sen_dport = ntohs(udp->uh_dport);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
454 break;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
455
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
456 case IPPROTO_TCP:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
457 if (m->m_len < hlen + 2 * sizeof(u_int16_t)) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
458 if ((m = m_pullup(m, hlen + 2 *
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
459 sizeof(u_int16_t))) == 0)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
460 return ENOBUFS;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
461 ip = mtod(m, struct ip *);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
462 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
463 tcp = (struct tcphdr *) (mtod(m, u_char *) + hlen);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
464 ddst->sen_sport = ntohs(tcp->th_sport);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
465 ddst->sen_dport = ntohs(tcp->th_dport);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
466 break;
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 default:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
469 ddst->sen_sport = 0;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
470 ddst->sen_dport = 0;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
471 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
472
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
473 rtalloc((struct route *) re);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
474 if (re->re_rt == NULL) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
475 splx(s);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
476 goto no_encap;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
477 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
478
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
479 gw = (struct sockaddr_encap *) (re->re_rt->rt_gateway);
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 /* Sanity check */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
482 if (gw == NULL || ((gw->sen_type != SENT_IPSP) &&
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
483 (gw->sen_type != SENT_IPSP6))) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
484 splx(s);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
485 DPRINTF(("ip_output(): no gw or gw data not IPSP\n"));
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
486
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
487 if (re->re_rt)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
488 RTFREE(re->re_rt);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
489 error = EHOSTUNREACH;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
490 m_freem(m);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
491 goto done;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
492 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
493
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 * There might be a specific route, that tells us to avoid
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
496 * doing IPsec; this is useful for specific routes that we
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
497 * don't want to have IPsec applied on, like the key
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
498 * management ports.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
499 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
500
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
501 if ((gw != NULL) && (gw->sen_ipsp_sproto == 0) &&
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
502 (gw->sen_ipsp_spi == 0)) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
503 if ((gw->sen_family == AF_INET) &&
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
504 (gw->sen_ipsp_dst.s_addr == 0)) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
505 splx(s);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
506 goto no_encap;
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 #ifdef INET6
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
510 if ((gw->sen_family == AF_INET6) &&
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
511 IN6_IS_ADDR_UNSPECIFIED(&gw->sen_ipsp6_dst)) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
512 splx(s);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
513 goto no_encap;
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 #endif /* INET6 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
516 }
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 * At this point we have an IPSP "gateway" (tunnel) spec.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
520 * Use the destination of the tunnel and the SPI to
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
521 * look up the necessary Tunnel Control Block. Look it up,
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
522 * and then pass it, along with the packet and the gw,
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
523 * to the appropriate transformation.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
524 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
525 bzero(&sunion, sizeof(sunion));
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
526
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
527 if (gw->sen_type == SENT_IPSP) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
528 sunion.sin.sin_family = AF_INET;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
529 sunion.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
530 sunion.sin.sin_addr = gw->sen_ipsp_dst;
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 #ifdef INET6
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
533 if (gw->sen_type == SENT_IPSP6) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
534 sunion.sin6.sin6_family = AF_INET6;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
535 sunion.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
536 sunion.sin6.sin6_addr = gw->sen_ipsp6_dst;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
537 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
538 #endif /* INET6 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
539
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
540 tdb = (struct tdb *) gettdb(gw->sen_ipsp_spi, &sunion,
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
541 gw->sen_ipsp_sproto);
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 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
544 * For VPNs a route with a reserved SPI is used to
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
545 * indicate the need for an SA when none is established.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
546 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
547 if (((ntohl(gw->sen_ipsp_spi) == SPI_LOCAL_USE) &&
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
548 (gw->sen_type == SENT_IPSP)) ||
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
549 ((ntohl(gw->sen_ipsp6_spi) == SPI_LOCAL_USE) &&
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
550 (gw->sen_type == SENT_IPSP6))) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
551 if (tdb == NULL) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
552 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
553 * XXX We should construct a TDB from system
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
554 * default (which should be tunable via sysctl).
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
555 * For now, drop packet and ignore SPD entry.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
556 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
557 splx(s);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
558 goto no_encap;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
559 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
560 else {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
561 if (tdb->tdb_authalgxform)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
562 sa_require = NOTIFY_SATYPE_AUTH;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
563 if (tdb->tdb_encalgxform)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
564 sa_require |= NOTIFY_SATYPE_CONF;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
565 if (tdb->tdb_flags & TDBF_TUNNELING)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
566 sa_require |= NOTIFY_SATYPE_TUNNEL;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
567 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
568
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
569 /* PF_KEYv2 notification message */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
570 if (tdb && tdb->tdb_satype != SADB_X_SATYPE_BYPASS)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
571 if ((error = pfkeyv2_acquire(tdb, 0)) != 0)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
572 return error;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
573
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
574 splx(s);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
575
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
576 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
577 * When sa_require is set, the packet will be dropped
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
578 * at no_encap.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
579 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
580 goto no_encap;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
581 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
582
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
583 have_tdb:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
584
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
585 ip->ip_len = htons((u_short) ip->ip_len);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
586 ip->ip_off = htons((u_short) ip->ip_off);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
587 ip->ip_sum = 0;
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 * Now we check if this tdb has all the transforms which
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
591 * are requried by the socket or our default policy.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
592 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
593 SPI_CHAIN_ATTRIB(sa_have, tdb_onext, tdb);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
594
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
595 if (sa_require & ~sa_have)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
596 goto no_encap;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
597
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
598 if (tdb == NULL) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
599 splx(s);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
600 if (gw->sen_type == SENT_IPSP)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
601 DPRINTF(("ip_output(): non-existant TDB for SA %s/%08x/%u\n", inet_ntoa4(gw->sen_ipsp_dst), ntohl(gw->sen_ipsp_spi), gw->sen_ipsp_sproto));
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
602 #ifdef INET6
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
603 else
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
604 DPRINTF(("ip_output(): non-existant TDB for SA %s/%08x/%u\n", inet6_ntoa4(gw->sen_ipsp6_dst), ntohl(gw->sen_ipsp6_spi), gw->sen_ipsp6_sproto));
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
605 #endif /* INET6 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
606
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
607 if (re->re_rt)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
608 RTFREE(re->re_rt);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
609 error = EHOSTUNREACH;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
610 m_freem(m);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
611 goto done;
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
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
614 for (t = tdb; t != NULL; t = t->tdb_onext)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
615 if ((t->tdb_sproto == IPPROTO_ESP && !esp_enable) ||
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
616 (t->tdb_sproto == IPPROTO_AH && !ah_enable)) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
617 DPRINTF(("ip_output(): IPSec outbound packet dropped due to policy\n"));
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
618
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
619 if (re->re_rt)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
620 RTFREE(re->re_rt);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
621 error = EHOSTUNREACH;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
622 m_freem(m);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
623 goto done;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
624 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
625
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
626 while (tdb && tdb->tdb_xform) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
627 /* Check if the SPI is invalid */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
628 if (tdb->tdb_flags & TDBF_INVALID) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
629 splx(s);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
630 DPRINTF(("ip_output(): attempt to use invalid SA %s/%08x/%u\n", ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi), tdb->tdb_sproto));
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
631 m_freem(m);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
632 if (re->re_rt)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
633 RTFREE(re->re_rt);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
634 return ENXIO;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
635 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
636
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
637 #ifndef INET6
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
638 /* Sanity check */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
639 if (tdb->tdb_dst.sa.sa_family != AF_INET) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
640 splx(s);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
641 DPRINTF(("ip_output(): attempt to use SA %s/%08x/%u for protocol family %d\n", ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi), tdb->tdb_sproto, tdb->tdb_dst.sa.sa_family));
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
642 m_freem(m);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
643 if (re->re_rt)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
644 RTFREE(re->re_rt);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
645 return ENXIO;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
646 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
647 #endif /* 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 /* Register first use, setup expiration timer */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
650 if (tdb->tdb_first_use == 0) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
651 tdb->tdb_first_use = time.tv_sec;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
652 tdb_expiration(tdb, TDBEXP_TIMEOUT);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
653 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
654
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
655 /* Check for tunneling */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
656 if (((tdb->tdb_dst.sa.sa_family == AF_INET) &&
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
657 (tdb->tdb_dst.sin.sin_addr.s_addr !=
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
658 INADDR_ANY) &&
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
659 (tdb->tdb_dst.sin.sin_addr.s_addr !=
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
660 ip->ip_dst.s_addr)) ||
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
661 (tdb->tdb_dst.sa.sa_family == AF_INET6) ||
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
662 ((tdb->tdb_flags & TDBF_TUNNELING) &&
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
663 (tdb->tdb_xform->xf_type != XF_IP4))) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
664 /* Fix length and checksum */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
665 ip->ip_len = htons(m->m_pkthdr.len);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
666 ip->ip_sum = in_cksum(m, ip->ip_hl << 2);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
667 error = ipe4_output(m, tdb, &mp,
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
668 ip->ip_hl << 2,
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
669 offsetof(struct ip, ip_p));
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
670 if (mp == NULL)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
671 error = EFAULT;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
672 if (error) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
673 splx(s);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
674 if (re->re_rt)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
675 RTFREE(re->re_rt);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
676 return error;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
677 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
678 if (tdb->tdb_dst.sa.sa_family == AF_INET)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
679 ip6flag = 0;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
680 #ifdef INET6
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
681 if (tdb->tdb_dst.sa.sa_family == AF_INET6)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
682 ip6flag = 1;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
683 #endif /* INET6 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
684 m = mp;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
685 mp = NULL;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
686 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
687
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
688 if ((tdb->tdb_xform->xf_type == XF_IP4) &&
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
689 (tdb->tdb_dst.sa.sa_family == AF_INET)) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
690 ip = mtod(m, struct ip *);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
691 ip->ip_len = htons(m->m_pkthdr.len);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
692 ip->ip_sum = in_cksum(m, ip->ip_hl << 2);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
693 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
694
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
695 #ifdef INET6
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
696 if ((tdb->tdb_xform->xf_type == XF_IP4) &&
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
697 (tdb->tdb_dst.sa.sa_family == AF_INET6)) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
698 ip6 = mtod(m, struct ip6_hdr *);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
699 ip6->ip6_plen = htons(m->m_pkthdr.len);
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 #endif /* INET6 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
702
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
703 #ifdef INET6
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 * This assumes that there is only just an IPv6
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
706 * header prepended.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
707 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
708 if (ip6flag)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
709 error = (*(tdb->tdb_xform->xf_output))(m, tdb, &mp, sizeof(struct ip6_hdr), offsetof(struct ip6_hdr, ip6_nxt));
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
710 #endif /* INET6 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
711
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
712 if (!ip6flag)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
713 error = (*(tdb->tdb_xform->xf_output))(m, tdb, &mp, ip->ip_hl << 2, offsetof(struct ip, ip_p));
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
714 if (!error && mp == NULL)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
715 error = EFAULT;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
716 if (error) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
717 splx(s);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
718 if (mp != NULL)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
719 m_freem(mp);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
720 if (re->re_rt)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
721 RTFREE(re->re_rt);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
722 return error;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
723 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
724
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
725 m = mp;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
726 mp = NULL;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
727
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
728 if (!ip6flag) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
729 ip = mtod(m, struct ip *);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
730 ip->ip_len = htons(m->m_pkthdr.len);
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
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
733 #ifdef INET6
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
734 if (ip6flag) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
735 ip6 = mtod(m, struct ip6_hdr *);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
736 ip6->ip6_plen = htons(m->m_pkthdr.len);
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 #endif /* INET6 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
739 tdb = tdb->tdb_onext;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
740 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
741 splx(s);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
742
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
743 if (!ip6flag)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
744 ip->ip_sum = in_cksum(m, ip->ip_hl << 2);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
745
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
746 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
747 * At this point, m is pointing to an mbuf chain with the
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
748 * processed packet. Call ourselves recursively, but
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
749 * bypass the encap code.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
750 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
751 if (re->re_rt)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
752 RTFREE(re->re_rt);
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 (!ip6flag) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
755 ip = mtod(m, struct ip *);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
756 NTOHS(ip->ip_len);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
757 NTOHS(ip->ip_off);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
758
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
759 return ip_output(m, NULL, NULL,
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
760 IP_ENCAPSULATED | IP_RAWOUTPUT,
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
761 NULL, NULL);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
762 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
763
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
764 #ifdef INET6
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
765 if (ip6flag) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
766 ip6 = mtod(m, struct ip6_hdr *);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
767 NTOHS(ip6->ip6_plen);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
768
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
769 /* Naturally, ip6_output() has to honor those two flags */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
770 return ip6_output(m, NULL, NULL,
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
771 IP_ENCAPSULATED | IP_RAWOUTPUT,
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
772 NULL, NULL);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
773 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
774 #endif /* INET6 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
775
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
776 no_encap:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
777 /* This is for possible future use, don't move or delete */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
778 if (re->re_rt)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
779 RTFREE(re->re_rt);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
780 /* No IPSec processing though it was required, drop packet */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
781 if (sa_require) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
782 error = EHOSTUNREACH;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
783 m_freem(m);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
784 goto done;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
785 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
786 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
787 #endif /* IPSEC */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
788
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
789 #if defined(IPFILTER) || defined(IPFILTER_LKM)
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 * looks like most checking has been done now...do a filter check
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
792 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
793 {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
794 struct mbuf *m0 = m;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
795 if (fr_checkp && (*fr_checkp)(ip, hlen, ifp, 1, &m0)) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
796 error = EHOSTUNREACH;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
797 goto done;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
798 } else
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
799 ip = mtod(m = m0, struct ip *);
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 #endif
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
802 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
803 * If small enough for interface, can just send directly.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
804 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
805 if ((u_int16_t)ip->ip_len <= ifp->if_mtu) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
806 ip->ip_len = htons((u_int16_t)ip->ip_len);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
807 ip->ip_off = htons((u_int16_t)ip->ip_off);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
808 ip->ip_sum = 0;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
809 ip->ip_sum = in_cksum(m, hlen);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
810 error = (*ifp->if_output)(ifp, m, sintosa(dst), ro->ro_rt);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
811 goto done;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
812 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
813
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
814 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
815 * Too large for interface; fragment if possible.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
816 * Must be able to put at least 8 bytes per fragment.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
817 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
818 #if 0
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
819 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
820 * If IPsec packet is too big for the interface, try fragment it.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
821 * XXX This really is a quickhack. May be inappropriate.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
822 * XXX fails if somebody is sending AH'ed packet, with:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
823 * sizeof(packet without AH) < mtu < sizeof(packet with AH)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
824 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
825 if (sab && ip->ip_p != IPPROTO_AH && (flags & IP_FORWARDING) == 0)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
826 ip->ip_off &= ~IP_DF;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
827 #endif /*IPSEC*/
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
828 if (ip->ip_off & IP_DF) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
829 error = EMSGSIZE;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
830 ipstat.ips_cantfrag++;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
831 goto bad;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
832 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
833 len = (ifp->if_mtu - hlen) &~ 7;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
834 if (len < 8) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
835 error = EMSGSIZE;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
836 goto bad;
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
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
839 {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
840 int mhlen, firstlen = len;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
841 struct mbuf **mnext = &m->m_nextpkt;
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 * Loop through length of segment after first fragment,
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
845 * make new header and copy data of each part and link onto chain.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
846 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
847 m0 = m;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
848 mhlen = sizeof (struct ip);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
849 for (off = hlen + len; off < (u_int16_t)ip->ip_len; off += len) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
850 MGETHDR(m, M_DONTWAIT, MT_HEADER);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
851 if (m == 0) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
852 error = ENOBUFS;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
853 ipstat.ips_odropped++;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
854 goto sendorfree;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
855 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
856 *mnext = m;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
857 mnext = &m->m_nextpkt;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
858 m->m_data += max_linkhdr;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
859 mhip = mtod(m, struct ip *);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
860 *mhip = *ip;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
861 if (hlen > sizeof (struct ip)) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
862 mhlen = ip_optcopy(ip, mhip) + sizeof (struct ip);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
863 mhip->ip_hl = mhlen >> 2;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
864 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
865 m->m_len = mhlen;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
866 mhip->ip_off = ((off - hlen) >> 3) + (ip->ip_off & ~IP_MF);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
867 if (ip->ip_off & IP_MF)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
868 mhip->ip_off |= IP_MF;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
869 if (off + len >= (u_int16_t)ip->ip_len)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
870 len = (u_int16_t)ip->ip_len - off;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
871 else
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
872 mhip->ip_off |= IP_MF;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
873 mhip->ip_len = htons((u_int16_t)(len + mhlen));
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
874 m->m_next = m_copy(m0, off, len);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
875 if (m->m_next == 0) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
876 error = ENOBUFS; /* ??? */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
877 ipstat.ips_odropped++;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
878 goto sendorfree;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
879 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
880 m->m_pkthdr.len = mhlen + len;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
881 m->m_pkthdr.rcvif = (struct ifnet *)0;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
882 mhip->ip_off = htons((u_int16_t)mhip->ip_off);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
883 mhip->ip_sum = 0;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
884 mhip->ip_sum = in_cksum(m, mhlen);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
885 ipstat.ips_ofragments++;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
886 }
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 * Update first fragment by trimming what's been copied out
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
889 * and updating header, then send each fragment (in order).
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
890 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
891 m = m0;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
892 m_adj(m, hlen + firstlen - (u_int16_t)ip->ip_len);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
893 m->m_pkthdr.len = hlen + firstlen;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
894 ip->ip_len = htons((u_int16_t)m->m_pkthdr.len);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
895 ip->ip_off = htons((u_int16_t)(ip->ip_off | IP_MF));
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
896 ip->ip_sum = 0;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
897 ip->ip_sum = in_cksum(m, hlen);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
898 sendorfree:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
899 for (m = m0; m; m = m0) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
900 m0 = m->m_nextpkt;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
901 m->m_nextpkt = 0;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
902 if (error == 0)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
903 error = (*ifp->if_output)(ifp, m, sintosa(dst),
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
904 ro->ro_rt);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
905 else
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
906 m_freem(m);
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 if (error == 0)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
910 ipstat.ips_fragmented++;
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 done:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
913 if (ro == &iproute && (flags & IP_ROUTETOIF) == 0 && ro->ro_rt)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
914 RTFREE(ro->ro_rt);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
915 return (error);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
916 bad:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
917 m_freem(m0);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
918 goto done;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
919 }
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 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
922 * Insert IP options into preformed packet.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
923 * Adjust IP destination as required for IP source routing,
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
924 * as indicated by a non-zero in_addr at the start of the options.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
925 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
926 static struct mbuf *
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
927 ip_insertoptions(m, opt, phlen)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
928 register struct mbuf *m;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
929 struct mbuf *opt;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
930 int *phlen;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
931 {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
932 register struct ipoption *p = mtod(opt, struct ipoption *);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
933 struct mbuf *n;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
934 register struct ip *ip = mtod(m, struct ip *);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
935 unsigned optlen;
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 optlen = opt->m_len - sizeof(p->ipopt_dst);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
938 if (optlen + (u_int16_t)ip->ip_len > IP_MAXPACKET)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
939 return (m); /* XXX should fail */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
940 if (p->ipopt_dst.s_addr)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
941 ip->ip_dst = p->ipopt_dst;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
942 if (m->m_flags & M_EXT || m->m_data - optlen < m->m_pktdat) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
943 MGETHDR(n, M_DONTWAIT, MT_HEADER);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
944 if (n == 0)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
945 return (m);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
946 n->m_pkthdr.len = m->m_pkthdr.len + optlen;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
947 m->m_len -= sizeof(struct ip);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
948 m->m_data += sizeof(struct ip);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
949 n->m_next = m;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
950 m = n;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
951 m->m_len = optlen + sizeof(struct ip);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
952 m->m_data += max_linkhdr;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
953 bcopy((caddr_t)ip, mtod(m, caddr_t), sizeof(struct ip));
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
954 } else {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
955 m->m_data -= optlen;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
956 m->m_len += optlen;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
957 m->m_pkthdr.len += optlen;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
958 ovbcopy((caddr_t)ip, mtod(m, caddr_t), sizeof(struct ip));
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
959 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
960 ip = mtod(m, struct ip *);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
961 bcopy((caddr_t)p->ipopt_list, (caddr_t)(ip + 1), (unsigned)optlen);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
962 *phlen = sizeof(struct ip) + optlen;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
963 ip->ip_len += optlen;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
964 return (m);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
965 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
966
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
967 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
968 * Copy options from ip to jp,
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
969 * omitting those not copied during fragmentation.
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 int
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
972 ip_optcopy(ip, jp)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
973 struct ip *ip, *jp;
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 register u_char *cp, *dp;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
976 int opt, optlen, cnt;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
977
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
978 cp = (u_char *)(ip + 1);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
979 dp = (u_char *)(jp + 1);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
980 cnt = (ip->ip_hl << 2) - sizeof (struct ip);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
981 for (; cnt > 0; cnt -= optlen, cp += optlen) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
982 opt = cp[0];
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
983 if (opt == IPOPT_EOL)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
984 break;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
985 if (opt == IPOPT_NOP) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
986 /* Preserve for IP mcast tunnel's LSRR alignment. */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
987 *dp++ = IPOPT_NOP;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
988 optlen = 1;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
989 continue;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
990 } else
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
991 optlen = cp[IPOPT_OLEN];
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
992 /* bogus lengths should have been caught by ip_dooptions */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
993 if (optlen > cnt)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
994 optlen = cnt;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
995 if (IPOPT_COPIED(opt)) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
996 bcopy((caddr_t)cp, (caddr_t)dp, (unsigned)optlen);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
997 dp += optlen;
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 for (optlen = dp - (u_char *)(jp+1); optlen & 0x3; optlen++)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1001 *dp++ = IPOPT_EOL;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1002 return (optlen);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1003 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1004
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 * IP socket option processing.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1007 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1008 int
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1009 ip_ctloutput(op, so, level, optname, mp)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1010 int op;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1011 struct socket *so;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1012 int level, optname;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1013 struct mbuf **mp;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1014 {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1015 register struct inpcb *inp = sotoinpcb(so);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1016 register struct mbuf *m = *mp;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1017 register int optval = 0;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1018 #ifdef IPSEC
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1019 struct proc *p = curproc; /* XXX */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1020 struct tdb *tdb;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1021 struct tdb_ident *tdbip, tdbi;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1022 int s;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1023 #endif
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1024 int error = 0;
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 if (level != IPPROTO_IP) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1027 error = EINVAL;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1028 if (op == PRCO_SETOPT && *mp)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1029 (void) m_free(*mp);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1030 } else switch (op) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1031
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1032 case PRCO_SETOPT:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1033 switch (optname) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1034 case IP_OPTIONS:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1035 #ifdef notyet
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1036 case IP_RETOPTS:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1037 return (ip_pcbopts(optname, &inp->inp_options, m));
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1038 #else
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1039 return (ip_pcbopts(&inp->inp_options, m));
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1040 #endif
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1041
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1042 case IP_TOS:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1043 case IP_TTL:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1044 case IP_RECVOPTS:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1045 case IP_RECVRETOPTS:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1046 case IP_RECVDSTADDR:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1047 if (m == NULL || m->m_len != sizeof(int))
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1048 error = EINVAL;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1049 else {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1050 optval = *mtod(m, int *);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1051 switch (optname) {
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 case IP_TOS:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1054 inp->inp_ip.ip_tos = optval;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1055 break;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1056
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1057 case IP_TTL:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1058 inp->inp_ip.ip_ttl = optval;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1059 break;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1060 #define OPTSET(bit) \
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1061 if (optval) \
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1062 inp->inp_flags |= bit; \
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1063 else \
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1064 inp->inp_flags &= ~bit;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1065
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1066 case IP_RECVOPTS:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1067 OPTSET(INP_RECVOPTS);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1068 break;
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 case IP_RECVRETOPTS:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1071 OPTSET(INP_RECVRETOPTS);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1072 break;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1073
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1074 case IP_RECVDSTADDR:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1075 OPTSET(INP_RECVDSTADDR);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1076 break;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1077 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1078 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1079 break;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1080 #undef OPTSET
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1081
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1082 case IP_MULTICAST_IF:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1083 case IP_MULTICAST_TTL:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1084 case IP_MULTICAST_LOOP:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1085 case IP_ADD_MEMBERSHIP:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1086 case IP_DROP_MEMBERSHIP:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1087 error = ip_setmoptions(optname, &inp->inp_moptions, m);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1088 break;
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 case IP_PORTRANGE:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1091 if (m == 0 || m->m_len != sizeof(int))
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1092 error = EINVAL;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1093 else {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1094 optval = *mtod(m, int *);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1095
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1096 switch (optval) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1097
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1098 case IP_PORTRANGE_DEFAULT:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1099 inp->inp_flags &= ~(INP_LOWPORT);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1100 inp->inp_flags &= ~(INP_HIGHPORT);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1101 break;
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 case IP_PORTRANGE_HIGH:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1104 inp->inp_flags &= ~(INP_LOWPORT);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1105 inp->inp_flags |= INP_HIGHPORT;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1106 break;
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 case IP_PORTRANGE_LOW:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1109 inp->inp_flags &= ~(INP_HIGHPORT);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1110 inp->inp_flags |= INP_LOWPORT;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1111 break;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1112
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1113 default:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1114
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1115 error = EINVAL;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1116 break;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1117 }
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 break;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1120 case IPSEC_OUTSA:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1121 #ifndef IPSEC
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1122 error = EINVAL;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1123 #else
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1124 s = spltdb();
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1125 if (m == 0 || m->m_len != sizeof(struct tdb_ident)) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1126 error = EINVAL;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1127 } else {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1128 tdbip = mtod(m, struct tdb_ident *);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1129 tdb = gettdb(tdbip->spi, &tdbip->dst,
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1130 tdbip->proto);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1131 if (tdb == NULL)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1132 error = ESRCH;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1133 else
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1134 tdb_add_inp(tdb, inp);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1135 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1136 splx(s);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1137 #endif /* IPSEC */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1138 break;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1139
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1140 case IP_AUTH_LEVEL:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1141 case IP_ESP_TRANS_LEVEL:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1142 case IP_ESP_NETWORK_LEVEL:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1143 #ifndef IPSEC
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1144 error = EINVAL;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1145 #else
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1146 if (m == 0 || m->m_len != sizeof(int)) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1147 error = EINVAL;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1148 break;
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 optval = *mtod(m, u_char *);
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 if (optval < IPSEC_LEVEL_BYPASS ||
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1153 optval > IPSEC_LEVEL_UNIQUE) {
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
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1158 switch (optname) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1159 case IP_AUTH_LEVEL:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1160 if (optval < ipsec_auth_default_level &&
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1161 suser(p->p_ucred, &p->p_acflag)) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1162 error = EACCES;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1163 break;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1164 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1165 inp->inp_seclevel[SL_AUTH] = optval;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1166 break;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1167
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1168 case IP_ESP_TRANS_LEVEL:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1169 if (optval < ipsec_esp_trans_default_level &&
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1170 suser(p->p_ucred, &p->p_acflag)) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1171 error = EACCES;
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 inp->inp_seclevel[SL_ESP_TRANS] = optval;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1175 break;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1176
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1177 case IP_ESP_NETWORK_LEVEL:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1178 if (optval < ipsec_esp_network_default_level &&
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1179 suser(p->p_ucred, &p->p_acflag)) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1180 error = EACCES;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1181 break;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1182 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1183 inp->inp_seclevel[SL_ESP_NETWORK] = optval;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1184 break;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1185 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1186 if (!error)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1187 inp->inp_secrequire = get_sa_require(inp);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1188 #endif
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1189 break;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1190
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1191 default:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1192 error = ENOPROTOOPT;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1193 break;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1194 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1195 if (m)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1196 (void)m_free(m);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1197 break;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1198
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1199 case PRCO_GETOPT:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1200 switch (optname) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1201 case IP_OPTIONS:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1202 case IP_RETOPTS:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1203 *mp = m = m_get(M_WAIT, MT_SOOPTS);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1204 if (inp->inp_options) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1205 m->m_len = inp->inp_options->m_len;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1206 bcopy(mtod(inp->inp_options, caddr_t),
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1207 mtod(m, caddr_t), (unsigned)m->m_len);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1208 } else
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1209 m->m_len = 0;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1210 break;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1211
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1212 case IP_TOS:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1213 case IP_TTL:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1214 case IP_RECVOPTS:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1215 case IP_RECVRETOPTS:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1216 case IP_RECVDSTADDR:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1217 *mp = m = m_get(M_WAIT, MT_SOOPTS);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1218 m->m_len = sizeof(int);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1219 switch (optname) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1220
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1221 case IP_TOS:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1222 optval = inp->inp_ip.ip_tos;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1223 break;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1224
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1225 case IP_TTL:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1226 optval = inp->inp_ip.ip_ttl;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1227 break;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1228
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1229 #define OPTBIT(bit) (inp->inp_flags & bit ? 1 : 0)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1230
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1231 case IP_RECVOPTS:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1232 optval = OPTBIT(INP_RECVOPTS);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1233 break;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1234
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1235 case IP_RECVRETOPTS:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1236 optval = OPTBIT(INP_RECVRETOPTS);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1237 break;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1238
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1239 case IP_RECVDSTADDR:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1240 optval = OPTBIT(INP_RECVDSTADDR);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1241 break;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1242 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1243 *mtod(m, int *) = optval;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1244 break;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1245
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1246 case IP_MULTICAST_IF:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1247 case IP_MULTICAST_TTL:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1248 case IP_MULTICAST_LOOP:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1249 case IP_ADD_MEMBERSHIP:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1250 case IP_DROP_MEMBERSHIP:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1251 error = ip_getmoptions(optname, inp->inp_moptions, mp);
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 IP_PORTRANGE:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1255 *mp = m = m_get(M_WAIT, MT_SOOPTS);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1256 m->m_len = sizeof(int);
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 if (inp->inp_flags & INP_HIGHPORT)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1259 optval = IP_PORTRANGE_HIGH;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1260 else if (inp->inp_flags & INP_LOWPORT)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1261 optval = IP_PORTRANGE_LOW;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1262 else
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1263 optval = 0;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1264
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1265 *mtod(m, int *) = optval;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1266 break;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1267
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1268 case IPSEC_OUTSA:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1269 #ifndef IPSEC
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1270 error = EINVAL;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1271 #else
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1272 s = spltdb();
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1273 if (inp->inp_tdb == NULL) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1274 error = ENOENT;
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 tdbi.spi = inp->inp_tdb->tdb_spi;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1277 tdbi.dst = inp->inp_tdb->tdb_dst;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1278 tdbi.proto = inp->inp_tdb->tdb_sproto;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1279 *mp = m = m_get(M_WAIT, MT_SOOPTS);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1280 m->m_len = sizeof(tdbi);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1281 bcopy((caddr_t)&tdbi, mtod(m, caddr_t),
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1282 (unsigned)m->m_len);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1283 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1284 splx(s);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1285 #endif /* IPSEC */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1286 break;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1287
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1288 case IP_AUTH_LEVEL:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1289 case IP_ESP_TRANS_LEVEL:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1290 case IP_ESP_NETWORK_LEVEL:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1291 #ifndef IPSEC
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1292 *mtod(m, int *) = IPSEC_LEVEL_NONE;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1293 #else
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1294 switch (optname) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1295 case IP_AUTH_LEVEL:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1296 optval = inp->inp_seclevel[SL_AUTH];
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1297 break;
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 IP_ESP_TRANS_LEVEL:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1300 optval = inp->inp_seclevel[SL_ESP_TRANS];
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1301 break;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1302
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1303 case IP_ESP_NETWORK_LEVEL:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1304 optval = inp->inp_seclevel[SL_ESP_NETWORK];
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 *mtod(m, int *) = optval;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1308 #endif
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1309 break;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1310 default:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1311 error = ENOPROTOOPT;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1312 break;
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 break;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1315 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1316 return (error);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1317 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1318
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1319 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1320 * Set up IP options in pcb for insertion in output packets.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1321 * Store in mbuf with pointer in pcbopt, adding pseudo-option
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1322 * with destination address if source routed.
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 int
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1325 #ifdef notyet
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1326 ip_pcbopts(optname, pcbopt, m)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1327 int optname;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1328 #else
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1329 ip_pcbopts(pcbopt, m)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1330 #endif
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1331 struct mbuf **pcbopt;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1332 register struct mbuf *m;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1333 {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1334 register int cnt, optlen;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1335 register u_char *cp;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1336 u_char opt;
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 /* turn off any old options */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1339 if (*pcbopt)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1340 (void)m_free(*pcbopt);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1341 *pcbopt = 0;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1342 if (m == (struct mbuf *)0 || m->m_len == 0) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1343 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1344 * Only turning off any previous options.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1345 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1346 if (m)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1347 (void)m_free(m);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1348 return (0);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1349 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1350
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1351 #ifndef vax
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1352 if (m->m_len % sizeof(int32_t))
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1353 goto bad;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1354 #endif
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 * IP first-hop destination address will be stored before
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1357 * actual options; move other options back
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1358 * and clear it when none present.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1359 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1360 if (m->m_data + m->m_len + sizeof(struct in_addr) >= &m->m_dat[MLEN])
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1361 goto bad;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1362 cnt = m->m_len;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1363 m->m_len += sizeof(struct in_addr);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1364 cp = mtod(m, u_char *) + sizeof(struct in_addr);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1365 ovbcopy(mtod(m, caddr_t), (caddr_t)cp, (unsigned)cnt);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1366 bzero(mtod(m, caddr_t), sizeof(struct in_addr));
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1367
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1368 for (; cnt > 0; cnt -= optlen, cp += optlen) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1369 opt = cp[IPOPT_OPTVAL];
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1370 if (opt == IPOPT_EOL)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1371 break;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1372 if (opt == IPOPT_NOP)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1373 optlen = 1;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1374 else {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1375 optlen = cp[IPOPT_OLEN];
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1376 if (optlen <= IPOPT_OLEN || optlen > cnt)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1377 goto bad;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1378 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1379 switch (opt) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1380
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1381 default:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1382 break;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1383
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1384 case IPOPT_LSRR:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1385 case IPOPT_SSRR:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1386 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1387 * user process specifies route as:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1388 * ->A->B->C->D
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1389 * D must be our final destination (but we can't
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1390 * check that since we may not have connected yet).
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1391 * A is first hop destination, which doesn't appear in
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1392 * actual IP option, but is stored before the options.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1393 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1394 if (optlen < IPOPT_MINOFF - 1 + sizeof(struct in_addr))
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1395 goto bad;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1396 m->m_len -= sizeof(struct in_addr);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1397 cnt -= sizeof(struct in_addr);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1398 optlen -= sizeof(struct in_addr);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1399 cp[IPOPT_OLEN] = optlen;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1400 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1401 * Move first hop before start of options.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1402 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1403 bcopy((caddr_t)&cp[IPOPT_OFFSET+1], mtod(m, caddr_t),
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1404 sizeof(struct in_addr));
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1405 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1406 * Then copy rest of options back
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1407 * to close up the deleted entry.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1408 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1409 ovbcopy((caddr_t)(&cp[IPOPT_OFFSET+1] +
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1410 sizeof(struct in_addr)),
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1411 (caddr_t)&cp[IPOPT_OFFSET+1],
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1412 (unsigned)cnt + sizeof(struct in_addr));
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1413 break;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1414 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1415 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1416 if (m->m_len > MAX_IPOPTLEN + sizeof(struct in_addr))
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1417 goto bad;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1418 *pcbopt = m;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1419 return (0);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1420
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1421 bad:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1422 (void)m_free(m);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1423 return (EINVAL);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1424 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1425
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1426 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1427 * Set the IP multicast options in response to user setsockopt().
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1428 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1429 int
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1430 ip_setmoptions(optname, imop, m)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1431 int optname;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1432 struct ip_moptions **imop;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1433 struct mbuf *m;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1434 {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1435 register int error = 0;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1436 u_char loop;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1437 register int i;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1438 struct in_addr addr;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1439 register struct ip_mreq *mreq;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1440 register struct ifnet *ifp;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1441 register struct ip_moptions *imo = *imop;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1442 struct route ro;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1443 register struct sockaddr_in *dst;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1444
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1445 if (imo == NULL) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1446 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1447 * No multicast option buffer attached to the pcb;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1448 * allocate one and initialize to default values.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1449 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1450 imo = (struct ip_moptions *)malloc(sizeof(*imo), M_IPMOPTS,
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1451 M_WAITOK);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1452
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1453 if (imo == NULL)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1454 return (ENOBUFS);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1455 *imop = imo;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1456 imo->imo_multicast_ifp = NULL;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1457 imo->imo_multicast_ttl = IP_DEFAULT_MULTICAST_TTL;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1458 imo->imo_multicast_loop = IP_DEFAULT_MULTICAST_LOOP;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1459 imo->imo_num_memberships = 0;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1460 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1461
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1462 switch (optname) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1463
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1464 case IP_MULTICAST_IF:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1465 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1466 * Select the interface for outgoing multicast packets.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1467 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1468 if (m == NULL || m->m_len != sizeof(struct in_addr)) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1469 error = EINVAL;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1470 break;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1471 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1472 addr = *(mtod(m, struct in_addr *));
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1473 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1474 * INADDR_ANY is used to remove a previous selection.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1475 * When no interface is selected, a default one is
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1476 * chosen every time a multicast packet is sent.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1477 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1478 if (addr.s_addr == INADDR_ANY) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1479 imo->imo_multicast_ifp = NULL;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1480 break;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1481 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1482 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1483 * The selected interface is identified by its local
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1484 * IP address. Find the interface and confirm that
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1485 * it supports multicasting.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1486 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1487 INADDR_TO_IFP(addr, ifp);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1488 if (ifp == NULL || (ifp->if_flags & IFF_MULTICAST) == 0) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1489 error = EADDRNOTAVAIL;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1490 break;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1491 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1492 imo->imo_multicast_ifp = ifp;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1493 break;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1494
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1495 case IP_MULTICAST_TTL:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1496 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1497 * Set the IP time-to-live for outgoing multicast packets.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1498 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1499 if (m == NULL || m->m_len != 1) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1500 error = EINVAL;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1501 break;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1502 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1503 imo->imo_multicast_ttl = *(mtod(m, u_char *));
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1504 break;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1505
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1506 case IP_MULTICAST_LOOP:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1507 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1508 * Set the loopback flag for outgoing multicast packets.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1509 * Must be zero or one.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1510 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1511 if (m == NULL || m->m_len != 1 ||
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1512 (loop = *(mtod(m, u_char *))) > 1) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1513 error = EINVAL;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1514 break;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1515 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1516 imo->imo_multicast_loop = loop;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1517 break;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1518
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1519 case IP_ADD_MEMBERSHIP:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1520 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1521 * Add a multicast group membership.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1522 * Group must be a valid IP multicast address.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1523 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1524 if (m == NULL || m->m_len != sizeof(struct ip_mreq)) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1525 error = EINVAL;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1526 break;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1527 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1528 mreq = mtod(m, struct ip_mreq *);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1529 if (!IN_MULTICAST(mreq->imr_multiaddr.s_addr)) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1530 error = EINVAL;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1531 break;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1532 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1533 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1534 * If no interface address was provided, use the interface of
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1535 * the route to the given multicast address.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1536 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1537 if (mreq->imr_interface.s_addr == INADDR_ANY) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1538 ro.ro_rt = NULL;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1539 dst = satosin(&ro.ro_dst);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1540 dst->sin_len = sizeof(*dst);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1541 dst->sin_family = AF_INET;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1542 dst->sin_addr = mreq->imr_multiaddr;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1543 rtalloc(&ro);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1544 if (ro.ro_rt == NULL) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1545 error = EADDRNOTAVAIL;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1546 break;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1547 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1548 ifp = ro.ro_rt->rt_ifp;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1549 rtfree(ro.ro_rt);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1550 } else {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1551 INADDR_TO_IFP(mreq->imr_interface, ifp);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1552 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1553 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1554 * See if we found an interface, and confirm that it
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1555 * supports multicast.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1556 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1557 if (ifp == NULL || (ifp->if_flags & IFF_MULTICAST) == 0) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1558 error = EADDRNOTAVAIL;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1559 break;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1560 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1561 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1562 * See if the membership already exists or if all the
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1563 * membership slots are full.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1564 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1565 for (i = 0; i < imo->imo_num_memberships; ++i) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1566 if (imo->imo_membership[i]->inm_ifp == ifp &&
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1567 imo->imo_membership[i]->inm_addr.s_addr
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1568 == mreq->imr_multiaddr.s_addr)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1569 break;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1570 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1571 if (i < imo->imo_num_memberships) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1572 error = EADDRINUSE;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1573 break;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1574 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1575 if (i == IP_MAX_MEMBERSHIPS) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1576 error = ETOOMANYREFS;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1577 break;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1578 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1579 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1580 * Everything looks good; add a new record to the multicast
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1581 * address list for the given interface.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1582 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1583 if ((imo->imo_membership[i] =
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1584 in_addmulti(&mreq->imr_multiaddr, ifp)) == NULL) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1585 error = ENOBUFS;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1586 break;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1587 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1588 ++imo->imo_num_memberships;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1589 break;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1590
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1591 case IP_DROP_MEMBERSHIP:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1592 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1593 * Drop a multicast group membership.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1594 * Group must be a valid IP multicast address.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1595 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1596 if (m == NULL || m->m_len != sizeof(struct ip_mreq)) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1597 error = EINVAL;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1598 break;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1599 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1600 mreq = mtod(m, struct ip_mreq *);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1601 if (!IN_MULTICAST(mreq->imr_multiaddr.s_addr)) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1602 error = EINVAL;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1603 break;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1604 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1605 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1606 * If an interface address was specified, get a pointer
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1607 * to its ifnet structure.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1608 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1609 if (mreq->imr_interface.s_addr == INADDR_ANY)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1610 ifp = NULL;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1611 else {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1612 INADDR_TO_IFP(mreq->imr_interface, ifp);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1613 if (ifp == NULL) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1614 error = EADDRNOTAVAIL;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1615 break;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1616 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1617 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1618 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1619 * Find the membership in the membership array.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1620 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1621 for (i = 0; i < imo->imo_num_memberships; ++i) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1622 if ((ifp == NULL ||
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1623 imo->imo_membership[i]->inm_ifp == ifp) &&
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1624 imo->imo_membership[i]->inm_addr.s_addr ==
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1625 mreq->imr_multiaddr.s_addr)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1626 break;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1627 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1628 if (i == imo->imo_num_memberships) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1629 error = EADDRNOTAVAIL;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1630 break;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1631 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1632 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1633 * Give up the multicast address record to which the
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1634 * membership points.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1635 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1636 in_delmulti(imo->imo_membership[i]);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1637 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1638 * Remove the gap in the membership array.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1639 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1640 for (++i; i < imo->imo_num_memberships; ++i)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1641 imo->imo_membership[i-1] = imo->imo_membership[i];
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1642 --imo->imo_num_memberships;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1643 break;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1644
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1645 default:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1646 error = EOPNOTSUPP;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1647 break;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1648 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1649
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1650 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1651 * If all options have default values, no need to keep the mbuf.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1652 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1653 if (imo->imo_multicast_ifp == NULL &&
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1654 imo->imo_multicast_ttl == IP_DEFAULT_MULTICAST_TTL &&
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1655 imo->imo_multicast_loop == IP_DEFAULT_MULTICAST_LOOP &&
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1656 imo->imo_num_memberships == 0) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1657 free(*imop, M_IPMOPTS);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1658 *imop = NULL;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1659 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1660
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1661 return (error);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1662 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1663
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1664 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1665 * Return the IP multicast options in response to user getsockopt().
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1666 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1667 int
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1668 ip_getmoptions(optname, imo, mp)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1669 int optname;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1670 register struct ip_moptions *imo;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1671 register struct mbuf **mp;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1672 {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1673 u_char *ttl;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1674 u_char *loop;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1675 struct in_addr *addr;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1676 struct in_ifaddr *ia;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1677
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1678 *mp = m_get(M_WAIT, MT_SOOPTS);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1679
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1680 switch (optname) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1681
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1682 case IP_MULTICAST_IF:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1683 addr = mtod(*mp, struct in_addr *);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1684 (*mp)->m_len = sizeof(struct in_addr);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1685 if (imo == NULL || imo->imo_multicast_ifp == NULL)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1686 addr->s_addr = INADDR_ANY;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1687 else {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1688 IFP_TO_IA(imo->imo_multicast_ifp, ia);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1689 addr->s_addr = (ia == NULL) ? INADDR_ANY
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1690 : ia->ia_addr.sin_addr.s_addr;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1691 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1692 return (0);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1693
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1694 case IP_MULTICAST_TTL:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1695 ttl = mtod(*mp, u_char *);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1696 (*mp)->m_len = 1;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1697 *ttl = (imo == NULL) ? IP_DEFAULT_MULTICAST_TTL
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1698 : imo->imo_multicast_ttl;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1699 return (0);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1700
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1701 case IP_MULTICAST_LOOP:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1702 loop = mtod(*mp, u_char *);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1703 (*mp)->m_len = 1;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1704 *loop = (imo == NULL) ? IP_DEFAULT_MULTICAST_LOOP
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1705 : imo->imo_multicast_loop;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1706 return (0);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1707
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1708 default:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1709 return (EOPNOTSUPP);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1710 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1711 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1712
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1713 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1714 * Discard the IP multicast options.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1715 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1716 void
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1717 ip_freemoptions(imo)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1718 register struct ip_moptions *imo;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1719 {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1720 register int i;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1721
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1722 if (imo != NULL) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1723 for (i = 0; i < imo->imo_num_memberships; ++i)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1724 in_delmulti(imo->imo_membership[i]);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1725 free(imo, M_IPMOPTS);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1726 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1727 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1728
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1729 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1730 * Routine called from ip_output() to loop back a copy of an IP multicast
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1731 * packet to the input queue of a specified interface. Note that this
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1732 * calls the output routine of the loopback "driver", but with an interface
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1733 * pointer that might NOT be &loif -- easier than replicating that code here.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1734 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1735 static void
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1736 ip_mloopback(ifp, m, dst)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1737 struct ifnet *ifp;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1738 register struct mbuf *m;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1739 register struct sockaddr_in *dst;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1740 {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1741 register struct ip *ip;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1742 struct mbuf *copym;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1743
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1744 copym = m_copy(m, 0, M_COPYALL);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1745 if (copym != NULL) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1746 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1747 * We don't bother to fragment if the IP length is greater
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1748 * than the interface's MTU. Can this possibly matter?
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1749 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1750 ip = mtod(copym, struct ip *);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1751 ip->ip_len = htons((u_int16_t)ip->ip_len);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1752 ip->ip_off = htons((u_int16_t)ip->ip_off);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1753 ip->ip_sum = 0;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1754 ip->ip_sum = in_cksum(copym, ip->ip_hl << 2);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1755 (void) looutput(ifp, copym, sintosa(dst), NULL);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1756 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1757 }