2 * Copyright (c) 1982, 1986, 1988, 1993
3 * The Regents of the University of California. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * @(#)ip_input.c 8.2 (Berkeley) 1/4/94
36 #include <sys/param.h>
37 #include <sys/systm.h>
38 #include <sys/malloc.h>
40 #include <sys/domain.h>
41 #include <sys/protosw.h>
42 #include <sys/socket.h>
43 #include <sys/errno.h>
45 #include <sys/kernel.h>
46 #include <sys/syslog.h>
49 #include <sys/sysctl.h>
52 #include <net/route.h>
53 #include <net/netisr.h>
55 #include <netinet/in.h>
56 #include <netinet/in_systm.h>
57 #include <netinet/in_var.h>
58 #include <netinet/ip.h>
59 #include <netinet/in_pcb.h>
60 #include <netinet/in_var.h>
61 #include <netinet/ip_var.h>
62 #include <netinet/ip_icmp.h>
64 #include <netinet/ip_fw.h>
66 #include <sys/socketvar.h>
68 u_char inetctlerrmap
[PRC_NCMDS
] = {
70 0, EMSGSIZE
, EHOSTDOWN
, EHOSTUNREACH
,
71 EHOSTUNREACH
, EHOSTUNREACH
, ECONNREFUSED
, ECONNREFUSED
,
72 EMSGSIZE
, EHOSTUNREACH
, 0, 0,
77 struct in_ifaddr
*in_ifaddr
; /* first inet address */
78 int ip_defttl
= IPDEFTTL
;
82 * We need to save the IP options in case a protocol wants to respond
83 * to an incoming packet over the same route if the packet got here
84 * using IP source routing. This allows connection establishment and
85 * maintenance when the remote end is on a network that is not known
89 static struct ip_srcrt
{
90 struct in_addr dst
; /* final destination */
91 char nop
; /* one NOP to align */
92 char srcopt
[IPOPT_OFFSET
+ 1]; /* OPTVAL, OLEN and OFFSET */
93 struct in_addr route
[MAX_IPOPTLEN
/sizeof(struct in_addr
)];
97 * Strip out IP options, at higher
98 * level protocol in the kernel.
99 * Second argument is buffer to which options
100 * will be moved, and return value is their length.
101 * XXX should be deleted; last arg currently ignored.
104 ip_stripoptions(m
, mopt
)
105 register struct mbuf
*m
;
109 struct ip
*ip
= mtod(m
, struct ip
*);
110 register caddr_t opts
;
113 olen
= (ip
->ip_hl
<<2) - sizeof (struct ip
);
114 opts
= (caddr_t
)(ip
+ 1);
115 i
= m
->m_len
- (sizeof (struct ip
) + olen
);
116 bcopy(opts
+ olen
, opts
, (unsigned)i
);
118 if (m
->m_flags
& M_PKTHDR
)
119 m
->m_pkthdr
.len
-= olen
;
120 ip
->ip_hl
= sizeof(struct ip
) >> 2;
124 * Retrieve incoming source route for use in replies,
125 * in the same form used by setsockopt.
126 * The first hop is placed before the options, will be removed later.
131 register struct in_addr
*p
, *q
;
132 register struct mbuf
*m
;
135 return ((struct mbuf
*)0);
136 m
= m_get(M_DONTWAIT
, MT_SOOPTS
);
138 return ((struct mbuf
*)0);
140 #define OPTSIZ (sizeof(ip_srcrt.nop) + sizeof(ip_srcrt.srcopt))
142 /* length is (nhops+1)*sizeof(addr) + sizeof(nop + srcrt header) */
143 m
->m_len
= ip_nhops
* sizeof(struct in_addr
) + sizeof(struct in_addr
) +
147 printf("ip_srcroute: nhops %d mlen %d", ip_nhops
, m
->m_len
);
151 * First save first hop for return route
153 p
= &ip_srcrt
.route
[ip_nhops
- 1];
154 *(mtod(m
, struct in_addr
*)) = *p
--;
157 printf(" hops %lx", ntohl(mtod(m
, struct in_addr
*)->s_addr
));
161 * Copy option fields and padding (nop) to mbuf.
163 ip_srcrt
.nop
= IPOPT_NOP
;
164 ip_srcrt
.srcopt
[IPOPT_OFFSET
] = IPOPT_MINOFF
;
165 (void)memcpy(mtod(m
, caddr_t
) + sizeof(struct in_addr
),
166 &ip_srcrt
.nop
, OPTSIZ
);
167 q
= (struct in_addr
*)(mtod(m
, caddr_t
) +
168 sizeof(struct in_addr
) + OPTSIZ
);
171 * Record return path as an IP source route,
172 * reversing the path (pointers are now aligned).
174 while (p
>= ip_srcrt
.route
) {
177 printf(" %lx", ntohl(q
->s_addr
));
182 * Last hop goes to final destination.
187 printf(" %lx\n", ntohl(q
->s_addr
));