comparison packages/net/bsd_tcpip/current/src/sys/netinet/ip_output.c @ 208:e0c0827131d1 ecos

Merge from eCos master repository on 2002-05-20-20:11:54-BST
author jlarmour
date Mon, 20 May 2002 22:19:26 +0000
parents
children 56b339272cd4
comparison
equal deleted inserted replaced
207:74c807ddde34 208:e0c0827131d1
1 //==========================================================================
2 //
3 // src/sys/netinet/ip_output.c
4 //
5 //==========================================================================
6 //####BSDCOPYRIGHTBEGIN####
7 //
8 // -------------------------------------------
9 //
10 // Portions of this software may have been derived from OpenBSD,
11 // FreeBSD or other sources, and are covered by the appropriate
12 // copyright disclaimers included herein.
13 //
14 // Portions created by Red Hat are
15 // Copyright (C) 2002 Red Hat, Inc. All Rights Reserved.
16 //
17 // -------------------------------------------
18 //
19 //####BSDCOPYRIGHTEND####
20 //==========================================================================
21
22 /*
23 * Copyright (c) 1982, 1986, 1988, 1990, 1993
24 * The Regents of the University of California. All rights reserved.
25 *
26 * Redistribution and use in source and binary forms, with or without
27 * modification, are permitted provided that the following conditions
28 * are met:
29 * 1. Redistributions of source code must retain the above copyright
30 * notice, this list of conditions and the following disclaimer.
31 * 2. Redistributions in binary form must reproduce the above copyright
32 * notice, this list of conditions and the following disclaimer in the
33 * documentation and/or other materials provided with the distribution.
34 * 3. All advertising materials mentioning features or use of this software
35 * must display the following acknowledgement:
36 * This product includes software developed by the University of
37 * California, Berkeley and its contributors.
38 * 4. Neither the name of the University nor the names of its contributors
39 * may be used to endorse or promote products derived from this software
40 * without specific prior written permission.
41 *
42 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
43 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
44 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
45 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
46 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
47 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
48 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
49 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
50 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
51 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
52 * SUCH DAMAGE.
53 *
54 * @(#)ip_output.c 8.3 (Berkeley) 1/21/94
55 * $FreeBSD: src/sys/netinet/ip_output.c,v 1.99.2.16 2001/07/19 06:37:26 kris Exp $
56 */
57
58 #define _IP_VHL
59
60 #include <sys/param.h>
61 #include <sys/malloc.h>
62 #include <sys/mbuf.h>
63 #include <sys/protosw.h>
64 #include <sys/socket.h>
65 #include <sys/socketvar.h>
66
67 #include <net/if.h>
68 #include <net/route.h>
69
70 #include <netinet/in.h>
71 #include <netinet/in_systm.h>
72 #include <netinet/ip.h>
73 #include <netinet/in_pcb.h>
74 #include <netinet/in_var.h>
75 #include <netinet/ip_var.h>
76
77 #ifdef IPSEC
78 #include <netinet6/ipsec.h>
79 #include <netkey/key.h>
80 #ifdef IPSEC_DEBUG
81 #include <netkey/key_debug.h>
82 #else
83 #define KEYDEBUG(lev,arg)
84 #endif
85 #endif /*IPSEC*/
86
87 #include <netinet/ip_fw.h>
88
89 #ifdef DUMMYNET
90 #include <netinet/ip_dummynet.h>
91 #endif
92
93 #ifdef IPFIREWALL_FORWARD_DEBUG
94 #define print_ip(a) printf("%ld.%ld.%ld.%ld",(ntohl(a.s_addr)>>24)&0xFF,\
95 (ntohl(a.s_addr)>>16)&0xFF,\
96 (ntohl(a.s_addr)>>8)&0xFF,\
97 (ntohl(a.s_addr))&0xFF);
98 #endif
99
100 u_short ip_id;
101
102 static struct mbuf *ip_insertoptions __P((struct mbuf *, struct mbuf *, int *));
103 static struct ifnet *ip_multicast_if __P((struct in_addr *, int *));
104 static void ip_mloopback
105 __P((struct ifnet *, struct mbuf *, struct sockaddr_in *, int));
106 static int ip_getmoptions
107 __P((struct sockopt *, struct ip_moptions *));
108 static int ip_pcbopts __P((int, struct mbuf **, struct mbuf *));
109 static int ip_setmoptions
110 __P((struct sockopt *, struct ip_moptions **));
111
112 int ip_optcopy __P((struct ip *, struct ip *));
113 extern int (*fr_checkp) __P((struct ip *, int, struct ifnet *, int, struct mbuf **));
114
115
116 extern struct protosw inetsw[];
117
118 /*
119 * IP output. The packet in mbuf chain m contains a skeletal IP
120 * header (with len, off, ttl, proto, tos, src, dst).
121 * The mbuf chain containing the packet will be freed.
122 * The mbuf opt, if present, will not be freed.
123 */
124 int
125 ip_output(m0, opt, ro, flags, imo)
126 struct mbuf *m0;
127 struct mbuf *opt;
128 struct route *ro;
129 int flags;
130 struct ip_moptions *imo;
131 {
132 struct ip *ip, *mhip;
133 struct ifnet *ifp;
134 struct mbuf *m = m0;
135 int hlen = sizeof (struct ip);
136 int len, off, error = 0;
137 struct sockaddr_in *dst;
138 struct in_ifaddr *ia = NULL;
139 int isbroadcast, sw_csum;
140 #ifdef IPSEC
141 struct route iproute;
142 struct socket *so = NULL;
143 struct secpolicy *sp = NULL;
144 #endif
145 u_int16_t divert_cookie; /* firewall cookie */
146 #ifdef IPFIREWALL_FORWARD
147 int fwd_rewrite_src = 0;
148 #endif
149 struct ip_fw_chain *rule = NULL;
150
151 #ifdef IPDIVERT
152 /* Get and reset firewall cookie */
153 divert_cookie = ip_divert_cookie;
154 ip_divert_cookie = 0;
155 #else
156 divert_cookie = 0;
157 #endif
158
159 #if defined(IPFIREWALL) && defined(DUMMYNET)
160 /*
161 * dummynet packet are prepended a vestigial mbuf with
162 * m_type = MT_DUMMYNET and m_data pointing to the matching
163 * rule.
164 */
165 if (m->m_type == MT_DUMMYNET) {
166 /*
167 * the packet was already tagged, so part of the
168 * processing was already done, and we need to go down.
169 * Get parameters from the header.
170 */
171 rule = (struct ip_fw_chain *)(m->m_data) ;
172 opt = NULL ;
173 ro = & ( ((struct dn_pkt *)m)->ro ) ;
174 imo = NULL ;
175 dst = ((struct dn_pkt *)m)->dn_dst ;
176 ifp = ((struct dn_pkt *)m)->ifp ;
177 flags = ((struct dn_pkt *)m)->flags ;
178
179 m0 = m = m->m_next ;
180 #ifdef IPSEC
181 so = ipsec_getsocket(m);
182 (void)ipsec_setsocket(m, NULL);
183 #endif
184 ip = mtod(m, struct ip *);
185 hlen = IP_VHL_HL(ip->ip_vhl) << 2 ;
186 if (ro->ro_rt != NULL)
187 ia = (struct in_ifaddr *)ro->ro_rt->rt_ifa;
188 goto sendit;
189 } else
190 rule = NULL ;
191 #endif
192 #ifdef IPSEC
193 so = ipsec_getsocket(m);
194 (void)ipsec_setsocket(m, NULL);
195 #endif
196
197 #ifdef DIAGNOSTIC
198 if ((m->m_flags & M_PKTHDR) == 0)
199 panic("ip_output no HDR");
200 if (!ro)
201 panic("ip_output no route, proto = %d",
202 mtod(m, struct ip *)->ip_p);
203 #endif
204 if (opt) {
205 m = ip_insertoptions(m, opt, &len);
206 hlen = len;
207 }
208 ip = mtod(m, struct ip *);
209 /*
210 * Fill in IP header.
211 */
212 if ((flags & (IP_FORWARDING|IP_RAWOUTPUT)) == 0) {
213 ip->ip_vhl = IP_MAKE_VHL(IPVERSION, hlen >> 2);
214 ip->ip_off &= IP_DF;
215 #ifdef RANDOM_IP_ID
216 ip->ip_id = ip_randomid();
217 #else
218 ip->ip_id = htons(ip_id++);
219 #endif
220 ipstat.ips_localout++;
221 } else {
222 hlen = IP_VHL_HL(ip->ip_vhl) << 2;
223 }
224
225 dst = (struct sockaddr_in *)&ro->ro_dst;
226 /*
227 * If there is a cached route,
228 * check that it is to the same destination
229 * and is still up. If not, free it and try again.
230 */
231 if (ro->ro_rt && ((ro->ro_rt->rt_flags & RTF_UP) == 0 ||
232 dst->sin_addr.s_addr != ip->ip_dst.s_addr)) {
233 RTFREE(ro->ro_rt);
234 ro->ro_rt = (struct rtentry *)0;
235 }
236 if (ro->ro_rt == 0) {
237 dst->sin_family = AF_INET;
238 dst->sin_len = sizeof(*dst);
239 dst->sin_addr = ip->ip_dst;
240 }
241 /*
242 * If routing to interface only,
243 * short circuit routing lookup.
244 */
245 #define ifatoia(ifa) ((struct in_ifaddr *)(ifa))
246 #define sintosa(sin) ((struct sockaddr *)(sin))
247 if (flags & IP_ROUTETOIF) {
248 if ((ia = ifatoia(ifa_ifwithdstaddr(sintosa(dst)))) == 0 &&
249 (ia = ifatoia(ifa_ifwithnet(sintosa(dst)))) == 0) {
250 ipstat.ips_noroute++;
251 error = ENETUNREACH;
252 goto bad;
253 }
254 ifp = ia->ia_ifp;
255 ip->ip_ttl = 1;
256 isbroadcast = in_broadcast(dst->sin_addr, ifp);
257 } else {
258 /*
259 * If this is the case, we probably don't want to allocate
260 * a protocol-cloned route since we didn't get one from the
261 * ULP. This lets TCP do its thing, while not burdening
262 * forwarding or ICMP with the overhead of cloning a route.
263 * Of course, we still want to do any cloning requested by
264 * the link layer, as this is probably required in all cases
265 * for correct operation (as it is for ARP).
266 */
267 if (ro->ro_rt == 0)
268 rtalloc_ign(ro, RTF_PRCLONING);
269 if (ro->ro_rt == 0) {
270 ipstat.ips_noroute++;
271 error = EHOSTUNREACH;
272 goto bad;
273 }
274 ia = ifatoia(ro->ro_rt->rt_ifa);
275 ifp = ro->ro_rt->rt_ifp;
276 ro->ro_rt->rt_use++;
277 if (ro->ro_rt->rt_flags & RTF_GATEWAY)
278 dst = (struct sockaddr_in *)ro->ro_rt->rt_gateway;
279 if (ro->ro_rt->rt_flags & RTF_HOST)
280 isbroadcast = (ro->ro_rt->rt_flags & RTF_BROADCAST);
281 else
282 isbroadcast = in_broadcast(dst->sin_addr, ifp);
283 }
284 if (IN_MULTICAST(ntohl(ip->ip_dst.s_addr))) {
285 struct in_multi *inm;
286
287 m->m_flags |= M_MCAST;
288 /*
289 * IP destination address is multicast. Make sure "dst"
290 * still points to the address in "ro". (It may have been
291 * changed to point to a gateway address, above.)
292 */
293 dst = (struct sockaddr_in *)&ro->ro_dst;
294 /*
295 * See if the caller provided any multicast options
296 */
297 if (imo != NULL) {
298 ip->ip_ttl = imo->imo_multicast_ttl;
299 if (imo->imo_multicast_ifp != NULL)
300 ifp = imo->imo_multicast_ifp;
301 if (imo->imo_multicast_vif != -1)
302 ip->ip_src.s_addr =
303 ip_mcast_src(imo->imo_multicast_vif);
304 } else
305 ip->ip_ttl = IP_DEFAULT_MULTICAST_TTL;
306 /*
307 * Confirm that the outgoing interface supports multicast.
308 */
309 if ((imo == NULL) || (imo->imo_multicast_vif == -1)) {
310 if ((ifp->if_flags & IFF_MULTICAST) == 0) {
311 ipstat.ips_noroute++;
312 error = ENETUNREACH;
313 goto bad;
314 }
315 }
316 /*
317 * If source address not specified yet, use address
318 * of outgoing interface.
319 */
320 if (ip->ip_src.s_addr == INADDR_ANY) {
321 register struct in_ifaddr *ia1;
322
323 TAILQ_FOREACH(ia1, &in_ifaddrhead, ia_link)
324 if (ia1->ia_ifp == ifp) {
325 ip->ip_src = IA_SIN(ia1)->sin_addr;
326 break;
327 }
328 }
329
330 IN_LOOKUP_MULTI(ip->ip_dst, ifp, inm);
331 if (inm != NULL &&
332 (imo == NULL || imo->imo_multicast_loop)) {
333 /*
334 * If we belong to the destination multicast group
335 * on the outgoing interface, and the caller did not
336 * forbid loopback, loop back a copy.
337 */
338 ip_mloopback(ifp, m, dst, hlen);
339 }
340 else {
341 /*
342 * If we are acting as a multicast router, perform
343 * multicast forwarding as if the packet had just
344 * arrived on the interface to which we are about
345 * to send. The multicast forwarding function
346 * recursively calls this function, using the
347 * IP_FORWARDING flag to prevent infinite recursion.
348 *
349 * Multicasts that are looped back by ip_mloopback(),
350 * above, will be forwarded by the ip_input() routine,
351 * if necessary.
352 */
353 if (ip_mrouter && (flags & IP_FORWARDING) == 0) {
354 /*
355 * Check if rsvp daemon is running. If not, don't
356 * set ip_moptions. This ensures that the packet
357 * is multicast and not just sent down one link
358 * as prescribed by rsvpd.
359 */
360 if (!rsvp_on)
361 imo = NULL;
362 if (ip_mforward(ip, ifp, m, imo) != 0) {
363 m_freem(m);
364 goto done;
365 }
366 }
367 }
368
369 /*
370 * Multicasts with a time-to-live of zero may be looped-
371 * back, above, but must not be transmitted on a network.
372 * Also, multicasts addressed to the loopback interface
373 * are not sent -- the above call to ip_mloopback() will
374 * loop back a copy if this host actually belongs to the
375 * destination group on the loopback interface.
376 */
377 if (ip->ip_ttl == 0 || ifp->if_flags & IFF_LOOPBACK) {
378 m_freem(m);
379 goto done;
380 }
381
382 goto sendit;
383 }
384 #ifndef notdef
385 /*
386 * If source address not specified yet, use address
387 * of outgoing interface.
388 */
389 if (ip->ip_src.s_addr == INADDR_ANY) {
390 ip->ip_src = IA_SIN(ia)->sin_addr;
391 #ifdef IPFIREWALL_FORWARD
392 /* Keep note that we did this - if the firewall changes
393 * the next-hop, our interface may change, changing the
394 * default source IP. It's a shame so much effort happens
395 * twice. Oh well.
396 */
397 fwd_rewrite_src++;
398 #endif /* IPFIREWALL_FORWARD */
399 }
400 #endif /* notdef */
401 #ifdef ALTQ
402 /*
403 * disable packet drop hack.
404 * packetdrop should be done by queueing.
405 */
406 #else /* !ALTQ */
407 /*
408 * Verify that we have any chance at all of being able to queue
409 * the packet or packet fragments
410 */
411 if ((ifp->if_snd.ifq_len + ip->ip_len / ifp->if_mtu + 1) >=
412 ifp->if_snd.ifq_maxlen) {
413 error = ENOBUFS;
414 goto bad;
415 }
416 #endif /* !ALTQ */
417
418 /*
419 * Look for broadcast address and
420 * and verify user is allowed to send
421 * such a packet.
422 */
423 if (isbroadcast) {
424 if ((ifp->if_flags & IFF_BROADCAST) == 0) {
425 error = EADDRNOTAVAIL;
426 goto bad;
427 }
428 if ((flags & IP_ALLOWBROADCAST) == 0) {
429 error = EACCES;
430 goto bad;
431 }
432 /* don't allow broadcast messages to be fragmented */
433 if ((u_short)ip->ip_len > ifp->if_mtu) {
434 error = EMSGSIZE;
435 goto bad;
436 }
437 m->m_flags |= M_BCAST;
438 } else {
439 m->m_flags &= ~M_BCAST;
440 }
441
442 sendit:
443 #ifdef IPSEC
444 /* get SP for this packet */
445 if (so == NULL)
446 sp = ipsec4_getpolicybyaddr(m, IPSEC_DIR_OUTBOUND, flags, &error);
447 else
448 sp = ipsec4_getpolicybysock(m, IPSEC_DIR_OUTBOUND, so, &error);
449
450 if (sp == NULL) {
451 ipsecstat.out_inval++;
452 goto bad;
453 }
454
455 error = 0;
456
457 /* check policy */
458 switch (sp->policy) {
459 case IPSEC_POLICY_DISCARD:
460 /*
461 * This packet is just discarded.
462 */
463 ipsecstat.out_polvio++;
464 goto bad;
465
466 case IPSEC_POLICY_BYPASS:
467 case IPSEC_POLICY_NONE:
468 /* no need to do IPsec. */
469 goto skip_ipsec;
470
471 case IPSEC_POLICY_IPSEC:
472 if (sp->req == NULL) {
473 /* acquire a policy */
474 error = key_spdacquire(sp);
475 goto bad;
476 }
477 break;
478
479 case IPSEC_POLICY_ENTRUST:
480 default:
481 printf("ip_output: Invalid policy found. %d\n", sp->policy);
482 }
483 {
484 struct ipsec_output_state state;
485 bzero(&state, sizeof(state));
486 state.m = m;
487 if (flags & IP_ROUTETOIF) {
488 state.ro = &iproute;
489 bzero(&iproute, sizeof(iproute));
490 } else
491 state.ro = ro;
492 state.dst = (struct sockaddr *)dst;
493
494 ip->ip_sum = 0;
495
496 /*
497 * XXX
498 * delayed checksums are not currently compatible with IPsec
499 */
500 if (m->m_pkthdr.csum_flags & CSUM_DELAY_DATA) {
501 in_delayed_cksum(m);
502 m->m_pkthdr.csum_flags &= ~CSUM_DELAY_DATA;
503 }
504
505 HTONS(ip->ip_len);
506 HTONS(ip->ip_off);
507
508 error = ipsec4_output(&state, sp, flags);
509
510 m = state.m;
511 if (flags & IP_ROUTETOIF) {
512 /*
513 * if we have tunnel mode SA, we may need to ignore
514 * IP_ROUTETOIF.
515 */
516 if (state.ro != &iproute || state.ro->ro_rt != NULL) {
517 flags &= ~IP_ROUTETOIF;
518 ro = state.ro;
519 }
520 } else
521 ro = state.ro;
522 dst = (struct sockaddr_in *)state.dst;
523 if (error) {
524 /* mbuf is already reclaimed in ipsec4_output. */
525 m0 = NULL;
526 switch (error) {
527 case EHOSTUNREACH:
528 case ENETUNREACH:
529 case EMSGSIZE:
530 case ENOBUFS:
531 case ENOMEM:
532 break;
533 default:
534 printf("ip4_output (ipsec): error code %d\n", error);
535 /*fall through*/
536 case ENOENT:
537 /* don't show these error codes to the user */
538 error = 0;
539 break;
540 }
541 goto bad;
542 }
543
544 /* be sure to update variables that are affected by ipsec4_output() */
545 ip = mtod(m, struct ip *);
546 #ifdef _IP_VHL
547 hlen = IP_VHL_HL(ip->ip_vhl) << 2;
548 #else
549 hlen = ip->ip_hl << 2;
550 #endif
551 if (ro->ro_rt == NULL) {
552 if ((flags & IP_ROUTETOIF) == 0) {
553 printf("ip_output: "
554 "can't update route after IPsec processing\n");
555 error = EHOSTUNREACH; /*XXX*/
556 goto bad;
557 }
558 } else {
559 if (state.encap) {
560 ia = ifatoia(ro->ro_rt->rt_ifa);
561 ifp = ro->ro_rt->rt_ifp;
562 }
563 }
564 }
565
566 /* make it flipped, again. */
567 NTOHS(ip->ip_len);
568 NTOHS(ip->ip_off);
569 skip_ipsec:
570 #endif /*IPSEC*/
571
572 /*
573 * IpHack's section.
574 * - Xlate: translate packet's addr/port (NAT).
575 * - Firewall: deny/allow/etc.
576 * - Wrap: fake packet's addr/port <unimpl.>
577 * - Encapsulate: put it in another IP and send out. <unimp.>
578 */
579 if (fr_checkp) {
580 struct mbuf *m1 = m;
581
582 if ((error = (*fr_checkp)(ip, hlen, ifp, 1, &m1)) || !m1)
583 goto done;
584 ip = mtod(m = m1, struct ip *);
585 }
586
587 /*
588 * Check with the firewall...
589 */
590 if (fw_enable && ip_fw_chk_ptr) {
591 struct sockaddr_in *old = dst;
592
593 off = (*ip_fw_chk_ptr)(&ip,
594 hlen, ifp, &divert_cookie, &m, &rule, &dst);
595 /*
596 * On return we must do the following:
597 * IP_FW_PORT_DENY_FLAG -> drop the pkt (XXX new)
598 * 1<=off<= 0xffff -> DIVERT
599 * (off & IP_FW_PORT_DYNT_FLAG) -> send to a DUMMYNET pipe
600 * (off & IP_FW_PORT_TEE_FLAG) -> TEE the packet
601 * dst != old -> IPFIREWALL_FORWARD
602 * off==0, dst==old -> accept
603 * If some of the above modules is not compiled in, then
604 * we should't have to check the corresponding condition
605 * (because the ipfw control socket should not accept
606 * unsupported rules), but better play safe and drop
607 * packets in case of doubt.
608 */
609 if ( (off & IP_FW_PORT_DENY_FLAG) || m == NULL) {
610 if (m)
611 m_freem(m);
612 error = EACCES ;
613 goto done ;
614 }
615 ip = mtod(m, struct ip *);
616 if (off == 0 && dst == old) /* common case */
617 goto pass ;
618 #ifdef DUMMYNET
619 if ((off & IP_FW_PORT_DYNT_FLAG) != 0) {
620 /*
621 * pass the pkt to dummynet. Need to include
622 * pipe number, m, ifp, ro, dst because these are
623 * not recomputed in the next pass.
624 * All other parameters have been already used and
625 * so they are not needed anymore.
626 * XXX note: if the ifp or ro entry are deleted
627 * while a pkt is in dummynet, we are in trouble!
628 */
629 error = dummynet_io(off & 0xffff, DN_TO_IP_OUT, m,
630 ifp,ro,dst,rule, flags);
631 goto done;
632 }
633 #endif
634 #ifdef IPDIVERT
635 if (off != 0 && (off & IP_FW_PORT_DYNT_FLAG) == 0) {
636 struct mbuf *clone = NULL;
637
638 /* Clone packet if we're doing a 'tee' */
639 if ((off & IP_FW_PORT_TEE_FLAG) != 0)
640 clone = m_dup(m, M_DONTWAIT);
641
642 /*
643 * XXX
644 * delayed checksums are not currently compatible
645 * with divert sockets.
646 */
647 if (m->m_pkthdr.csum_flags & CSUM_DELAY_DATA) {
648 in_delayed_cksum(m);
649 m->m_pkthdr.csum_flags &= ~CSUM_DELAY_DATA;
650 }
651
652 /* Restore packet header fields to original values */
653 HTONS(ip->ip_len);
654 HTONS(ip->ip_off);
655
656 /* Deliver packet to divert input routine */
657 ip_divert_cookie = divert_cookie;
658 divert_packet(m, 0, off & 0xffff);
659
660 /* If 'tee', continue with original packet */
661 if (clone != NULL) {
662 m = clone;
663 ip = mtod(m, struct ip *);
664 goto pass;
665 }
666 goto done;
667 }
668 #endif
669
670 #ifdef IPFIREWALL_FORWARD
671 /* Here we check dst to make sure it's directly reachable on the
672 * interface we previously thought it was.
673 * If it isn't (which may be likely in some situations) we have
674 * to re-route it (ie, find a route for the next-hop and the
675 * associated interface) and set them here. This is nested
676 * forwarding which in most cases is undesirable, except where
677 * such control is nigh impossible. So we do it here.
678 * And I'm babbling.
679 */
680 if (off == 0 && old != dst) {
681 struct in_ifaddr *ia;
682
683 /* It's changed... */
684 /* There must be a better way to do this next line... */
685 static struct route sro_fwd, *ro_fwd = &sro_fwd;
686 #ifdef IPFIREWALL_FORWARD_DEBUG
687 printf("IPFIREWALL_FORWARD: New dst ip: ");
688 print_ip(dst->sin_addr);
689 printf("\n");
690 #endif
691 /*
692 * We need to figure out if we have been forwarded
693 * to a local socket. If so then we should somehow
694 * "loop back" to ip_input, and get directed to the
695 * PCB as if we had received this packet. This is
696 * because it may be dificult to identify the packets
697 * you want to forward until they are being output
698 * and have selected an interface. (e.g. locally
699 * initiated packets) If we used the loopback inteface,
700 * we would not be able to control what happens
701 * as the packet runs through ip_input() as
702 * it is done through a ISR.
703 */
704 TAILQ_FOREACH(ia, &in_ifaddrhead, ia_link) {
705 /*
706 * If the addr to forward to is one
707 * of ours, we pretend to
708 * be the destination for this packet.
709 */
710 if (IA_SIN(ia)->sin_addr.s_addr ==
711 dst->sin_addr.s_addr)
712 break;
713 }
714 if (ia) {
715 /* tell ip_input "dont filter" */
716 ip_fw_fwd_addr = dst;
717 if (m->m_pkthdr.rcvif == NULL)
718 m->m_pkthdr.rcvif = ifunit("lo0");
719 if (m->m_pkthdr.csum_flags & CSUM_DELAY_DATA) {
720 m->m_pkthdr.csum_flags |=
721 CSUM_DATA_VALID | CSUM_PSEUDO_HDR;
722 m0->m_pkthdr.csum_data = 0xffff;
723 }
724 m->m_pkthdr.csum_flags |=
725 CSUM_IP_CHECKED | CSUM_IP_VALID;
726 HTONS(ip->ip_len);
727 HTONS(ip->ip_off);
728 ip_input(m);
729 goto done;
730 }
731 /* Some of the logic for this was
732 * nicked from above.
733 *
734 * This rewrites the cached route in a local PCB.
735 * Is this what we want to do?
736 */
737 bcopy(dst, &ro_fwd->ro_dst, sizeof(*dst));
738
739 ro_fwd->ro_rt = 0;
740 rtalloc_ign(ro_fwd, RTF_PRCLONING);
741
742 if (ro_fwd->ro_rt == 0) {
743 ipstat.ips_noroute++;
744 error = EHOSTUNREACH;
745 goto bad;
746 }
747
748 ia = ifatoia(ro_fwd->ro_rt->rt_ifa);
749 ifp = ro_fwd->ro_rt->rt_ifp;
750 ro_fwd->ro_rt->rt_use++;
751 if (ro_fwd->ro_rt->rt_flags & RTF_GATEWAY)
752 dst = (struct sockaddr_in *)ro_fwd->ro_rt->rt_gateway;
753 if (ro_fwd->ro_rt->rt_flags & RTF_HOST)
754 isbroadcast =
755 (ro_fwd->ro_rt->rt_flags & RTF_BROADCAST);
756 else
757 isbroadcast = in_broadcast(dst->sin_addr, ifp);
758 RTFREE(ro->ro_rt);
759 ro->ro_rt = ro_fwd->ro_rt;
760 dst = (struct sockaddr_in *)&ro_fwd->ro_dst;
761
762 /*
763 * If we added a default src ip earlier,
764 * which would have been gotten from the-then
765 * interface, do it again, from the new one.
766 */
767 if (fwd_rewrite_src)
768 ip->ip_src = IA_SIN(ia)->sin_addr;
769 goto pass ;
770 }
771 #endif /* IPFIREWALL_FORWARD */
772 /*
773 * if we get here, none of the above matches, and
774 * we have to drop the pkt
775 */
776 m_freem(m);
777 error = EACCES; /* not sure this is the right error msg */
778 goto done;
779 }
780
781 pass:
782 m->m_pkthdr.csum_flags |= CSUM_IP;
783 sw_csum = m->m_pkthdr.csum_flags & ~ifp->if_hwassist;
784 if (sw_csum & CSUM_DELAY_DATA) {
785 in_delayed_cksum(m);
786 sw_csum &= ~CSUM_DELAY_DATA;
787 }
788 m->m_pkthdr.csum_flags &= ifp->if_hwassist;
789
790 /*
791 * If small enough for interface, or the interface will take
792 * care of the fragmentation for us, can just send directly.
793 */
794 if ((u_short)ip->ip_len <= ifp->if_mtu ||
795 ifp->if_hwassist & CSUM_FRAGMENT) {
796 HTONS(ip->ip_len);
797 HTONS(ip->ip_off);
798 ip->ip_sum = 0;
799 if (sw_csum & CSUM_DELAY_IP) {
800 if (ip->ip_vhl == IP_VHL_BORING) {
801 ip->ip_sum = in_cksum_hdr(ip);
802 } else {
803 ip->ip_sum = in_cksum(m, hlen);
804 }
805 }
806
807 /* Record statistics for this interface address. */
808 if (!(flags & IP_FORWARDING) && ia != NULL) {
809 ia->ia_ifa.if_opackets++;
810 ia->ia_ifa.if_obytes += m->m_pkthdr.len;
811 }
812
813 #ifdef IPSEC
814 /* clean ipsec history once it goes out of the node */
815 ipsec_delaux(m);
816 #endif
817
818 error = (*ifp->if_output)(ifp, m,
819 (struct sockaddr *)dst, ro->ro_rt);
820 goto done;
821 }
822 /*
823 * Too large for interface; fragment if possible.
824 * Must be able to put at least 8 bytes per fragment.
825 */
826 if (ip->ip_off & IP_DF) {
827 error = EMSGSIZE;
828 /*
829 * This case can happen if the user changed the MTU
830 * of an interface after enabling IP on it. Because
831 * most netifs don't keep track of routes pointing to
832 * them, there is no way for one to update all its
833 * routes when the MTU is changed.
834 */
835 if ((ro->ro_rt->rt_flags & (RTF_UP | RTF_HOST))
836 && !(ro->ro_rt->rt_rmx.rmx_locks & RTV_MTU)
837 && (ro->ro_rt->rt_rmx.rmx_mtu > ifp->if_mtu)) {
838 ro->ro_rt->rt_rmx.rmx_mtu = ifp->if_mtu;
839 }
840 ipstat.ips_cantfrag++;
841 goto bad;
842 }
843 len = (ifp->if_mtu - hlen) &~ 7;
844 if (len < 8) {
845 error = EMSGSIZE;
846 goto bad;
847 }
848
849 /*
850 * if the interface will not calculate checksums on
851 * fragmented packets, then do it here.
852 */
853 if (m->m_pkthdr.csum_flags & CSUM_DELAY_DATA &&
854 (ifp->if_hwassist & CSUM_IP_FRAGS) == 0) {
855 in_delayed_cksum(m);
856 m->m_pkthdr.csum_flags &= ~CSUM_DELAY_DATA;
857 }
858
859 {
860 int mhlen, firstlen = len;
861 struct mbuf **mnext = &m->m_nextpkt;
862 int nfrags = 1;
863
864 /*
865 * Loop through length of segment after first fragment,
866 * make new header and copy data of each part and link onto chain.
867 */
868 m0 = m;
869 mhlen = sizeof (struct ip);
870 for (off = hlen + len; off < (u_short)ip->ip_len; off += len) {
871 MGETHDR(m, M_DONTWAIT, MT_HEADER);
872 if (m == 0) {
873 error = ENOBUFS;
874 ipstat.ips_odropped++;
875 goto sendorfree;
876 }
877 m->m_flags |= (m0->m_flags & M_MCAST) | M_FRAG;
878 m->m_data += max_linkhdr;
879 mhip = mtod(m, struct ip *);
880 *mhip = *ip;
881 if (hlen > sizeof (struct ip)) {
882 mhlen = ip_optcopy(ip, mhip) + sizeof (struct ip);
883 mhip->ip_vhl = IP_MAKE_VHL(IPVERSION, mhlen >> 2);
884 }
885 m->m_len = mhlen;
886 mhip->ip_off = ((off - hlen) >> 3) + (ip->ip_off & ~IP_MF);
887 if (ip->ip_off & IP_MF)
888 mhip->ip_off |= IP_MF;
889 if (off + len >= (u_short)ip->ip_len)
890 len = (u_short)ip->ip_len - off;
891 else
892 mhip->ip_off |= IP_MF;
893 mhip->ip_len = htons((u_short)(len + mhlen));
894 m->m_next = m_copy(m0, off, len);
895 if (m->m_next == 0) {
896 (void) m_free(m);
897 error = ENOBUFS; /* ??? */
898 ipstat.ips_odropped++;
899 goto sendorfree;
900 }
901 m->m_pkthdr.len = mhlen + len;
902 m->m_pkthdr.rcvif = (struct ifnet *)0;
903 m->m_pkthdr.csum_flags = m0->m_pkthdr.csum_flags;
904 HTONS(mhip->ip_off);
905 mhip->ip_sum = 0;
906 if (sw_csum & CSUM_DELAY_IP) {
907 if (mhip->ip_vhl == IP_VHL_BORING) {
908 mhip->ip_sum = in_cksum_hdr(mhip);
909 } else {
910 mhip->ip_sum = in_cksum(m, mhlen);
911 }
912 }
913 *mnext = m;
914 mnext = &m->m_nextpkt;
915 nfrags++;
916 }
917 ipstat.ips_ofragments += nfrags;
918
919 /* set first/last markers for fragment chain */
920 m->m_flags |= M_LASTFRAG;
921 m0->m_flags |= M_FIRSTFRAG | M_FRAG;
922 m0->m_pkthdr.csum_data = nfrags;
923
924 /*
925 * Update first fragment by trimming what's been copied out
926 * and updating header, then send each fragment (in order).
927 */
928 m = m0;
929 m_adj(m, hlen + firstlen - (u_short)ip->ip_len);
930 m->m_pkthdr.len = hlen + firstlen;
931 ip->ip_len = htons((u_short)m->m_pkthdr.len);
932 ip->ip_off |= IP_MF;
933 HTONS(ip->ip_off);
934 ip->ip_sum = 0;
935 if (sw_csum & CSUM_DELAY_IP) {
936 if (ip->ip_vhl == IP_VHL_BORING) {
937 ip->ip_sum = in_cksum_hdr(ip);
938 } else {
939 ip->ip_sum = in_cksum(m, hlen);
940 }
941 }
942 sendorfree:
943 for (m = m0; m; m = m0) {
944 m0 = m->m_nextpkt;
945 m->m_nextpkt = 0;
946 #ifdef IPSEC
947 /* clean ipsec history once it goes out of the node */
948 ipsec_delaux(m);
949 #endif
950 if (error == 0) {
951 /* Record statistics for this interface address. */
952 if (ia != NULL) {
953 ia->ia_ifa.if_opackets++;
954 ia->ia_ifa.if_obytes += m->m_pkthdr.len;
955 }
956
957 error = (*ifp->if_output)(ifp, m,
958 (struct sockaddr *)dst, ro->ro_rt);
959 } else
960 m_freem(m);
961 }
962
963 if (error == 0)
964 ipstat.ips_fragmented++;
965 }
966 done:
967 #ifdef IPSEC
968 if (ro == &iproute && ro->ro_rt) {
969 RTFREE(ro->ro_rt);
970 ro->ro_rt = NULL;
971 }
972 if (sp != NULL) {
973 KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
974 printf("DP ip_output call free SP:%p\n", sp));
975 key_freesp(sp);
976 }
977 #endif /* IPSEC */
978 return (error);
979 bad:
980 m_freem(m0);
981 goto done;
982 }
983
984 void
985 in_delayed_cksum(struct mbuf *m)
986 {
987 struct ip *ip;
988 u_short csum, offset;
989
990 ip = mtod(m, struct ip *);
991 offset = IP_VHL_HL(ip->ip_vhl) << 2 ;
992 csum = in_cksum_skip(m, ip->ip_len, offset);
993 if (m->m_pkthdr.csum_flags & CSUM_UDP && csum == 0)
994 csum = 0xffff;
995 offset += m->m_pkthdr.csum_data; /* checksum offset */
996
997 if (offset + sizeof(u_short) > m->m_len) {
998 printf("delayed m_pullup, m->len: %d off: %d p: %d\n",
999 m->m_len, offset, ip->ip_p);
1000 /*
1001 * XXX
1002 * this shouldn't happen, but if it does, the
1003 * correct behavior may be to insert the checksum
1004 * in the existing chain instead of rearranging it.
1005 */
1006 m = m_pullup(m, offset + sizeof(u_short));
1007 }
1008 *(u_short *)(m->m_data + offset) = csum;
1009 }
1010
1011 /*
1012 * Insert IP options into preformed packet.
1013 * Adjust IP destination as required for IP source routing,
1014 * as indicated by a non-zero in_addr at the start of the options.
1015 *
1016 * XXX This routine assumes that the packet has no options in place.
1017 */
1018 static struct mbuf *
1019 ip_insertoptions(m, opt, phlen)
1020 register struct mbuf *m;
1021 struct mbuf *opt;
1022 int *phlen;
1023 {
1024 register struct ipoption *p = mtod(opt, struct ipoption *);
1025 struct mbuf *n;
1026 register struct ip *ip = mtod(m, struct ip *);
1027 unsigned optlen;
1028
1029 optlen = opt->m_len - sizeof(p->ipopt_dst);
1030 if (optlen + (u_short)ip->ip_len > IP_MAXPACKET)
1031 return (m); /* XXX should fail */
1032 if (p->ipopt_dst.s_addr)
1033 ip->ip_dst = p->ipopt_dst;
1034 if (m->m_flags & M_EXT || m->m_data - optlen < m->m_pktdat) {
1035 MGETHDR(n, M_DONTWAIT, MT_HEADER);
1036 if (n == 0)
1037 return (m);
1038 n->m_pkthdr.rcvif = (struct ifnet *)0;
1039 n->m_pkthdr.len = m->m_pkthdr.len + optlen;
1040 m->m_len -= sizeof(struct ip);
1041 m->m_data += sizeof(struct ip);
1042 n->m_next = m;
1043 m = n;
1044 m->m_len = optlen + sizeof(struct ip);
1045 m->m_data += max_linkhdr;
1046 (void)memcpy(mtod(m, void *), ip, sizeof(struct ip));
1047 } else {
1048 m->m_data -= optlen;
1049 m->m_len += optlen;
1050 m->m_pkthdr.len += optlen;
1051 ovbcopy((caddr_t)ip, mtod(m, caddr_t), sizeof(struct ip));
1052 }
1053 ip = mtod(m, struct ip *);
1054 bcopy(p->ipopt_list, ip + 1, optlen);
1055 *phlen = sizeof(struct ip) + optlen;
1056 ip->ip_vhl = IP_MAKE_VHL(IPVERSION, *phlen >> 2);
1057 ip->ip_len += optlen;
1058 return (m);
1059 }
1060
1061 /*
1062 * Copy options from ip to jp,
1063 * omitting those not copied during fragmentation.
1064 */
1065 int
1066 ip_optcopy(ip, jp)
1067 struct ip *ip, *jp;
1068 {
1069 register u_char *cp, *dp;
1070 int opt, optlen, cnt;
1071
1072 cp = (u_char *)(ip + 1);
1073 dp = (u_char *)(jp + 1);
1074 cnt = (IP_VHL_HL(ip->ip_vhl) << 2) - sizeof (struct ip);
1075 for (; cnt > 0; cnt -= optlen, cp += optlen) {
1076 opt = cp[0];
1077 if (opt == IPOPT_EOL)
1078 break;
1079 if (opt == IPOPT_NOP) {
1080 /* Preserve for IP mcast tunnel's LSRR alignment. */
1081 *dp++ = IPOPT_NOP;
1082 optlen = 1;
1083 continue;
1084 }
1085 #ifdef DIAGNOSTIC
1086 if (cnt < IPOPT_OLEN + sizeof(*cp))
1087 panic("malformed IPv4 option passed to ip_optcopy");
1088 #endif
1089 optlen = cp[IPOPT_OLEN];
1090 #ifdef DIAGNOSTIC
1091 if (optlen < IPOPT_OLEN + sizeof(*cp) || optlen > cnt)
1092 panic("malformed IPv4 option passed to ip_optcopy");
1093 #endif
1094 /* bogus lengths should have been caught by ip_dooptions */
1095 if (optlen > cnt)
1096 optlen = cnt;
1097 if (IPOPT_COPIED(opt)) {
1098 bcopy(cp, dp, optlen);
1099 dp += optlen;
1100 }
1101 }
1102 for (optlen = dp - (u_char *)(jp+1); optlen & 0x3; optlen++)
1103 *dp++ = IPOPT_EOL;
1104 return (optlen);
1105 }
1106
1107 /*
1108 * IP socket option processing.
1109 */
1110 int
1111 ip_ctloutput(so, sopt)
1112 struct socket *so;
1113 struct sockopt *sopt;
1114 {
1115 struct inpcb *inp = sotoinpcb(so);
1116 int error, optval;
1117
1118 error = optval = 0;
1119 if (sopt->sopt_level != IPPROTO_IP) {
1120 return (EINVAL);
1121 }
1122
1123 switch (sopt->sopt_dir) {
1124 case SOPT_SET:
1125 switch (sopt->sopt_name) {
1126 case IP_OPTIONS:
1127 #ifdef notyet
1128 case IP_RETOPTS:
1129 #endif
1130 {
1131 struct mbuf *m;
1132 if (sopt->sopt_valsize > MLEN) {
1133 error = EMSGSIZE;
1134 break;
1135 }
1136 MGET(m, sopt->sopt_p ? M_WAIT : M_DONTWAIT, MT_HEADER);
1137 if (m == 0) {
1138 error = ENOBUFS;
1139 break;
1140 }
1141 m->m_len = sopt->sopt_valsize;
1142 error = sooptcopyin(sopt, mtod(m, char *), m->m_len,
1143 m->m_len);
1144
1145 return (ip_pcbopts(sopt->sopt_name, &inp->inp_options,
1146 m));
1147 }
1148
1149 case IP_TOS:
1150 case IP_TTL:
1151 case IP_RECVOPTS:
1152 case IP_RECVRETOPTS:
1153 case IP_RECVDSTADDR:
1154 case IP_RECVIF:
1155 #if defined(NFAITH) && NFAITH > 0
1156 case IP_FAITH:
1157 #endif
1158 error = sooptcopyin(sopt, &optval, sizeof optval,
1159 sizeof optval);
1160 if (error)
1161 break;
1162
1163 switch (sopt->sopt_name) {
1164 case IP_TOS:
1165 inp->inp_ip_tos = optval;
1166 break;
1167
1168 case IP_TTL:
1169 inp->inp_ip_ttl = optval;
1170 break;
1171 #define OPTSET(bit) \
1172 if (optval) \
1173 inp->inp_flags |= bit; \
1174 else \
1175 inp->inp_flags &= ~bit;
1176
1177 case IP_RECVOPTS:
1178 OPTSET(INP_RECVOPTS);
1179 break;
1180
1181 case IP_RECVRETOPTS:
1182 OPTSET(INP_RECVRETOPTS);
1183 break;
1184
1185 case IP_RECVDSTADDR:
1186 OPTSET(INP_RECVDSTADDR);
1187 break;
1188
1189 case IP_RECVIF:
1190 OPTSET(INP_RECVIF);
1191 break;
1192
1193 #if defined(NFAITH) && NFAITH > 0
1194 case IP_FAITH:
1195 OPTSET(INP_FAITH);
1196 break;
1197 #endif
1198 }
1199 break;
1200 #undef OPTSET
1201
1202 case IP_MULTICAST_IF:
1203 case IP_MULTICAST_VIF:
1204 case IP_MULTICAST_TTL:
1205 case IP_MULTICAST_LOOP:
1206 case IP_ADD_MEMBERSHIP:
1207 case IP_DROP_MEMBERSHIP:
1208 error = ip_setmoptions(sopt, &inp->inp_moptions);
1209 break;
1210
1211 case IP_PORTRANGE:
1212 error = sooptcopyin(sopt, &optval, sizeof optval,
1213 sizeof optval);
1214 if (error)
1215 break;
1216
1217 switch (optval) {
1218 case IP_PORTRANGE_DEFAULT:
1219 inp->inp_flags &= ~(INP_LOWPORT);
1220 inp->inp_flags &= ~(INP_HIGHPORT);
1221 break;
1222
1223 case IP_PORTRANGE_HIGH:
1224 inp->inp_flags &= ~(INP_LOWPORT);
1225 inp->inp_flags |= INP_HIGHPORT;
1226 break;
1227
1228 case IP_PORTRANGE_LOW:
1229 inp->inp_flags &= ~(INP_HIGHPORT);
1230 inp->inp_flags |= INP_LOWPORT;
1231 break;
1232
1233 default:
1234 error = EINVAL;
1235 break;
1236 }
1237 break;
1238
1239 #ifdef IPSEC
1240 case IP_IPSEC_POLICY:
1241 {
1242 caddr_t req;
1243 size_t len = 0;
1244 int priv;
1245 struct mbuf *m;
1246 int optname;
1247
1248 if ((error = soopt_getm(sopt, &m)) != 0) /* XXX */
1249 break;
1250 if ((error = soopt_mcopyin(sopt, m)) != 0) /* XXX */
1251 break;
1252 priv = (sopt->sopt_p != NULL &&
1253 suser(sopt->sopt_p) != 0) ? 0 : 1;
1254 req = mtod(m, caddr_t);
1255 len = m->m_len;
1256 optname = sopt->sopt_name;
1257 error = ipsec4_set_policy(inp, optname, req, len, priv);
1258 m_freem(m);
1259 break;
1260 }
1261 #endif /*IPSEC*/
1262
1263 default:
1264 error = ENOPROTOOPT;
1265 break;
1266 }
1267 break;
1268
1269 case SOPT_GET:
1270 switch (sopt->sopt_name) {
1271 case IP_OPTIONS:
1272 case IP_RETOPTS:
1273 if (inp->inp_options)
1274 error = sooptcopyout(sopt,
1275 mtod(inp->inp_options,
1276 char *),
1277 inp->inp_options->m_len);
1278 else
1279 sopt->sopt_valsize = 0;
1280 break;
1281
1282 case IP_TOS:
1283 case IP_TTL:
1284 case IP_RECVOPTS:
1285 case IP_RECVRETOPTS:
1286 case IP_RECVDSTADDR:
1287 case IP_RECVIF:
1288 case IP_PORTRANGE:
1289 #if defined(NFAITH) && NFAITH > 0
1290 case IP_FAITH:
1291 #endif
1292 switch (sopt->sopt_name) {
1293
1294 case IP_TOS:
1295 optval = inp->inp_ip_tos;
1296 break;
1297
1298 case IP_TTL:
1299 optval = inp->inp_ip_ttl;
1300 break;
1301
1302 #define OPTBIT(bit) (inp->inp_flags & bit ? 1 : 0)
1303
1304 case IP_RECVOPTS:
1305 optval = OPTBIT(INP_RECVOPTS);
1306 break;
1307
1308 case IP_RECVRETOPTS:
1309 optval = OPTBIT(INP_RECVRETOPTS);
1310 break;
1311
1312 case IP_RECVDSTADDR:
1313 optval = OPTBIT(INP_RECVDSTADDR);
1314 break;
1315
1316 case IP_RECVIF:
1317 optval = OPTBIT(INP_RECVIF);
1318 break;
1319
1320 case IP_PORTRANGE:
1321 if (inp->inp_flags & INP_HIGHPORT)
1322 optval = IP_PORTRANGE_HIGH;
1323 else if (inp->inp_flags & INP_LOWPORT)
1324 optval = IP_PORTRANGE_LOW;
1325 else
1326 optval = 0;
1327 break;
1328
1329 #if defined(NFAITH) && NFAITH > 0
1330 case IP_FAITH:
1331 optval = OPTBIT(INP_FAITH);
1332 break;
1333 #endif
1334 }
1335 error = sooptcopyout(sopt, &optval, sizeof optval);
1336 break;
1337
1338 case IP_MULTICAST_IF:
1339 case IP_MULTICAST_VIF:
1340 case IP_MULTICAST_TTL:
1341 case IP_MULTICAST_LOOP:
1342 case IP_ADD_MEMBERSHIP:
1343 case IP_DROP_MEMBERSHIP:
1344 error = ip_getmoptions(sopt, inp->inp_moptions);
1345 break;
1346
1347 #ifdef IPSEC
1348 case IP_IPSEC_POLICY:
1349 {
1350 struct mbuf *m = NULL;
1351 caddr_t req = NULL;
1352 size_t len = 0;
1353
1354 if (m != 0) {
1355 req = mtod(m, caddr_t);
1356 len = m->m_len;
1357 }
1358 error = ipsec4_get_policy(sotoinpcb(so), req, len, &m);
1359 if (error == 0)
1360 error = soopt_mcopyout(sopt, m); /* XXX */
1361 if (error == 0)
1362 m_freem(m);
1363 break;
1364 }
1365 #endif /*IPSEC*/
1366
1367 default:
1368 error = ENOPROTOOPT;
1369 break;
1370 }
1371 break;
1372 }
1373 return (error);
1374 }
1375
1376 /*
1377 * Set up IP options in pcb for insertion in output packets.
1378 * Store in mbuf with pointer in pcbopt, adding pseudo-option
1379 * with destination address if source routed.
1380 */
1381 static int
1382 ip_pcbopts(optname, pcbopt, m)
1383 int optname;
1384 struct mbuf **pcbopt;
1385 register struct mbuf *m;
1386 {
1387 register int cnt, optlen;
1388 register u_char *cp;
1389 u_char opt;
1390
1391 /* turn off any old options */
1392 if (*pcbopt)
1393 (void)m_free(*pcbopt);
1394 *pcbopt = 0;
1395 if (m == (struct mbuf *)0 || m->m_len == 0) {
1396 /*
1397 * Only turning off any previous options.
1398 */
1399 if (m)
1400 (void)m_free(m);
1401 return (0);
1402 }
1403
1404 #ifndef vax
1405 if (m->m_len % sizeof(int32_t))
1406 goto bad;
1407 #endif
1408 /*
1409 * IP first-hop destination address will be stored before
1410 * actual options; move other options back
1411 * and clear it when none present.
1412 */
1413 if (m->m_data + m->m_len + sizeof(struct in_addr) >= &m->m_dat[MLEN])
1414 goto bad;
1415 cnt = m->m_len;
1416 m->m_len += sizeof(struct in_addr);
1417 cp = mtod(m, u_char *) + sizeof(struct in_addr);
1418 ovbcopy(mtod(m, caddr_t), (caddr_t)cp, (unsigned)cnt);
1419 bzero(mtod(m, caddr_t), sizeof(struct in_addr));
1420
1421 for (; cnt > 0; cnt -= optlen, cp += optlen) {
1422 opt = cp[IPOPT_OPTVAL];
1423 if (opt == IPOPT_EOL)
1424 break;
1425 if (opt == IPOPT_NOP)
1426 optlen = 1;
1427 else {
1428 if (cnt < IPOPT_OLEN + sizeof(*cp))
1429 goto bad;
1430 optlen = cp[IPOPT_OLEN];
1431 if (optlen < IPOPT_OLEN + sizeof(*cp) || optlen > cnt)
1432 goto bad;
1433 }
1434 switch (opt) {
1435
1436 default:
1437 break;
1438
1439 case IPOPT_LSRR:
1440 case IPOPT_SSRR:
1441 /*
1442 * user process specifies route as:
1443 * ->A->B->C->D
1444 * D must be our final destination (but we can't
1445 * check that since we may not have connected yet).
1446 * A is first hop destination, which doesn't appear in
1447 * actual IP option, but is stored before the options.
1448 */
1449 if (optlen < IPOPT_MINOFF - 1 + sizeof(struct in_addr))
1450 goto bad;
1451 m->m_len -= sizeof(struct in_addr);
1452 cnt -= sizeof(struct in_addr);
1453 optlen -= sizeof(struct in_addr);
1454 cp[IPOPT_OLEN] = optlen;
1455 /*
1456 * Move first hop before start of options.
1457 */
1458 bcopy((caddr_t)&cp[IPOPT_OFFSET+1], mtod(m, caddr_t),
1459 sizeof(struct in_addr));
1460 /*
1461 * Then copy rest of options back
1462 * to close up the deleted entry.
1463 */
1464 ovbcopy((caddr_t)(&cp[IPOPT_OFFSET+1] +
1465 sizeof(struct in_addr)),
1466 (caddr_t)&cp[IPOPT_OFFSET+1],
1467 (unsigned)cnt + sizeof(struct in_addr));
1468 break;
1469 }
1470 }
1471 if (m->m_len > MAX_IPOPTLEN + sizeof(struct in_addr))
1472 goto bad;
1473 *pcbopt = m;
1474 return (0);
1475
1476 bad:
1477 (void)m_free(m);
1478 return (EINVAL);
1479 }
1480
1481 /*
1482 * XXX
1483 * The whole multicast option thing needs to be re-thought.
1484 * Several of these options are equally applicable to non-multicast
1485 * transmission, and one (IP_MULTICAST_TTL) totally duplicates a
1486 * standard option (IP_TTL).
1487 */
1488
1489 /*
1490 * following RFC1724 section 3.3, 0.0.0.0/8 is interpreted as interface index.
1491 */
1492 static struct ifnet *
1493 ip_multicast_if(a, ifindexp)
1494 struct in_addr *a;
1495 int *ifindexp;
1496 {
1497 int ifindex;
1498 struct ifnet *ifp;
1499
1500 if (ifindexp)
1501 *ifindexp = 0;
1502 if (ntohl(a->s_addr) >> 24 == 0) {
1503 ifindex = ntohl(a->s_addr) & 0xffffff;
1504 if (ifindex < 0 || if_index < ifindex)
1505 return NULL;
1506 ifp = ifindex2ifnet[ifindex];
1507 if (ifindexp)
1508 *ifindexp = ifindex;
1509 } else {
1510 INADDR_TO_IFP(*a, ifp);
1511 }
1512 return ifp;
1513 }
1514
1515 /*
1516 * Set the IP multicast options in response to user setsockopt().
1517 */
1518 static int
1519 ip_setmoptions(sopt, imop)
1520 struct sockopt *sopt;
1521 struct ip_moptions **imop;
1522 {
1523 int error = 0;
1524 int i;
1525 struct in_addr addr;
1526 struct ip_mreq mreq;
1527 struct ifnet *ifp;
1528 struct ip_moptions *imo = *imop;
1529 struct route ro;
1530 struct sockaddr_in *dst;
1531 int ifindex;
1532 int s;
1533
1534 if (imo == NULL) {
1535 /*
1536 * No multicast option buffer attached to the pcb;
1537 * allocate one and initialize to default values.
1538 */
1539 imo = (struct ip_moptions*)malloc(sizeof(*imo), M_IPMOPTS,
1540 M_WAITOK);
1541
1542 if (imo == NULL)
1543 return (ENOBUFS);
1544 *imop = imo;
1545 imo->imo_multicast_ifp = NULL;
1546 imo->imo_multicast_addr.s_addr = INADDR_ANY;
1547 imo->imo_multicast_vif = -1;
1548 imo->imo_multicast_ttl = IP_DEFAULT_MULTICAST_TTL;
1549 imo->imo_multicast_loop = IP_DEFAULT_MULTICAST_LOOP;
1550 imo->imo_num_memberships = 0;
1551 }
1552
1553 switch (sopt->sopt_name) {
1554 /* store an index number for the vif you wanna use in the send */
1555 case IP_MULTICAST_VIF:
1556 if (legal_vif_num == 0) {
1557 error = EOPNOTSUPP;
1558 break;
1559 }
1560 error = sooptcopyin(sopt, &i, sizeof i, sizeof i);
1561 if (error)
1562 break;
1563 if (!legal_vif_num(i) && (i != -1)) {
1564 error = EINVAL;
1565 break;
1566 }
1567 imo->imo_multicast_vif = i;
1568 break;
1569
1570 case IP_MULTICAST_IF:
1571 /*
1572 * Select the interface for outgoing multicast packets.
1573 */
1574 error = sooptcopyin(sopt, &addr, sizeof addr, sizeof addr);
1575 if (error)
1576 break;
1577 /*
1578 * INADDR_ANY is used to remove a previous selection.
1579 * When no interface is selected, a default one is
1580 * chosen every time a multicast packet is sent.
1581 */
1582 if (addr.s_addr == INADDR_ANY) {
1583 imo->imo_multicast_ifp = NULL;
1584 break;
1585 }
1586 /*
1587 * The selected interface is identified by its local
1588 * IP address. Find the interface and confirm that
1589 * it supports multicasting.
1590 */
1591 s = splimp();
1592 ifp = ip_multicast_if(&addr, &ifindex);
1593 if (ifp == NULL || (ifp->if_flags & IFF_MULTICAST) == 0) {
1594 splx(s);
1595 error = EADDRNOTAVAIL;
1596 break;
1597 }
1598 imo->imo_multicast_ifp = ifp;
1599 if (ifindex)
1600 imo->imo_multicast_addr = addr;
1601 else
1602 imo->imo_multicast_addr.s_addr = INADDR_ANY;
1603 splx(s);
1604 break;
1605
1606 case IP_MULTICAST_TTL:
1607 /*
1608 * Set the IP time-to-live for outgoing multicast packets.
1609 * The original multicast API required a char argument,
1610 * which is inconsistent with the rest of the socket API.
1611 * We allow either a char or an int.
1612 */
1613 if (sopt->sopt_valsize == 1) {
1614 u_char ttl;
1615 error = sooptcopyin(sopt, &ttl, 1, 1);
1616 if (error)
1617 break;
1618 imo->imo_multicast_ttl = ttl;
1619 } else {
1620 u_int ttl;
1621 error = sooptcopyin(sopt, &ttl, sizeof ttl,
1622 sizeof ttl);
1623 if (error)
1624 break;
1625 if (ttl > 255)
1626 error = EINVAL;
1627 else
1628 imo->imo_multicast_ttl = ttl;
1629 }
1630 break;
1631
1632 case IP_MULTICAST_LOOP:
1633 /*
1634 * Set the loopback flag for outgoing multicast packets.
1635 * Must be zero or one. The original multicast API required a
1636 * char argument, which is inconsistent with the rest
1637 * of the socket API. We allow either a char or an int.
1638 */
1639 if (sopt->sopt_valsize == 1) {
1640 u_char loop;
1641 error = sooptcopyin(sopt, &loop, 1, 1);
1642 if (error)
1643 break;
1644 imo->imo_multicast_loop = !!loop;
1645 } else {
1646 u_int loop;
1647 error = sooptcopyin(sopt, &loop, sizeof loop,
1648 sizeof loop);
1649 if (error)
1650 break;
1651 imo->imo_multicast_loop = !!loop;
1652 }
1653 break;
1654
1655 case IP_ADD_MEMBERSHIP:
1656 /*
1657 * Add a multicast group membership.
1658 * Group must be a valid IP multicast address.
1659 */
1660 error = sooptcopyin(sopt, &mreq, sizeof mreq, sizeof mreq);
1661 if (error)
1662 break;
1663
1664 if (!IN_MULTICAST(ntohl(mreq.imr_multiaddr.s_addr))) {
1665 error = EINVAL;
1666 break;
1667 }
1668 s = splimp();
1669 /*
1670 * If no interface address was provided, use the interface of
1671 * the route to the given multicast address.
1672 */
1673 if (mreq.imr_interface.s_addr == INADDR_ANY) {
1674 bzero((caddr_t)&ro, sizeof(ro));
1675 dst = (struct sockaddr_in *)&ro.ro_dst;
1676 dst->sin_len = sizeof(*dst);
1677 dst->sin_family = AF_INET;
1678 dst->sin_addr = mreq.imr_multiaddr;
1679 rtalloc(&ro);
1680 if (ro.ro_rt == NULL) {
1681 error = EADDRNOTAVAIL;
1682 splx(s);
1683 break;
1684 }
1685 ifp = ro.ro_rt->rt_ifp;
1686 rtfree(ro.ro_rt);
1687 }
1688 else {
1689 ifp = ip_multicast_if(&mreq.imr_interface, NULL);
1690 }
1691
1692 /*
1693 * See if we found an interface, and confirm that it
1694 * supports multicast.
1695 */
1696 if (ifp == NULL || (ifp->if_flags & IFF_MULTICAST) == 0) {
1697 error = EADDRNOTAVAIL;
1698 splx(s);
1699 break;
1700 }
1701 /*
1702 * See if the membership already exists or if all the
1703 * membership slots are full.
1704 */
1705 for (i = 0; i < imo->imo_num_memberships; ++i) {
1706 if (imo->imo_membership[i]->inm_ifp == ifp &&
1707 imo->imo_membership[i]->inm_addr.s_addr
1708 == mreq.imr_multiaddr.s_addr)
1709 break;
1710 }
1711 if (i < imo->imo_num_memberships) {
1712 error = EADDRINUSE;
1713 splx(s);
1714 break;
1715 }
1716 if (i == IP_MAX_MEMBERSHIPS) {
1717 error = ETOOMANYREFS;
1718 splx(s);
1719 break;
1720 }
1721 /*
1722 * Everything looks good; add a new record to the multicast
1723 * address list for the given interface.
1724 */
1725 if ((imo->imo_membership[i] =
1726 in_addmulti(&mreq.imr_multiaddr, ifp)) == NULL) {
1727 error = ENOBUFS;
1728 splx(s);
1729 break;
1730 }
1731 ++imo->imo_num_memberships;
1732 splx(s);
1733 break;
1734
1735 case IP_DROP_MEMBERSHIP:
1736 /*
1737 * Drop a multicast group membership.
1738 * Group must be a valid IP multicast address.
1739 */
1740 error = sooptcopyin(sopt, &mreq, sizeof mreq, sizeof mreq);
1741 if (error)
1742 break;
1743
1744 if (!IN_MULTICAST(ntohl(mreq.imr_multiaddr.s_addr))) {
1745 error = EINVAL;
1746 break;
1747 }
1748
1749 s = splimp();
1750 /*
1751 * If an interface address was specified, get a pointer
1752 * to its ifnet structure.
1753 */
1754 if (mreq.imr_interface.s_addr == INADDR_ANY)
1755 ifp = NULL;
1756 else {
1757 ifp = ip_multicast_if(&mreq.imr_interface, NULL);
1758 if (ifp == NULL) {
1759 error = EADDRNOTAVAIL;
1760 splx(s);
1761 break;
1762 }
1763 }
1764 /*
1765 * Find the membership in the membership array.
1766 */
1767 for (i = 0; i < imo->imo_num_memberships; ++i) {
1768 if ((ifp == NULL ||
1769 imo->imo_membership[i]->inm_ifp == ifp) &&
1770 imo->imo_membership[i]->inm_addr.s_addr ==
1771 mreq.imr_multiaddr.s_addr)
1772 break;
1773 }
1774 if (i == imo->imo_num_memberships) {
1775 error = EADDRNOTAVAIL;
1776 splx(s);
1777 break;
1778 }
1779 /*
1780 * Give up the multicast address record to which the
1781 * membership points.
1782 */
1783 in_delmulti(imo->imo_membership[i]);
1784 /*
1785 * Remove the gap in the membership array.
1786 */
1787 for (++i; i < imo->imo_num_memberships; ++i)
1788 imo->imo_membership[i-1] = imo->imo_membership[i];
1789 --imo->imo_num_memberships;
1790 splx(s);
1791 break;
1792
1793 default:
1794 error = EOPNOTSUPP;
1795 break;
1796 }
1797
1798 /*
1799 * If all options have default values, no need to keep the mbuf.
1800 */
1801 if (imo->imo_multicast_ifp == NULL &&
1802 imo->imo_multicast_vif == -1 &&
1803 imo->imo_multicast_ttl == IP_DEFAULT_MULTICAST_TTL &&
1804 imo->imo_multicast_loop == IP_DEFAULT_MULTICAST_LOOP &&
1805 imo->imo_num_memberships == 0) {
1806 free(*imop, M_IPMOPTS);
1807 *imop = NULL;
1808 }
1809
1810 return (error);
1811 }
1812
1813 /*
1814 * Return the IP multicast options in response to user getsockopt().
1815 */
1816 static int
1817 ip_getmoptions(sopt, imo)
1818 struct sockopt *sopt;
1819 register struct ip_moptions *imo;
1820 {
1821 struct in_addr addr;
1822 struct in_ifaddr *ia;
1823 int error, optval;
1824 u_char coptval;
1825
1826 error = 0;
1827 switch (sopt->sopt_name) {
1828 case IP_MULTICAST_VIF:
1829 if (imo != NULL)
1830 optval = imo->imo_multicast_vif;
1831 else
1832 optval = -1;
1833 error = sooptcopyout(sopt, &optval, sizeof optval);
1834 break;
1835
1836 case IP_MULTICAST_IF:
1837 if (imo == NULL || imo->imo_multicast_ifp == NULL)
1838 addr.s_addr = INADDR_ANY;
1839 else if (imo->imo_multicast_addr.s_addr) {
1840 /* return the value user has set */
1841 addr = imo->imo_multicast_addr;
1842 } else {
1843 IFP_TO_IA(imo->imo_multicast_ifp, ia);
1844 addr.s_addr = (ia == NULL) ? INADDR_ANY
1845 : IA_SIN(ia)->sin_addr.s_addr;
1846 }
1847 error = sooptcopyout(sopt, &addr, sizeof addr);
1848 break;
1849
1850 case IP_MULTICAST_TTL:
1851 if (imo == 0)
1852 optval = coptval = IP_DEFAULT_MULTICAST_TTL;
1853 else
1854 optval = coptval = imo->imo_multicast_ttl;
1855 if (sopt->sopt_valsize == 1)
1856 error = sooptcopyout(sopt, &coptval, 1);
1857 else
1858 error = sooptcopyout(sopt, &optval, sizeof optval);
1859 break;
1860
1861 case IP_MULTICAST_LOOP:
1862 if (imo == 0)
1863 optval = coptval = IP_DEFAULT_MULTICAST_LOOP;
1864 else
1865 optval = coptval = imo->imo_multicast_loop;
1866 if (sopt->sopt_valsize == 1)
1867 error = sooptcopyout(sopt, &coptval, 1);
1868 else
1869 error = sooptcopyout(sopt, &optval, sizeof optval);
1870 break;
1871
1872 default:
1873 error = ENOPROTOOPT;
1874 break;
1875 }
1876 return (error);
1877 }
1878
1879 /*
1880 * Discard the IP multicast options.
1881 */
1882 void
1883 ip_freemoptions(imo)
1884 register struct ip_moptions *imo;
1885 {
1886 register int i;
1887
1888 if (imo != NULL) {
1889 for (i = 0; i < imo->imo_num_memberships; ++i)
1890 in_delmulti(imo->imo_membership[i]);
1891 free(imo, M_IPMOPTS);
1892 }
1893 }
1894
1895 /*
1896 * Routine called from ip_output() to loop back a copy of an IP multicast
1897 * packet to the input queue of a specified interface. Note that this
1898 * calls the output routine of the loopback "driver", but with an interface
1899 * pointer that might NOT be a loopback interface -- evil, but easier than
1900 * replicating that code here.
1901 */
1902 static void
1903 ip_mloopback(ifp, m, dst, hlen)
1904 struct ifnet *ifp;
1905 register struct mbuf *m;
1906 register struct sockaddr_in *dst;
1907 int hlen;
1908 {
1909 register struct ip *ip;
1910 struct mbuf *copym;
1911
1912 copym = m_copy(m, 0, M_COPYALL);
1913 if (copym != NULL && (copym->m_flags & M_EXT || copym->m_len < hlen))
1914 copym = m_pullup(copym, hlen);
1915 if (copym != NULL) {
1916 /*
1917 * We don't bother to fragment if the IP length is greater
1918 * than the interface's MTU. Can this possibly matter?
1919 */
1920 ip = mtod(copym, struct ip *);
1921 HTONS(ip->ip_len);
1922 HTONS(ip->ip_off);
1923 ip->ip_sum = 0;
1924 if (ip->ip_vhl == IP_VHL_BORING) {
1925 ip->ip_sum = in_cksum_hdr(ip);
1926 } else {
1927 ip->ip_sum = in_cksum(copym, hlen);
1928 }
1929 /*
1930 * NB:
1931 * It's not clear whether there are any lingering
1932 * reentrancy problems in other areas which might
1933 * be exposed by using ip_input directly (in
1934 * particular, everything which modifies the packet
1935 * in-place). Yet another option is using the
1936 * protosw directly to deliver the looped back
1937 * packet. For the moment, we'll err on the side
1938 * of safety by using if_simloop().
1939 */
1940 #if 1 /* XXX */
1941 if (dst->sin_family != AF_INET) {
1942 printf("ip_mloopback: bad address family %d\n",
1943 dst->sin_family);
1944 dst->sin_family = AF_INET;
1945 }
1946 #endif
1947
1948 #ifdef notdef
1949 copym->m_pkthdr.rcvif = ifp;
1950 ip_input(copym);
1951 #else
1952 /* if the checksum hasn't been computed, mark it as valid */
1953 if (copym->m_pkthdr.csum_flags & CSUM_DELAY_DATA) {
1954 copym->m_pkthdr.csum_flags |=
1955 CSUM_DATA_VALID | CSUM_PSEUDO_HDR;
1956 copym->m_pkthdr.csum_data = 0xffff;
1957 }
1958 if_simloop(ifp, copym, dst->sin_family, 0);
1959 #endif
1960 }
1961 }