1 /*
2 * Copyright (c) 1982, 1986, 1988, 1990, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
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.
20 *
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
31 * SUCH DAMAGE.
32 *
33 * @(#)ip_output.c 8.3 (Berkeley) 1/21/94
34 * $FreeBSD$
35 */
36
37 #define _IP_VHL
38
39 #include "opt_ipfw.h"
40 #include "opt_ipdn.h"
41 #include "opt_ipdivert.h"
42 #include "opt_ipfilter.h"
43
44 #include <sys/param.h>
45 #include <sys/systm.h>
46 #include <sys/kernel.h>
47 #include <sys/malloc.h>
48 #include <sys/mbuf.h>
49 #include <sys/protosw.h>
50 #include <sys/socket.h>
51 #include <sys/socketvar.h>
52
53 #include <net/if.h>
54 #include <net/route.h>
55
56 #include <netinet/in.h>
57 #include <netinet/in_systm.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
63 #ifdef vax
64 #include <machine/mtpr.h>
65 #endif
66 #include <machine/in_cksum.h>
67
68 static MALLOC_DEFINE(M_IPMOPTS, "ip_moptions", "internet multicast options");
69
70 #if !defined(COMPAT_IPFW) || COMPAT_IPFW == 1
71 #undef COMPAT_IPFW
72 #define COMPAT_IPFW 1
73 #else
74 #undef COMPAT_IPFW
75 #endif
76
77 #ifdef COMPAT_IPFW
78 #include <netinet/ip_fw.h>
79 #endif
80
81 #ifdef DUMMYNET
82 #include <netinet/ip_dummynet.h>
83 #endif
84
85 #ifdef IPFIREWALL_FORWARD_DEBUG
86 #define print_ip(a) printf("%ld.%ld.%ld.%ld",(ntohl(a.s_addr)>>24)&0xFF,\
87 (ntohl(a.s_addr)>>16)&0xFF,\
88 (ntohl(a.s_addr)>>8)&0xFF,\
89 (ntohl(a.s_addr))&0xFF);
90 #endif
91
92 u_short ip_id;
93
94 static struct mbuf *ip_insertoptions __P((struct mbuf *, struct mbuf *, int *));
95 static void ip_mloopback
96 __P((struct ifnet *, struct mbuf *, struct sockaddr_in *, int));
97 static int ip_getmoptions
98 __P((struct sockopt *, struct ip_moptions *));
99 static int ip_pcbopts __P((int, struct mbuf **, struct mbuf *));
100 static int ip_setmoptions
101 __P((struct sockopt *, struct ip_moptions **));
102
103 #if defined(IPFILTER_LKM) || defined(IPFILTER)
104 int ip_optcopy __P((struct ip *, struct ip *));
105 extern int (*fr_checkp) __P((struct ip *, int, struct ifnet *, int, struct mbuf **));
106 #else
107 static int ip_optcopy __P((struct ip *, struct ip *));
108 #endif
109
110
111 extern struct protosw inetsw[];
112
113 /*
114 * IP output. The packet in mbuf chain m contains a skeletal IP
115 * header (with len, off, ttl, proto, tos, src, dst).
116 * The mbuf chain containing the packet will be freed.
117 * The mbuf opt, if present, will not be freed.
118 */
119 int
120 ip_output(m0, opt, ro, flags, imo)
121 struct mbuf *m0;
122 struct mbuf *opt;
123 struct route *ro;
124 int flags;
125 struct ip_moptions *imo;
126 {
127 struct ip *ip, *mhip;
128 struct ifnet *ifp;
129 struct mbuf *m = m0;
130 int hlen = sizeof (struct ip);
131 int len, off, error = 0;
132 struct sockaddr_in *dst;
133 struct in_ifaddr *ia;
134 int isbroadcast;
135 #ifdef IPFIREWALL_FORWARD
136 int fwd_rewrite_src = 0;
137 #endif
138
139 #ifndef IPDIVERT /* dummy variable for the firewall code to play with */
140 u_short ip_divert_cookie = 0 ;
141 #endif
142 #ifdef COMPAT_IPFW
143 struct ip_fw_chain *rule = NULL ;
144 #endif
145
146 #if defined(IPFIREWALL) && defined(DUMMYNET)
147 /*
148 * dummynet packet are prepended a vestigial mbuf with
149 * m_type = MT_DUMMYNET and m_data pointing to the matching
150 * rule.
151 */
152 if (m->m_type == MT_DUMMYNET) {
153 /*
154 * the packet was already tagged, so part of the
155 * processing was already done, and we need to go down.
156 * Get parameters from the header.
157 */
158 rule = (struct ip_fw_chain *)(m->m_data) ;
159 opt = NULL ;
160 ro = & ( ((struct dn_pkt *)m)->ro ) ;
161 flags = 0 ; /* XXX is this correct ? */
162 imo = NULL ;
163 dst = ((struct dn_pkt *)m)->dn_dst ;
164 ifp = ((struct dn_pkt *)m)->ifp ;
165
166 m0 = m = m->m_next ;
167 ip = mtod(m, struct ip *);
168 hlen = IP_VHL_HL(ip->ip_vhl) << 2 ;
169 goto sendit;
170 } else
171 rule = NULL ;
172 #endif
173
174 #ifdef DIAGNOSTIC
175 if ((m->m_flags & M_PKTHDR) == 0)
176 panic("ip_output no HDR");
177 if (!ro)
178 panic("ip_output no route, proto = %d",
179 mtod(m, struct ip *)->ip_p);
180 #endif
181 if (opt) {
182 m = ip_insertoptions(m, opt, &len);
183 hlen = len;
184 }
185 ip = mtod(m, struct ip *);
186 /*
187 * Fill in IP header.
188 */
189 if ((flags & (IP_FORWARDING|IP_RAWOUTPUT)) == 0) {
190 ip->ip_vhl = IP_MAKE_VHL(IPVERSION, hlen >> 2);
191 ip->ip_off &= IP_DF;
192 ip->ip_id = htons(ip_id++);
193 ipstat.ips_localout++;
194 } else {
195 hlen = IP_VHL_HL(ip->ip_vhl) << 2;
196 }
197
198 dst = (struct sockaddr_in *)&ro->ro_dst;
199 /*
200 * If there is a cached route,
201 * check that it is to the same destination
202 * and is still up. If not, free it and try again.
203 */
204 if (ro->ro_rt && ((ro->ro_rt->rt_flags & RTF_UP) == 0 ||
205 dst->sin_addr.s_addr != ip->ip_dst.s_addr)) {
206 RTFREE(ro->ro_rt);
207 ro->ro_rt = (struct rtentry *)0;
208 }
209 if (ro->ro_rt == 0) {
210 dst->sin_family = AF_INET;
211 dst->sin_len = sizeof(*dst);
212 dst->sin_addr = ip->ip_dst;
213 }
214 /*
215 * If routing to interface only,
216 * short circuit routing lookup.
217 */
218 #define ifatoia(ifa) ((struct in_ifaddr *)(ifa))
219 #define sintosa(sin) ((struct sockaddr *)(sin))
220 if (flags & IP_ROUTETOIF) {
221 if ((ia = ifatoia(ifa_ifwithdstaddr(sintosa(dst)))) == 0 &&
222 (ia = ifatoia(ifa_ifwithnet(sintosa(dst)))) == 0) {
223 ipstat.ips_noroute++;
224 error = ENETUNREACH;
225 goto bad;
226 }
227 ifp = ia->ia_ifp;
228 ip->ip_ttl = 1;
229 isbroadcast = in_broadcast(dst->sin_addr, ifp);
230 } else {
231 /*
232 * If this is the case, we probably don't want to allocate
233 * a protocol-cloned route since we didn't get one from the
234 * ULP. This lets TCP do its thing, while not burdening
235 * forwarding or ICMP with the overhead of cloning a route.
236 * Of course, we still want to do any cloning requested by
237 * the link layer, as this is probably required in all cases
238 * for correct operation (as it is for ARP).
239 */
240 if (ro->ro_rt == 0)
241 rtalloc_ign(ro, RTF_PRCLONING);
242 if (ro->ro_rt == 0) {
243 ipstat.ips_noroute++;
244 error = EHOSTUNREACH;
245 goto bad;
246 }
247 ia = ifatoia(ro->ro_rt->rt_ifa);
248 ifp = ro->ro_rt->rt_ifp;
249 ro->ro_rt->rt_use++;
250 if (ro->ro_rt->rt_flags & RTF_GATEWAY)
251 dst = (struct sockaddr_in *)ro->ro_rt->rt_gateway;
252 if (ro->ro_rt->rt_flags & RTF_HOST)
253 isbroadcast = (ro->ro_rt->rt_flags & RTF_BROADCAST);
254 else
255 isbroadcast = in_broadcast(dst->sin_addr, ifp);
256 }
257 if (IN_MULTICAST(ntohl(ip->ip_dst.s_addr))) {
258 struct in_multi *inm;
259
260 m->m_flags |= M_MCAST;
261 /*
262 * IP destination address is multicast. Make sure "dst"
263 * still points to the address in "ro". (It may have been
264 * changed to point to a gateway address, above.)
265 */
266 dst = (struct sockaddr_in *)&ro->ro_dst;
267 /*
268 * See if the caller provided any multicast options
269 */
270 if (imo != NULL) {
271 ip->ip_ttl = imo->imo_multicast_ttl;
272 if (imo->imo_multicast_ifp != NULL)
273 ifp = imo->imo_multicast_ifp;
274 if (imo->imo_multicast_vif != -1)
275 ip->ip_src.s_addr =
276 ip_mcast_src(imo->imo_multicast_vif);
277 } else
278 ip->ip_ttl = IP_DEFAULT_MULTICAST_TTL;
279 /*
280 * Confirm that the outgoing interface supports multicast.
281 */
282 if ((imo == NULL) || (imo->imo_multicast_vif == -1)) {
283 if ((ifp->if_flags & IFF_MULTICAST) == 0) {
284 ipstat.ips_noroute++;
285 error = ENETUNREACH;
286 goto bad;
287 }
288 }
289 /*
290 * If source address not specified yet, use address
291 * of outgoing interface.
292 */
293 if (ip->ip_src.s_addr == INADDR_ANY) {
294 register struct in_ifaddr *ia1;
295
296 for (ia1 = in_ifaddrhead.tqh_first; ia1;
297 ia1 = ia1->ia_link.tqe_next)
298 if (ia1->ia_ifp == ifp) {
299 ip->ip_src = IA_SIN(ia1)->sin_addr;
300 break;
301 }
302 }
303
304 IN_LOOKUP_MULTI(ip->ip_dst, ifp, inm);
305 if (inm != NULL &&
306 (imo == NULL || imo->imo_multicast_loop)) {
307 /*
308 * If we belong to the destination multicast group
309 * on the outgoing interface, and the caller did not
310 * forbid loopback, loop back a copy.
311 */
312 ip_mloopback(ifp, m, dst, hlen);
313 }
314 else {
315 /*
316 * If we are acting as a multicast router, perform
317 * multicast forwarding as if the packet had just
318 * arrived on the interface to which we are about
319 * to send. The multicast forwarding function
320 * recursively calls this function, using the
321 * IP_FORWARDING flag to prevent infinite recursion.
322 *
323 * Multicasts that are looped back by ip_mloopback(),
324 * above, will be forwarded by the ip_input() routine,
325 * if necessary.
326 */
327 if (ip_mrouter && (flags & IP_FORWARDING) == 0) {
328 /*
329 * Check if rsvp daemon is running. If not, don't
330 * set ip_moptions. This ensures that the packet
331 * is multicast and not just sent down one link
332 * as prescribed by rsvpd.
333 */
334 if (!rsvp_on)
335 imo = NULL;
336 if (ip_mforward(ip, ifp, m, imo) != 0) {
337 m_freem(m);
338 goto done;
339 }
340 }
341 }
342
343 /*
344 * Multicasts with a time-to-live of zero may be looped-
345 * back, above, but must not be transmitted on a network.
346 * Also, multicasts addressed to the loopback interface
347 * are not sent -- the above call to ip_mloopback() will
348 * loop back a copy if this host actually belongs to the
349 * destination group on the loopback interface.
350 */
351 if (ip->ip_ttl == 0 || ifp->if_flags & IFF_LOOPBACK) {
352 m_freem(m);
353 goto done;
354 }
355
356 goto sendit;
357 }
358 #ifndef notdef
359 /*
360 * If source address not specified yet, use address
361 * of outgoing interface.
362 */
363 if (ip->ip_src.s_addr == INADDR_ANY) {
364 ip->ip_src = IA_SIN(ia)->sin_addr;
365 #ifdef IPFIREWALL_FORWARD
366 /* Keep note that we did this - if the firewall changes
367 * the next-hop, our interface may change, changing the
368 * default source IP. It's a shame so much effort happens
369 * twice. Oh well.
370 */
371 fwd_rewrite_src++;
372 #endif /* IPFIREWALL_FORWARD */
373 }
374 #endif /* notdef */
375 /*
376 * Verify that we have any chance at all of being able to queue
377 * the packet or packet fragments
378 */
379 if ((ifp->if_snd.ifq_len + ip->ip_len / ifp->if_mtu + 1) >=
380 ifp->if_snd.ifq_maxlen) {
381 error = ENOBUFS;
382 goto bad;
383 }
384
385 /*
386 * Look for broadcast address and
387 * and verify user is allowed to send
388 * such a packet.
389 */
390 if (isbroadcast) {
391 if ((ifp->if_flags & IFF_BROADCAST) == 0) {
392 error = EADDRNOTAVAIL;
393 goto bad;
394 }
395 if ((flags & IP_ALLOWBROADCAST) == 0) {
396 error = EACCES;
397 goto bad;
398 }
399 /* don't allow broadcast messages to be fragmented */
400 if ((u_short)ip->ip_len > ifp->if_mtu) {
401 error = EMSGSIZE;
402 goto bad;
403 }
404 m->m_flags |= M_BCAST;
405 } else {
406 m->m_flags &= ~M_BCAST;
407 }
408
409 sendit:
410 /*
411 * IpHack's section.
412 * - Xlate: translate packet's addr/port (NAT).
413 * - Firewall: deny/allow/etc.
414 * - Wrap: fake packet's addr/port <unimpl.>
415 * - Encapsulate: put it in another IP and send out. <unimp.>
416 */
417 #if defined(IPFILTER) || defined(IPFILTER_LKM)
418 if (fr_checkp) {
419 struct mbuf *m1 = m;
420
421 if ((error = (*fr_checkp)(ip, hlen, ifp, 1, &m1)) || !m1)
422 goto done;
423 ip = mtod(m = m1, struct ip *);
424 }
425 #endif
426
427 #ifdef COMPAT_IPFW
428 /*
429 * Check with the firewall...
430 */
431 if (fw_enable && ip_fw_chk_ptr) {
432 struct sockaddr_in *old = dst;
433
434 off = (*ip_fw_chk_ptr)(&ip,
435 hlen, ifp, &ip_divert_cookie, &m, &rule, &dst);
436 /*
437 * On return we must do the following:
438 * m == NULL -> drop the pkt
439 * 1<=off<= 0xffff -> DIVERT
440 * (off & 0x10000) -> send to a DUMMYNET pipe
441 * dst != old -> IPFIREWALL_FORWARD
442 * off==0, dst==old -> accept
443 * If some of the above modules is not compiled in, then
444 * we should't have to check the corresponding condition
445 * (because the ipfw control socket should not accept
446 * unsupported rules), but better play safe and drop
447 * packets in case of doubt.
448 */
449 if (!m) { /* firewall said to reject */
450 error = EACCES;
451 goto done;
452 }
453 if (off == 0 && dst == old) /* common case */
454 goto pass ;
455 #ifdef DUMMYNET
456 if (off & 0x10000) {
457 /*
458 * pass the pkt to dummynet. Need to include
459 * pipe number, m, ifp, ro, dst because these are
460 * not recomputed in the next pass.
461 * All other parameters have been already used and
462 * so they are not needed anymore.
463 * XXX note: if the ifp or ro entry are deleted
464 * while a pkt is in dummynet, we are in trouble!
465 */
466 dummynet_io(off & 0xffff, DN_TO_IP_OUT, m,ifp,ro,dst,rule);
467 goto done;
468 }
469 #endif
470 #ifdef IPDIVERT
471 if (off > 0 && off < 0x10000) { /* Divert packet */
472 ip_divert_port = off & 0xffff ;
473 (*inetsw[ip_protox[IPPROTO_DIVERT]].pr_input)(m, 0);
474 goto done;
475 }
476 #endif
477
478 #ifdef IPFIREWALL_FORWARD
479 /* Here we check dst to make sure it's directly reachable on the
480 * interface we previously thought it was.
481 * If it isn't (which may be likely in some situations) we have
482 * to re-route it (ie, find a route for the next-hop and the
483 * associated interface) and set them here. This is nested
484 * forwarding which in most cases is undesirable, except where
485 * such control is nigh impossible. So we do it here.
486 * And I'm babbling.
487 */
488 if (off == 0 && old != dst) {
489 struct in_ifaddr *ia;
490
491 /* It's changed... */
492 /* There must be a better way to do this next line... */
493 static struct route sro_fwd, *ro_fwd = &sro_fwd;
494 #ifdef IPFIREWALL_FORWARD_DEBUG
495 printf("IPFIREWALL_FORWARD: New dst ip: ");
496 print_ip(dst->sin_addr);
497 printf("\n");
498 #endif
499 /*
500 * We need to figure out if we have been forwarded
501 * to a local socket. If so then we should somehow
502 * "loop back" to ip_input, and get directed to the
503 * PCB as if we had received this packet. This is
504 * because it may be dificult to identify the packets
505 * you want to forward until they are being output
506 * and have selected an interface. (e.g. locally
507 * initiated packets) If we used the loopback inteface,
508 * we would not be able to control what happens
509 * as the packet runs through ip_input() as
510 * it is done through a ISR.
511 */
512 for (ia = TAILQ_FIRST(&in_ifaddrhead); ia;
513 ia = TAILQ_NEXT(ia, ia_link)) {
514 /*
515 * If the addr to forward to is one
516 * of ours, we pretend to
517 * be the destination for this packet.
518 */
519 if (IA_SIN(ia)->sin_addr.s_addr ==
520 dst->sin_addr.s_addr)
521 break;
522 }
523 if (ia) {
524 /* tell ip_input "dont filter" */
525 ip_fw_fwd_addr = dst;
526 if (m->m_pkthdr.rcvif == NULL)
527 m->m_pkthdr.rcvif = ifunit("lo0");
528 ip->ip_len = htons((u_short)ip->ip_len);
529 ip->ip_off = htons((u_short)ip->ip_off);
530 ip->ip_sum = 0;
531 if (ip->ip_vhl == IP_VHL_BORING) {
532 ip->ip_sum = in_cksum_hdr(ip);
533 } else {
534 ip->ip_sum = in_cksum(m, hlen);
535 }
536 ip_input(m);
537 goto done;
538 }
539 /* Some of the logic for this was
540 * nicked from above.
541 *
542 * This rewrites the cached route in a local PCB.
543 * Is this what we want to do?
544 */
545 bcopy(dst, &ro_fwd->ro_dst, sizeof(*dst));
546
547 ro_fwd->ro_rt = 0;
548 rtalloc_ign(ro_fwd, RTF_PRCLONING);
549
550 if (ro_fwd->ro_rt == 0) {
551 ipstat.ips_noroute++;
552 error = EHOSTUNREACH;
553 goto bad;
554 }
555
556 ia = ifatoia(ro_fwd->ro_rt->rt_ifa);
557 ifp = ro_fwd->ro_rt->rt_ifp;
558 ro_fwd->ro_rt->rt_use++;
559 if (ro_fwd->ro_rt->rt_flags & RTF_GATEWAY)
560 dst = (struct sockaddr_in *)ro_fwd->ro_rt->rt_gateway;
561 if (ro_fwd->ro_rt->rt_flags & RTF_HOST)
562 isbroadcast =
563 (ro_fwd->ro_rt->rt_flags & RTF_BROADCAST);
564 else
565 isbroadcast = in_broadcast(dst->sin_addr, ifp);
566 RTFREE(ro->ro_rt);
567 ro->ro_rt = ro_fwd->ro_rt;
568 dst = (struct sockaddr_in *)&ro_fwd->ro_dst;
569
570 /*
571 * If we added a default src ip earlier,
572 * which would have been gotten from the-then
573 * interface, do it again, from the new one.
574 */
575 if (fwd_rewrite_src)
576 ip->ip_src = IA_SIN(ia)->sin_addr;
577 goto pass ;
578 }
579 #endif /* IPFIREWALL_FORWARD */
580 /*
581 * if we get here, none of the above matches, and
582 * we have to drop the pkt
583 */
584 m_freem(m);
585 error = EACCES; /* not sure this is the right error msg */
586 goto done;
587 }
588 #endif /* COMPAT_IPFW */
589
590 pass:
591 /*
592 * If small enough for interface, can just send directly.
593 */
594 if ((u_short)ip->ip_len <= ifp->if_mtu) {
595 ip->ip_len = htons((u_short)ip->ip_len);
596 ip->ip_off = htons((u_short)ip->ip_off);
597 ip->ip_sum = 0;
598 if (ip->ip_vhl == IP_VHL_BORING) {
599 ip->ip_sum = in_cksum_hdr(ip);
600 } else {
601 ip->ip_sum = in_cksum(m, hlen);
602 }
603 error = (*ifp->if_output)(ifp, m,
604 (struct sockaddr *)dst, ro->ro_rt);
605 goto done;
606 }
607 /*
608 * Too large for interface; fragment if possible.
609 * Must be able to put at least 8 bytes per fragment.
610 */
611 if (ip->ip_off & IP_DF) {
612 error = EMSGSIZE;
613 /*
614 * This case can happen if the user changed the MTU
615 * of an interface after enabling IP on it. Because
616 * most netifs don't keep track of routes pointing to
617 * them, there is no way for one to update all its
618 * routes when the MTU is changed.
619 */
620 if ((ro->ro_rt->rt_flags & (RTF_UP | RTF_HOST))
621 && !(ro->ro_rt->rt_rmx.rmx_locks & RTV_MTU)
622 && (ro->ro_rt->rt_rmx.rmx_mtu > ifp->if_mtu)) {
623 ro->ro_rt->rt_rmx.rmx_mtu = ifp->if_mtu;
624 }
625 ipstat.ips_cantfrag++;
626 goto bad;
627 }
628 len = (ifp->if_mtu - hlen) &~ 7;
629 if (len < 8) {
630 error = EMSGSIZE;
631 goto bad;
632 }
633
634 {
635 int mhlen, firstlen = len;
636 struct mbuf **mnext = &m->m_nextpkt;
637
638 /*
639 * Loop through length of segment after first fragment,
640 * make new header and copy data of each part and link onto chain.
641 */
642 m0 = m;
643 mhlen = sizeof (struct ip);
644 for (off = hlen + len; off < (u_short)ip->ip_len; off += len) {
645 MGETHDR(m, M_DONTWAIT, MT_HEADER);
646 if (m == 0) {
647 error = ENOBUFS;
648 ipstat.ips_odropped++;
649 goto sendorfree;
650 }
651 m->m_flags |= (m0->m_flags & M_MCAST);
652 m->m_data += max_linkhdr;
653 mhip = mtod(m, struct ip *);
654 *mhip = *ip;
655 if (hlen > sizeof (struct ip)) {
656 mhlen = ip_optcopy(ip, mhip) + sizeof (struct ip);
657 mhip->ip_vhl = IP_MAKE_VHL(IPVERSION, mhlen >> 2);
658 }
659 m->m_len = mhlen;
660 mhip->ip_off = ((off - hlen) >> 3) + (ip->ip_off & ~IP_MF);
661 if (ip->ip_off & IP_MF)
662 mhip->ip_off |= IP_MF;
663 if (off + len >= (u_short)ip->ip_len)
664 len = (u_short)ip->ip_len - off;
665 else
666 mhip->ip_off |= IP_MF;
667 mhip->ip_len = htons((u_short)(len + mhlen));
668 m->m_next = m_copy(m0, off, len);
669 if (m->m_next == 0) {
670 (void) m_free(m);
671 error = ENOBUFS; /* ??? */
672 ipstat.ips_odropped++;
673 goto sendorfree;
674 }
675 m->m_pkthdr.len = mhlen + len;
676 m->m_pkthdr.rcvif = (struct ifnet *)0;
677 mhip->ip_off = htons((u_short)mhip->ip_off);
678 mhip->ip_sum = 0;
679 if (mhip->ip_vhl == IP_VHL_BORING) {
680 mhip->ip_sum = in_cksum_hdr(mhip);
681 } else {
682 mhip->ip_sum = in_cksum(m, mhlen);
683 }
684 *mnext = m;
685 mnext = &m->m_nextpkt;
686 ipstat.ips_ofragments++;
687 }
688 /*
689 * Update first fragment by trimming what's been copied out
690 * and updating header, then send each fragment (in order).
691 */
692 m = m0;
693 m_adj(m, hlen + firstlen - (u_short)ip->ip_len);
694 m->m_pkthdr.len = hlen + firstlen;
695 ip->ip_len = htons((u_short)m->m_pkthdr.len);
696 ip->ip_off = htons((u_short)(ip->ip_off | IP_MF));
697 ip->ip_sum = 0;
698 if (ip->ip_vhl == IP_VHL_BORING) {
699 ip->ip_sum = in_cksum_hdr(ip);
700 } else {
701 ip->ip_sum = in_cksum(m, hlen);
702 }
703 sendorfree:
704 for (m = m0; m; m = m0) {
705 m0 = m->m_nextpkt;
706 m->m_nextpkt = 0;
707 if (error == 0)
708 error = (*ifp->if_output)(ifp, m,
709 (struct sockaddr *)dst, ro->ro_rt);
710 else
711 m_freem(m);
712 }
713
714 if (error == 0)
715 ipstat.ips_fragmented++;
716 }
717 done:
718 return (error);
719 bad:
720 m_freem(m0);
721 goto done;
722 }
723
724 /*
725 * Insert IP options into preformed packet.
726 * Adjust IP destination as required for IP source routing,
727 * as indicated by a non-zero in_addr at the start of the options.
728 *
729 * XXX This routine assumes that the packet has no options in place.
730 */
731 static struct mbuf *
732 ip_insertoptions(m, opt, phlen)
733 register struct mbuf *m;
734 struct mbuf *opt;
735 int *phlen;
736 {
737 register struct ipoption *p = mtod(opt, struct ipoption *);
738 struct mbuf *n;
739 register struct ip *ip = mtod(m, struct ip *);
740 unsigned optlen;
741
742 optlen = opt->m_len - sizeof(p->ipopt_dst);
743 if (optlen + (u_short)ip->ip_len > IP_MAXPACKET)
744 return (m); /* XXX should fail */
745 if (p->ipopt_dst.s_addr)
746 ip->ip_dst = p->ipopt_dst;
747 if (m->m_flags & M_EXT || m->m_data - optlen < m->m_pktdat) {
748 MGETHDR(n, M_DONTWAIT, MT_HEADER);
749 if (n == 0)
750 return (m);
751 n->m_pkthdr.rcvif = (struct ifnet *)0;
752 n->m_pkthdr.len = m->m_pkthdr.len + optlen;
753 m->m_len -= sizeof(struct ip);
754 m->m_data += sizeof(struct ip);
755 n->m_next = m;
756 m = n;
757 m->m_len = optlen + sizeof(struct ip);
758 m->m_data += max_linkhdr;
759 (void)memcpy(mtod(m, void *), ip, sizeof(struct ip));
760 } else {
761 m->m_data -= optlen;
762 m->m_len += optlen;
763 m->m_pkthdr.len += optlen;
764 ovbcopy((caddr_t)ip, mtod(m, caddr_t), sizeof(struct ip));
765 }
766 ip = mtod(m, struct ip *);
767 bcopy(p->ipopt_list, ip + 1, optlen);
768 *phlen = sizeof(struct ip) + optlen;
769 ip->ip_vhl = IP_MAKE_VHL(IPVERSION, *phlen >> 2);
770 ip->ip_len += optlen;
771 return (m);
772 }
773
774 /*
775 * Copy options from ip to jp,
776 * omitting those not copied during fragmentation.
777 */
778 #if !defined(IPFILTER) && !defined(IPFILTER_LKM)
779 static
780 #endif
781 int
782 ip_optcopy(ip, jp)
783 struct ip *ip, *jp;
784 {
785 register u_char *cp, *dp;
786 int opt, optlen, cnt;
787
788 cp = (u_char *)(ip + 1);
789 dp = (u_char *)(jp + 1);
790 cnt = (IP_VHL_HL(ip->ip_vhl) << 2) - sizeof (struct ip);
791 for (; cnt > 0; cnt -= optlen, cp += optlen) {
792 opt = cp[0];
793 if (opt == IPOPT_EOL)
794 break;
795 if (opt == IPOPT_NOP) {
796 /* Preserve for IP mcast tunnel's LSRR alignment. */
797 *dp++ = IPOPT_NOP;
798 optlen = 1;
799 continue;
800 } else
801 optlen = cp[IPOPT_OLEN];
802 /* bogus lengths should have been caught by ip_dooptions */
803 if (optlen > cnt)
804 optlen = cnt;
805 if (IPOPT_COPIED(opt)) {
806 bcopy(cp, dp, optlen);
807 dp += optlen;
808 }
809 }
810 for (optlen = dp - (u_char *)(jp+1); optlen & 0x3; optlen++)
811 *dp++ = IPOPT_EOL;
812 return (optlen);
813 }
814
815 /*
816 * IP socket option processing.
817 */
818 int
819 ip_ctloutput(so, sopt)
820 struct socket *so;
821 struct sockopt *sopt;
822 {
823 struct inpcb *inp = sotoinpcb(so);
824 int error, optval;
825
826 error = optval = 0;
827 if (sopt->sopt_level != IPPROTO_IP) {
828 return (EINVAL);
829 }
830
831 switch (sopt->sopt_dir) {
832 case SOPT_SET:
833 switch (sopt->sopt_name) {
834 case IP_OPTIONS:
835 #ifdef notyet
836 case IP_RETOPTS:
837 #endif
838 {
839 struct mbuf *m;
840 if (sopt->sopt_valsize > MLEN) {
841 error = EMSGSIZE;
842 break;
843 }
844 MGET(m, sopt->sopt_p ? M_WAIT : M_DONTWAIT, MT_HEADER);
845 if (m == 0) {
846 error = ENOBUFS;
847 break;
848 }
849 m->m_len = sopt->sopt_valsize;
850 error = sooptcopyin(sopt, mtod(m, char *), m->m_len,
851 m->m_len);
852
853 return (ip_pcbopts(sopt->sopt_name, &inp->inp_options,
854 m));
855 }
856
857 case IP_TOS:
858 case IP_TTL:
859 case IP_RECVOPTS:
860 case IP_RECVRETOPTS:
861 case IP_RECVDSTADDR:
862 case IP_RECVIF:
863 error = sooptcopyin(sopt, &optval, sizeof optval,
864 sizeof optval);
865 if (error)
866 break;
867
868 switch (sopt->sopt_name) {
869 case IP_TOS:
870 inp->inp_ip_tos = optval;
871 break;
872
873 case IP_TTL:
874 inp->inp_ip_ttl = optval;
875 break;
876 #define OPTSET(bit) \
877 if (optval) \
878 inp->inp_flags |= bit; \
879 else \
880 inp->inp_flags &= ~bit;
881
882 case IP_RECVOPTS:
883 OPTSET(INP_RECVOPTS);
884 break;
885
886 case IP_RECVRETOPTS:
887 OPTSET(INP_RECVRETOPTS);
888 break;
889
890 case IP_RECVDSTADDR:
891 OPTSET(INP_RECVDSTADDR);
892 break;
893
894 case IP_RECVIF:
895 OPTSET(INP_RECVIF);
896 break;
897 }
898 break;
899 #undef OPTSET
900
901 case IP_MULTICAST_IF:
902 case IP_MULTICAST_VIF:
903 case IP_MULTICAST_TTL:
904 case IP_MULTICAST_LOOP:
905 case IP_ADD_MEMBERSHIP:
906 case IP_DROP_MEMBERSHIP:
907 error = ip_setmoptions(sopt, &inp->inp_moptions);
908 break;
909
910 case IP_PORTRANGE:
911 error = sooptcopyin(sopt, &optval, sizeof optval,
912 sizeof optval);
913 if (error)
914 break;
915
916 switch (optval) {
917 case IP_PORTRANGE_DEFAULT:
918 inp->inp_flags &= ~(INP_LOWPORT);
919 inp->inp_flags &= ~(INP_HIGHPORT);
920 break;
921
922 case IP_PORTRANGE_HIGH:
923 inp->inp_flags &= ~(INP_LOWPORT);
924 inp->inp_flags |= INP_HIGHPORT;
925 break;
926
927 case IP_PORTRANGE_LOW:
928 inp->inp_flags &= ~(INP_HIGHPORT);
929 inp->inp_flags |= INP_LOWPORT;
930 break;
931
932 default:
933 error = EINVAL;
934 break;
935 }
936 break;
937
938 default:
939 error = ENOPROTOOPT;
940 break;
941 }
942 break;
943
944 case SOPT_GET:
945 switch (sopt->sopt_name) {
946 case IP_OPTIONS:
947 case IP_RETOPTS:
948 if (inp->inp_options)
949 error = sooptcopyout(sopt,
950 mtod(inp->inp_options,
951 char *),
952 inp->inp_options->m_len);
953 else
954 sopt->sopt_valsize = 0;
955 break;
956
957 case IP_TOS:
958 case IP_TTL:
959 case IP_RECVOPTS:
960 case IP_RECVRETOPTS:
961 case IP_RECVDSTADDR:
962 case IP_RECVIF:
963 case IP_PORTRANGE:
964 switch (sopt->sopt_name) {
965
966 case IP_TOS:
967 optval = inp->inp_ip_tos;
968 break;
969
970 case IP_TTL:
971 optval = inp->inp_ip_ttl;
972 break;
973
974 #define OPTBIT(bit) (inp->inp_flags & bit ? 1 : 0)
975
976 case IP_RECVOPTS:
977 optval = OPTBIT(INP_RECVOPTS);
978 break;
979
980 case IP_RECVRETOPTS:
981 optval = OPTBIT(INP_RECVRETOPTS);
982 break;
983
984 case IP_RECVDSTADDR:
985 optval = OPTBIT(INP_RECVDSTADDR);
986 break;
987
988 case IP_RECVIF:
989 optval = OPTBIT(INP_RECVIF);
990 break;
991
992 case IP_PORTRANGE:
993 if (inp->inp_flags & INP_HIGHPORT)
994 optval = IP_PORTRANGE_HIGH;
995 else if (inp->inp_flags & INP_LOWPORT)
996 optval = IP_PORTRANGE_LOW;
997 else
998 optval = 0;
999 break;
1000 }
1001 error = sooptcopyout(sopt, &optval, sizeof optval);
1002 break;
1003
1004 case IP_MULTICAST_IF:
1005 case IP_MULTICAST_VIF:
1006 case IP_MULTICAST_TTL:
1007 case IP_MULTICAST_LOOP:
1008 case IP_ADD_MEMBERSHIP:
1009 case IP_DROP_MEMBERSHIP:
1010 error = ip_getmoptions(sopt, inp->inp_moptions);
1011 break;
1012
1013 default:
1014 error = ENOPROTOOPT;
1015 break;
1016 }
1017 break;
1018 }
1019 return (error);
1020 }
1021
1022 /*
1023 * Set up IP options in pcb for insertion in output packets.
1024 * Store in mbuf with pointer in pcbopt, adding pseudo-option
1025 * with destination address if source routed.
1026 */
1027 static int
1028 ip_pcbopts(optname, pcbopt, m)
1029 int optname;
1030 struct mbuf **pcbopt;
1031 register struct mbuf *m;
1032 {
1033 register int cnt, optlen;
1034 register u_char *cp;
1035 u_char opt;
1036
1037 /* turn off any old options */
1038 if (*pcbopt)
1039 (void)m_free(*pcbopt);
1040 *pcbopt = 0;
1041 if (m == (struct mbuf *)0 || m->m_len == 0) {
1042 /*
1043 * Only turning off any previous options.
1044 */
1045 if (m)
1046 (void)m_free(m);
1047 return (0);
1048 }
1049
1050 #ifndef vax
1051 if (m->m_len % sizeof(int32_t))
1052 goto bad;
1053 #endif
1054 /*
1055 * IP first-hop destination address will be stored before
1056 * actual options; move other options back
1057 * and clear it when none present.
1058 */
1059 if (m->m_data + m->m_len + sizeof(struct in_addr) >= &m->m_dat[MLEN])
1060 goto bad;
1061 cnt = m->m_len;
1062 m->m_len += sizeof(struct in_addr);
1063 cp = mtod(m, u_char *) + sizeof(struct in_addr);
1064 ovbcopy(mtod(m, caddr_t), (caddr_t)cp, (unsigned)cnt);
1065 bzero(mtod(m, caddr_t), sizeof(struct in_addr));
1066
1067 for (; cnt > 0; cnt -= optlen, cp += optlen) {
1068 opt = cp[IPOPT_OPTVAL];
1069 if (opt == IPOPT_EOL)
1070 break;
1071 if (opt == IPOPT_NOP)
1072 optlen = 1;
1073 else {
1074 if (cnt < IPOPT_OLEN + sizeof(*cp))
1075 goto bad;
1076 optlen = cp[IPOPT_OLEN];
1077 if (optlen < IPOPT_OLEN + sizeof(*cp) || optlen > cnt)
1078 goto bad;
1079 }
1080 switch (opt) {
1081
1082 default:
1083 break;
1084
1085 case IPOPT_LSRR:
1086 case IPOPT_SSRR:
1087 /*
1088 * user process specifies route as:
1089 * ->A->B->C->D
1090 * D must be our final destination (but we can't
1091 * check that since we may not have connected yet).
1092 * A is first hop destination, which doesn't appear in
1093 * actual IP option, but is stored before the options.
1094 */
1095 if (optlen < IPOPT_MINOFF - 1 + sizeof(struct in_addr))
1096 goto bad;
1097 m->m_len -= sizeof(struct in_addr);
1098 cnt -= sizeof(struct in_addr);
1099 optlen -= sizeof(struct in_addr);
1100 cp[IPOPT_OLEN] = optlen;
1101 /*
1102 * Move first hop before start of options.
1103 */
1104 bcopy((caddr_t)&cp[IPOPT_OFFSET+1], mtod(m, caddr_t),
1105 sizeof(struct in_addr));
1106 /*
1107 * Then copy rest of options back
1108 * to close up the deleted entry.
1109 */
1110 ovbcopy((caddr_t)(&cp[IPOPT_OFFSET+1] +
1111 sizeof(struct in_addr)),
1112 (caddr_t)&cp[IPOPT_OFFSET+1],
1113 (unsigned)cnt + sizeof(struct in_addr));
1114 break;
1115 }
1116 }
1117 if (m->m_len > MAX_IPOPTLEN + sizeof(struct in_addr))
1118 goto bad;
1119 *pcbopt = m;
1120 return (0);
1121
1122 bad:
1123 (void)m_free(m);
1124 return (EINVAL);
1125 }
1126
1127 /*
1128 * XXX
1129 * The whole multicast option thing needs to be re-thought.
1130 * Several of these options are equally applicable to non-multicast
1131 * transmission, and one (IP_MULTICAST_TTL) totally duplicates a
1132 * standard option (IP_TTL).
1133 */
1134 /*
1135 * Set the IP multicast options in response to user setsockopt().
1136 */
1137 static int
1138 ip_setmoptions(sopt, imop)
1139 struct sockopt *sopt;
1140 struct ip_moptions **imop;
1141 {
1142 int error = 0;
1143 int i;
1144 struct in_addr addr;
1145 struct ip_mreq mreq;
1146 struct ifnet *ifp;
1147 struct ip_moptions *imo = *imop;
1148 struct route ro;
1149 struct sockaddr_in *dst;
1150 int s;
1151
1152 if (imo == NULL) {
1153 /*
1154 * No multicast option buffer attached to the pcb;
1155 * allocate one and initialize to default values.
1156 */
1157 imo = (struct ip_moptions*)malloc(sizeof(*imo), M_IPMOPTS,
1158 M_WAITOK);
1159
1160 if (imo == NULL)
1161 return (ENOBUFS);
1162 *imop = imo;
1163 imo->imo_multicast_ifp = NULL;
1164 imo->imo_multicast_vif = -1;
1165 imo->imo_multicast_ttl = IP_DEFAULT_MULTICAST_TTL;
1166 imo->imo_multicast_loop = IP_DEFAULT_MULTICAST_LOOP;
1167 imo->imo_num_memberships = 0;
1168 }
1169
1170 switch (sopt->sopt_name) {
1171 /* store an index number for the vif you wanna use in the send */
1172 case IP_MULTICAST_VIF:
1173 if (legal_vif_num == 0) {
1174 error = EOPNOTSUPP;
1175 break;
1176 }
1177 error = sooptcopyin(sopt, &i, sizeof i, sizeof i);
1178 if (error)
1179 break;
1180 if (!legal_vif_num(i) && (i != -1)) {
1181 error = EINVAL;
1182 break;
1183 }
1184 imo->imo_multicast_vif = i;
1185 break;
1186
1187 case IP_MULTICAST_IF:
1188 /*
1189 * Select the interface for outgoing multicast packets.
1190 */
1191 error = sooptcopyin(sopt, &addr, sizeof addr, sizeof addr);
1192 if (error)
1193 break;
1194 /*
1195 * INADDR_ANY is used to remove a previous selection.
1196 * When no interface is selected, a default one is
1197 * chosen every time a multicast packet is sent.
1198 */
1199 if (addr.s_addr == INADDR_ANY) {
1200 imo->imo_multicast_ifp = NULL;
1201 break;
1202 }
1203 /*
1204 * The selected interface is identified by its local
1205 * IP address. Find the interface and confirm that
1206 * it supports multicasting.
1207 */
1208 s = splimp();
1209 INADDR_TO_IFP(addr, ifp);
1210 if (ifp == NULL || (ifp->if_flags & IFF_MULTICAST) == 0) {
1211 splx(s);
1212 error = EADDRNOTAVAIL;
1213 break;
1214 }
1215 imo->imo_multicast_ifp = ifp;
1216 splx(s);
1217 break;
1218
1219 case IP_MULTICAST_TTL:
1220 /*
1221 * Set the IP time-to-live for outgoing multicast packets.
1222 * The original multicast API required a char argument,
1223 * which is inconsistent with the rest of the socket API.
1224 * We allow either a char or an int.
1225 */
1226 if (sopt->sopt_valsize == 1) {
1227 u_char ttl;
1228 error = sooptcopyin(sopt, &ttl, 1, 1);
1229 if (error)
1230 break;
1231 imo->imo_multicast_ttl = ttl;
1232 } else {
1233 u_int ttl;
1234 error = sooptcopyin(sopt, &ttl, sizeof ttl,
1235 sizeof ttl);
1236 if (error)
1237 break;
1238 if (ttl > 255)
1239 error = EINVAL;
1240 else
1241 imo->imo_multicast_ttl = ttl;
1242 }
1243 break;
1244
1245 case IP_MULTICAST_LOOP:
1246 /*
1247 * Set the loopback flag for outgoing multicast packets.
1248 * Must be zero or one. The original multicast API required a
1249 * char argument, which is inconsistent with the rest
1250 * of the socket API. We allow either a char or an int.
1251 */
1252 if (sopt->sopt_valsize == 1) {
1253 u_char loop;
1254 error = sooptcopyin(sopt, &loop, 1, 1);
1255 if (error)
1256 break;
1257 imo->imo_multicast_loop = !!loop;
1258 } else {
1259 u_int loop;
1260 error = sooptcopyin(sopt, &loop, sizeof loop,
1261 sizeof loop);
1262 if (error)
1263 break;
1264 imo->imo_multicast_loop = !!loop;
1265 }
1266 break;
1267
1268 case IP_ADD_MEMBERSHIP:
1269 /*
1270 * Add a multicast group membership.
1271 * Group must be a valid IP multicast address.
1272 */
1273 error = sooptcopyin(sopt, &mreq, sizeof mreq, sizeof mreq);
1274 if (error)
1275 break;
1276
1277 if (!IN_MULTICAST(ntohl(mreq.imr_multiaddr.s_addr))) {
1278 error = EINVAL;
1279 break;
1280 }
1281 s = splimp();
1282 /*
1283 * If no interface address was provided, use the interface of
1284 * the route to the given multicast address.
1285 */
1286 if (mreq.imr_interface.s_addr == INADDR_ANY) {
1287 bzero((caddr_t)&ro, sizeof(ro));
1288 dst = (struct sockaddr_in *)&ro.ro_dst;
1289 dst->sin_len = sizeof(*dst);
1290 dst->sin_family = AF_INET;
1291 dst->sin_addr = mreq.imr_multiaddr;
1292 rtalloc(&ro);
1293 if (ro.ro_rt == NULL) {
1294 error = EADDRNOTAVAIL;
1295 splx(s);
1296 break;
1297 }
1298 ifp = ro.ro_rt->rt_ifp;
1299 rtfree(ro.ro_rt);
1300 }
1301 else {
1302 INADDR_TO_IFP(mreq.imr_interface, ifp);
1303 }
1304
1305 /*
1306 * See if we found an interface, and confirm that it
1307 * supports multicast.
1308 */
1309 if (ifp == NULL || (ifp->if_flags & IFF_MULTICAST) == 0) {
1310 error = EADDRNOTAVAIL;
1311 splx(s);
1312 break;
1313 }
1314 /*
1315 * See if the membership already exists or if all the
1316 * membership slots are full.
1317 */
1318 for (i = 0; i < imo->imo_num_memberships; ++i) {
1319 if (imo->imo_membership[i]->inm_ifp == ifp &&
1320 imo->imo_membership[i]->inm_addr.s_addr
1321 == mreq.imr_multiaddr.s_addr)
1322 break;
1323 }
1324 if (i < imo->imo_num_memberships) {
1325 error = EADDRINUSE;
1326 splx(s);
1327 break;
1328 }
1329 if (i == IP_MAX_MEMBERSHIPS) {
1330 error = ETOOMANYREFS;
1331 splx(s);
1332 break;
1333 }
1334 /*
1335 * Everything looks good; add a new record to the multicast
1336 * address list for the given interface.
1337 */
1338 if ((imo->imo_membership[i] =
1339 in_addmulti(&mreq.imr_multiaddr, ifp)) == NULL) {
1340 error = ENOBUFS;
1341 splx(s);
1342 break;
1343 }
1344 ++imo->imo_num_memberships;
1345 splx(s);
1346 break;
1347
1348 case IP_DROP_MEMBERSHIP:
1349 /*
1350 * Drop a multicast group membership.
1351 * Group must be a valid IP multicast address.
1352 */
1353 error = sooptcopyin(sopt, &mreq, sizeof mreq, sizeof mreq);
1354 if (error)
1355 break;
1356
1357 if (!IN_MULTICAST(ntohl(mreq.imr_multiaddr.s_addr))) {
1358 error = EINVAL;
1359 break;
1360 }
1361
1362 s = splimp();
1363 /*
1364 * If an interface address was specified, get a pointer
1365 * to its ifnet structure.
1366 */
1367 if (mreq.imr_interface.s_addr == INADDR_ANY)
1368 ifp = NULL;
1369 else {
1370 INADDR_TO_IFP(mreq.imr_interface, ifp);
1371 if (ifp == NULL) {
1372 error = EADDRNOTAVAIL;
1373 splx(s);
1374 break;
1375 }
1376 }
1377 /*
1378 * Find the membership in the membership array.
1379 */
1380 for (i = 0; i < imo->imo_num_memberships; ++i) {
1381 if ((ifp == NULL ||
1382 imo->imo_membership[i]->inm_ifp == ifp) &&
1383 imo->imo_membership[i]->inm_addr.s_addr ==
1384 mreq.imr_multiaddr.s_addr)
1385 break;
1386 }
1387 if (i == imo->imo_num_memberships) {
1388 error = EADDRNOTAVAIL;
1389 splx(s);
1390 break;
1391 }
1392 /*
1393 * Give up the multicast address record to which the
1394 * membership points.
1395 */
1396 in_delmulti(imo->imo_membership[i]);
1397 /*
1398 * Remove the gap in the membership array.
1399 */
1400 for (++i; i < imo->imo_num_memberships; ++i)
1401 imo->imo_membership[i-1] = imo->imo_membership[i];
1402 --imo->imo_num_memberships;
1403 splx(s);
1404 break;
1405
1406 default:
1407 error = EOPNOTSUPP;
1408 break;
1409 }
1410
1411 /*
1412 * If all options have default values, no need to keep the mbuf.
1413 */
1414 if (imo->imo_multicast_ifp == NULL &&
1415 imo->imo_multicast_vif == -1 &&
1416 imo->imo_multicast_ttl == IP_DEFAULT_MULTICAST_TTL &&
1417 imo->imo_multicast_loop == IP_DEFAULT_MULTICAST_LOOP &&
1418 imo->imo_num_memberships == 0) {
1419 free(*imop, M_IPMOPTS);
1420 *imop = NULL;
1421 }
1422
1423 return (error);
1424 }
1425
1426 /*
1427 * Return the IP multicast options in response to user getsockopt().
1428 */
1429 static int
1430 ip_getmoptions(sopt, imo)
1431 struct sockopt *sopt;
1432 register struct ip_moptions *imo;
1433 {
1434 struct in_addr addr;
1435 struct in_ifaddr *ia;
1436 int error, optval;
1437 u_char coptval;
1438
1439 error = 0;
1440 switch (sopt->sopt_name) {
1441 case IP_MULTICAST_VIF:
1442 if (imo != NULL)
1443 optval = imo->imo_multicast_vif;
1444 else
1445 optval = -1;
1446 error = sooptcopyout(sopt, &optval, sizeof optval);
1447 break;
1448
1449 case IP_MULTICAST_IF:
1450 if (imo == NULL || imo->imo_multicast_ifp == NULL)
1451 addr.s_addr = INADDR_ANY;
1452 else {
1453 IFP_TO_IA(imo->imo_multicast_ifp, ia);
1454 addr.s_addr = (ia == NULL) ? INADDR_ANY
1455 : IA_SIN(ia)->sin_addr.s_addr;
1456 }
1457 error = sooptcopyout(sopt, &addr, sizeof addr);
1458 break;
1459
1460 case IP_MULTICAST_TTL:
1461 if (imo == 0)
1462 optval = coptval = IP_DEFAULT_MULTICAST_TTL;
1463 else
1464 optval = coptval = imo->imo_multicast_ttl;
1465 if (sopt->sopt_valsize == 1)
1466 error = sooptcopyout(sopt, &coptval, 1);
1467 else
1468 error = sooptcopyout(sopt, &optval, sizeof optval);
1469 break;
1470
1471 case IP_MULTICAST_LOOP:
1472 if (imo == 0)
1473 optval = coptval = IP_DEFAULT_MULTICAST_LOOP;
1474 else
1475 optval = coptval = imo->imo_multicast_loop;
1476 if (sopt->sopt_valsize == 1)
1477 error = sooptcopyout(sopt, &coptval, 1);
1478 else
1479 error = sooptcopyout(sopt, &optval, sizeof optval);
1480 break;
1481
1482 default:
1483 error = ENOPROTOOPT;
1484 break;
1485 }
1486 return (error);
1487 }
1488
1489 /*
1490 * Discard the IP multicast options.
1491 */
1492 void
1493 ip_freemoptions(imo)
1494 register struct ip_moptions *imo;
1495 {
1496 register int i;
1497
1498 if (imo != NULL) {
1499 for (i = 0; i < imo->imo_num_memberships; ++i)
1500 in_delmulti(imo->imo_membership[i]);
1501 free(imo, M_IPMOPTS);
1502 }
1503 }
1504
1505 /*
1506 * Routine called from ip_output() to loop back a copy of an IP multicast
1507 * packet to the input queue of a specified interface. Note that this
1508 * calls the output routine of the loopback "driver", but with an interface
1509 * pointer that might NOT be a loopback interface -- evil, but easier than
1510 * replicating that code here.
1511 */
1512 static void
1513 ip_mloopback(ifp, m, dst, hlen)
1514 struct ifnet *ifp;
1515 register struct mbuf *m;
1516 register struct sockaddr_in *dst;
1517 int hlen;
1518 {
1519 register struct ip *ip;
1520 struct mbuf *copym;
1521
1522 copym = m_copy(m, 0, M_COPYALL);
1523 if (copym != NULL && (copym->m_flags & M_EXT || copym->m_len < hlen))
1524 copym = m_pullup(copym, hlen);
1525 if (copym != NULL) {
1526 /*
1527 * We don't bother to fragment if the IP length is greater
1528 * than the interface's MTU. Can this possibly matter?
1529 */
1530 ip = mtod(copym, struct ip *);
1531 ip->ip_len = htons((u_short)ip->ip_len);
1532 ip->ip_off = htons((u_short)ip->ip_off);
1533 ip->ip_sum = 0;
1534 if (ip->ip_vhl == IP_VHL_BORING) {
1535 ip->ip_sum = in_cksum_hdr(ip);
1536 } else {
1537 ip->ip_sum = in_cksum(copym, hlen);
1538 }
1539 /*
1540 * NB:
1541 * It's not clear whether there are any lingering
1542 * reentrancy problems in other areas which might
1543 * be exposed by using ip_input directly (in
1544 * particular, everything which modifies the packet
1545 * in-place). Yet another option is using the
1546 * protosw directly to deliver the looped back
1547 * packet. For the moment, we'll err on the side
1548 * of safety by using if_simloop().
1549 */
1550 #if 1 /* XXX */
1551 if (dst->sin_family != AF_INET) {
1552 printf("ip_mloopback: bad address family %d\n",
1553 dst->sin_family);
1554 dst->sin_family = AF_INET;
1555 }
1556 #endif
1557
1558 #ifdef notdef
1559 copym->m_pkthdr.rcvif = ifp;
1560 ip_input(copym);
1561 #else
1562 if_simloop(ifp, copym, (struct sockaddr *)dst, 0);
1563 #endif
1564 }
1565 }
Cache object: cbb21c57a464ff33316a9e5111bc96b2
|