FreeBSD kernel IPv4 code
ip_icmp.c
Go to the documentation of this file.
1/*-
2 * SPDX-License-Identifier: BSD-3-Clause
3 *
4 * Copyright (c) 1982, 1986, 1988, 1993
5 * The Regents of the University of California. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the University nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 *
31 * @(#)ip_icmp.c 8.2 (Berkeley) 1/4/94
32 */
33
34#include <sys/cdefs.h>
35__FBSDID("$FreeBSD$");
36
37#include "opt_inet.h"
38
39#include <sys/param.h>
40#include <sys/systm.h>
41#include <sys/mbuf.h>
42#include <sys/protosw.h>
43#include <sys/socket.h>
44#include <sys/time.h>
45#include <sys/kernel.h>
46#include <sys/lock.h>
47#include <sys/sysctl.h>
48#include <sys/syslog.h>
49
50#include <net/if.h>
51#include <net/if_var.h>
52#include <net/if_types.h>
53#include <net/route.h>
54#include <net/route/route_ctl.h>
55#include <net/route/nhop.h>
56#include <net/vnet.h>
57
58#include <netinet/in.h>
59#include <netinet/in_fib.h>
60#include <netinet/in_pcb.h>
61#include <netinet/in_systm.h>
62#include <netinet/in_var.h>
63#include <netinet/ip.h>
64#include <netinet/ip_icmp.h>
65#include <netinet/ip_var.h>
66#include <netinet/ip_options.h>
67#include <netinet/sctp.h>
68#include <netinet/tcp.h>
69#include <netinet/tcp_var.h>
70#include <netinet/tcpip.h>
71#include <netinet/icmp_var.h>
72
73#ifdef INET
74
75#include <machine/in_cksum.h>
76
77#include <security/mac/mac_framework.h>
78#endif /* INET */
79
80/*
81 * ICMP routines: error generation, receive packet processing, and
82 * routines to turnaround packets back to the originator, and
83 * host table maintenance routines.
84 */
85VNET_DEFINE_STATIC(int, icmplim) = 200;
86#define V_icmplim VNET(icmplim)
87SYSCTL_INT(_net_inet_icmp, ICMPCTL_ICMPLIM, icmplim, CTLFLAG_VNET | CTLFLAG_RW,
88 &VNET_NAME(icmplim), 0,
89 "Maximum number of ICMP responses per second");
90
91VNET_DEFINE_STATIC(int, icmplim_output) = 1;
92#define V_icmplim_output VNET(icmplim_output)
93SYSCTL_INT(_net_inet_icmp, OID_AUTO, icmplim_output, CTLFLAG_VNET | CTLFLAG_RW,
94 &VNET_NAME(icmplim_output), 0,
95 "Enable logging of ICMP response rate limiting");
96
97#ifdef INET
100SYSCTL_VNET_PCPUSTAT(_net_inet_icmp, ICMPCTL_STATS, stats, struct icmpstat,
101 icmpstat, "ICMP statistics (struct icmpstat, netinet/icmp_var.h)");
102
103#ifdef VIMAGE
105#endif /* VIMAGE */
106
107VNET_DEFINE_STATIC(int, icmpmaskrepl) = 0;
108#define V_icmpmaskrepl VNET(icmpmaskrepl)
109SYSCTL_INT(_net_inet_icmp, ICMPCTL_MASKREPL, maskrepl, CTLFLAG_VNET | CTLFLAG_RW,
110 &VNET_NAME(icmpmaskrepl), 0,
111 "Reply to ICMP Address Mask Request packets");
112
113VNET_DEFINE_STATIC(u_int, icmpmaskfake) = 0;
114#define V_icmpmaskfake VNET(icmpmaskfake)
115SYSCTL_UINT(_net_inet_icmp, OID_AUTO, maskfake, CTLFLAG_VNET | CTLFLAG_RW,
116 &VNET_NAME(icmpmaskfake), 0,
117 "Fake reply to ICMP Address Mask Request packets");
118
119VNET_DEFINE(int, drop_redirect) = 0;
120#define V_drop_redirect VNET(drop_redirect)
121SYSCTL_INT(_net_inet_icmp, OID_AUTO, drop_redirect, CTLFLAG_VNET | CTLFLAG_RW,
122 &VNET_NAME(drop_redirect), 0,
123 "Ignore ICMP redirects");
124
125VNET_DEFINE_STATIC(int, log_redirect) = 0;
126#define V_log_redirect VNET(log_redirect)
127SYSCTL_INT(_net_inet_icmp, OID_AUTO, log_redirect, CTLFLAG_VNET | CTLFLAG_RW,
128 &VNET_NAME(log_redirect), 0,
129 "Log ICMP redirects to the console");
130
131VNET_DEFINE_STATIC(int, redirtimeout) = 60 * 10; /* 10 minutes */
132#define V_redirtimeout VNET(redirtimeout)
133SYSCTL_INT(_net_inet_icmp, OID_AUTO, redirtimeout, CTLFLAG_VNET | CTLFLAG_RW,
134 &VNET_NAME(redirtimeout), 0,
135 "Delay in seconds before expiring redirect route");
136
137VNET_DEFINE_STATIC(char, reply_src[IFNAMSIZ]);
138#define V_reply_src VNET(reply_src)
139SYSCTL_STRING(_net_inet_icmp, OID_AUTO, reply_src, CTLFLAG_VNET | CTLFLAG_RW,
140 &VNET_NAME(reply_src), IFNAMSIZ,
141 "ICMP reply source for non-local packets");
142
143VNET_DEFINE_STATIC(int, icmp_rfi) = 0;
144#define V_icmp_rfi VNET(icmp_rfi)
145SYSCTL_INT(_net_inet_icmp, OID_AUTO, reply_from_interface, CTLFLAG_VNET | CTLFLAG_RW,
146 &VNET_NAME(icmp_rfi), 0,
147 "ICMP reply from incoming interface for non-local packets");
148/* Router requirements RFC 1812 section 4.3.2.3 requires 576 - 28. */
149VNET_DEFINE_STATIC(int, icmp_quotelen) = 548;
150#define V_icmp_quotelen VNET(icmp_quotelen)
151SYSCTL_INT(_net_inet_icmp, OID_AUTO, quotelen, CTLFLAG_VNET | CTLFLAG_RW,
152 &VNET_NAME(icmp_quotelen), 0,
153 "Number of bytes from original packet to quote in ICMP reply");
154
155VNET_DEFINE_STATIC(int, icmpbmcastecho) = 0;
156#define V_icmpbmcastecho VNET(icmpbmcastecho)
157SYSCTL_INT(_net_inet_icmp, OID_AUTO, bmcastecho, CTLFLAG_VNET | CTLFLAG_RW,
158 &VNET_NAME(icmpbmcastecho), 0,
159 "Reply to multicast ICMP Echo Request and Timestamp packets");
160
161VNET_DEFINE_STATIC(int, icmptstamprepl) = 1;
162#define V_icmptstamprepl VNET(icmptstamprepl)
163SYSCTL_INT(_net_inet_icmp, OID_AUTO, tstamprepl, CTLFLAG_VNET | CTLFLAG_RW,
164 &VNET_NAME(icmptstamprepl), 0,
165 "Respond to ICMP Timestamp packets");
166
167VNET_DEFINE_STATIC(int, error_keeptags) = 0;
168#define V_error_keeptags VNET(error_keeptags)
169SYSCTL_INT(_net_inet_icmp, OID_AUTO, error_keeptags, CTLFLAG_VNET | CTLFLAG_RW,
170 &VNET_NAME(error_keeptags), 0,
171 "ICMP error response keeps copy of mbuf_tags of original packet");
172
173#ifdef ICMPPRINTFS
174int icmpprintfs = 0;
175#endif
176
177static void icmp_reflect(struct mbuf *);
178static void icmp_send(struct mbuf *, struct mbuf *);
179static int icmp_verify_redirect_gateway(struct sockaddr_in *,
180 struct sockaddr_in *, struct sockaddr_in *, u_int);
181
182extern struct protosw inetsw[];
183
184/*
185 * Kernel module interface for updating icmpstat. The argument is an index
186 * into icmpstat treated as an array of u_long. While this encodes the
187 * general layout of icmpstat into the caller, it doesn't encode its
188 * location, so that future changes to add, for example, per-CPU stats
189 * support won't cause binary compatibility problems for kernel modules.
190 */
191void
192kmod_icmpstat_inc(int statnum)
193{
194
195 counter_u64_add(VNET(icmpstat)[statnum], 1);
196}
197
198/*
199 * Generate an error packet of type error
200 * in response to bad packet ip.
201 */
202void
203icmp_error(struct mbuf *n, int type, int code, uint32_t dest, int mtu)
204{
205 struct ip *oip, *nip;
206 struct icmp *icp;
207 struct mbuf *m;
208 unsigned icmplen, icmpelen, nlen, oiphlen;
209
210 KASSERT((u_int)type <= ICMP_MAXTYPE, ("%s: illegal ICMP type",
211 __func__));
212
213 if (type != ICMP_REDIRECT)
214 ICMPSTAT_INC(icps_error);
215 /*
216 * Don't send error:
217 * if the original packet was encrypted.
218 * if not the first fragment of message.
219 * in response to a multicast or broadcast packet.
220 * if the old packet protocol was an ICMP error message.
221 */
222 if (n->m_flags & M_DECRYPTED)
223 goto freeit;
224 if (n->m_flags & (M_BCAST|M_MCAST))
225 goto freeit;
226
227 /* Drop if IP header plus 8 bytes is not contiguous in first mbuf. */
228 if (n->m_len < sizeof(struct ip) + ICMP_MINLEN)
229 goto freeit;
230 oip = mtod(n, struct ip *);
231 oiphlen = oip->ip_hl << 2;
232 if (n->m_len < oiphlen + ICMP_MINLEN)
233 goto freeit;
234#ifdef ICMPPRINTFS
235 if (icmpprintfs)
236 printf("icmp_error(%p, %x, %d)\n", oip, type, code);
237#endif
238 if (oip->ip_off & htons(~(IP_MF|IP_DF)))
239 goto freeit;
240 if (oip->ip_p == IPPROTO_ICMP && type != ICMP_REDIRECT &&
241 !ICMP_INFOTYPE(((struct icmp *)((caddr_t)oip +
242 oiphlen))->icmp_type)) {
243 ICMPSTAT_INC(icps_oldicmp);
244 goto freeit;
245 }
246 /*
247 * Calculate length to quote from original packet and
248 * prevent the ICMP mbuf from overflowing.
249 * Unfortunately this is non-trivial since ip_forward()
250 * sends us truncated packets.
251 */
252 nlen = m_length(n, NULL);
253 if (oip->ip_p == IPPROTO_TCP) {
254 struct tcphdr *th;
255 int tcphlen;
256
257 if (oiphlen + sizeof(struct tcphdr) > n->m_len &&
258 n->m_next == NULL)
259 goto stdreply;
260 if (n->m_len < oiphlen + sizeof(struct tcphdr) &&
261 (n = m_pullup(n, oiphlen + sizeof(struct tcphdr))) == NULL)
262 goto freeit;
263 oip = mtod(n, struct ip *);
264 th = mtodo(n, oiphlen);
265 tcphlen = th->th_off << 2;
266 if (tcphlen < sizeof(struct tcphdr))
267 goto freeit;
268 if (ntohs(oip->ip_len) < oiphlen + tcphlen)
269 goto freeit;
270 if (oiphlen + tcphlen > n->m_len && n->m_next == NULL)
271 goto stdreply;
272 if (n->m_len < oiphlen + tcphlen &&
273 (n = m_pullup(n, oiphlen + tcphlen)) == NULL)
274 goto freeit;
275 oip = mtod(n, struct ip *);
276 icmpelen = max(tcphlen, min(V_icmp_quotelen,
277 ntohs(oip->ip_len) - oiphlen));
278 } else if (oip->ip_p == IPPROTO_SCTP) {
279 struct sctphdr *sh;
280 struct sctp_chunkhdr *ch;
281
282 if (ntohs(oip->ip_len) < oiphlen + sizeof(struct sctphdr))
283 goto stdreply;
284 if (oiphlen + sizeof(struct sctphdr) > n->m_len &&
285 n->m_next == NULL)
286 goto stdreply;
287 if (n->m_len < oiphlen + sizeof(struct sctphdr) &&
288 (n = m_pullup(n, oiphlen + sizeof(struct sctphdr))) == NULL)
289 goto freeit;
290 oip = mtod(n, struct ip *);
291 icmpelen = max(sizeof(struct sctphdr),
292 min(V_icmp_quotelen, ntohs(oip->ip_len) - oiphlen));
293 sh = mtodo(n, oiphlen);
294 if (ntohl(sh->v_tag) == 0 &&
295 ntohs(oip->ip_len) >= oiphlen +
296 sizeof(struct sctphdr) + 8 &&
297 (n->m_len >= oiphlen + sizeof(struct sctphdr) + 8 ||
298 n->m_next != NULL)) {
299 if (n->m_len < oiphlen + sizeof(struct sctphdr) + 8 &&
300 (n = m_pullup(n, oiphlen +
301 sizeof(struct sctphdr) + 8)) == NULL)
302 goto freeit;
303 oip = mtod(n, struct ip *);
304 sh = mtodo(n, oiphlen);
305 ch = (struct sctp_chunkhdr *)(sh + 1);
306 if (ch->chunk_type == SCTP_INITIATION) {
307 icmpelen = max(sizeof(struct sctphdr) + 8,
308 min(V_icmp_quotelen, ntohs(oip->ip_len) -
309 oiphlen));
310 }
311 }
312 } else
313stdreply: icmpelen = max(8, min(V_icmp_quotelen, ntohs(oip->ip_len) -
314 oiphlen));
315
316 icmplen = min(oiphlen + icmpelen, nlen);
317 if (icmplen < sizeof(struct ip))
318 goto freeit;
319
320 if (MHLEN > sizeof(struct ip) + ICMP_MINLEN + icmplen)
321 m = m_gethdr(M_NOWAIT, MT_DATA);
322 else
323 m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
324 if (m == NULL)
325 goto freeit;
326#ifdef MAC
327 mac_netinet_icmp_reply(n, m);
328#endif
329 icmplen = min(icmplen, M_TRAILINGSPACE(m) -
330 sizeof(struct ip) - ICMP_MINLEN);
331 m_align(m, sizeof(struct ip) + ICMP_MINLEN + icmplen);
332 m->m_data += sizeof(struct ip);
333 m->m_len = ICMP_MINLEN + icmplen;
334
335 /* XXX MRT make the outgoing packet use the same FIB
336 * that was associated with the incoming packet
337 */
338 M_SETFIB(m, M_GETFIB(n));
339 icp = mtod(m, struct icmp *);
340 ICMPSTAT_INC(icps_outhist[type]);
341 icp->icmp_type = type;
342 if (type == ICMP_REDIRECT)
343 icp->icmp_gwaddr.s_addr = dest;
344 else {
345 icp->icmp_void = 0;
346 /*
347 * The following assignments assume an overlay with the
348 * just zeroed icmp_void field.
349 */
350 if (type == ICMP_PARAMPROB) {
351 icp->icmp_pptr = code;
352 code = 0;
353 } else if (type == ICMP_UNREACH &&
354 code == ICMP_UNREACH_NEEDFRAG && mtu) {
355 icp->icmp_nextmtu = htons(mtu);
356 }
357 }
358 icp->icmp_code = code;
359
360 /*
361 * Copy the quotation into ICMP message and
362 * convert quoted IP header back to network representation.
363 */
364 m_copydata(n, 0, icmplen, (caddr_t)&icp->icmp_ip);
365 nip = &icp->icmp_ip;
366
367 /*
368 * Set up ICMP message mbuf and copy old IP header (without options
369 * in front of ICMP message.
370 * If the original mbuf was meant to bypass the firewall, the error
371 * reply should bypass as well.
372 */
373 m->m_flags |= n->m_flags & M_SKIP_FIREWALL;
374 KASSERT(M_LEADINGSPACE(m) >= sizeof(struct ip),
375 ("insufficient space for ip header"));
376 m->m_data -= sizeof(struct ip);
377 m->m_len += sizeof(struct ip);
378 m->m_pkthdr.len = m->m_len;
379 m->m_pkthdr.rcvif = n->m_pkthdr.rcvif;
380 nip = mtod(m, struct ip *);
381 bcopy((caddr_t)oip, (caddr_t)nip, sizeof(struct ip));
382 nip->ip_len = htons(m->m_len);
383 nip->ip_v = IPVERSION;
384 nip->ip_hl = 5;
385 nip->ip_p = IPPROTO_ICMP;
386 nip->ip_tos = 0;
387 nip->ip_off = 0;
388
389 if (V_error_keeptags)
390 m_tag_copy_chain(m, n, M_NOWAIT);
391
392 icmp_reflect(m);
393
394freeit:
395 m_freem(n);
396}
397
398/*
399 * Process a received ICMP message.
400 */
401int
402icmp_input(struct mbuf **mp, int *offp, int proto)
403{
404 struct icmp *icp;
405 struct in_ifaddr *ia;
406 struct mbuf *m = *mp;
407 struct ip *ip = mtod(m, struct ip *);
408 struct sockaddr_in icmpsrc, icmpdst, icmpgw;
409 int hlen = *offp;
410 int icmplen = ntohs(ip->ip_len) - *offp;
411 int i, code;
412 void (*ctlfunc)(int, struct sockaddr *, void *);
413 int fibnum;
414
415 NET_EPOCH_ASSERT();
416
417 *mp = NULL;
418
419 /*
420 * Locate icmp structure in mbuf, and check
421 * that not corrupted and of at least minimum length.
422 */
423#ifdef ICMPPRINTFS
424 if (icmpprintfs) {
425 char srcbuf[INET_ADDRSTRLEN];
426 char dstbuf[INET_ADDRSTRLEN];
427
428 printf("icmp_input from %s to %s, len %d\n",
429 inet_ntoa_r(ip->ip_src, srcbuf),
430 inet_ntoa_r(ip->ip_dst, dstbuf), icmplen);
431 }
432#endif
433 if (icmplen < ICMP_MINLEN) {
434 ICMPSTAT_INC(icps_tooshort);
435 goto freeit;
436 }
437 i = hlen + min(icmplen, ICMP_ADVLENMIN);
438 if (m->m_len < i && (m = m_pullup(m, i)) == NULL) {
439 ICMPSTAT_INC(icps_tooshort);
440 return (IPPROTO_DONE);
441 }
442 ip = mtod(m, struct ip *);
443 m->m_len -= hlen;
444 m->m_data += hlen;
445 icp = mtod(m, struct icmp *);
446 if (in_cksum(m, icmplen)) {
447 ICMPSTAT_INC(icps_checksum);
448 goto freeit;
449 }
450 m->m_len += hlen;
451 m->m_data -= hlen;
452
453#ifdef ICMPPRINTFS
454 if (icmpprintfs)
455 printf("icmp_input, type %d code %d\n", icp->icmp_type,
456 icp->icmp_code);
457#endif
458
459 /*
460 * Message type specific processing.
461 */
462 if (icp->icmp_type > ICMP_MAXTYPE)
463 goto raw;
464
465 /* Initialize */
466 bzero(&icmpsrc, sizeof(icmpsrc));
467 icmpsrc.sin_len = sizeof(struct sockaddr_in);
468 icmpsrc.sin_family = AF_INET;
469 bzero(&icmpdst, sizeof(icmpdst));
470 icmpdst.sin_len = sizeof(struct sockaddr_in);
471 icmpdst.sin_family = AF_INET;
472 bzero(&icmpgw, sizeof(icmpgw));
473 icmpgw.sin_len = sizeof(struct sockaddr_in);
474 icmpgw.sin_family = AF_INET;
475
476 ICMPSTAT_INC(icps_inhist[icp->icmp_type]);
477 code = icp->icmp_code;
478 switch (icp->icmp_type) {
479 case ICMP_UNREACH:
480 switch (code) {
481 case ICMP_UNREACH_NET:
491 code = PRC_UNREACH_NET;
492 break;
493
495 code = PRC_MSGSIZE;
496 break;
497
498 /*
499 * RFC 1122, Sections 3.2.2.1 and 4.2.3.9.
500 * Treat subcodes 2,3 as immediate RST
501 */
503 code = PRC_UNREACH_PROTOCOL;
504 break;
506 code = PRC_UNREACH_PORT;
507 break;
508
512 code = PRC_UNREACH_ADMIN_PROHIB;
513 break;
514
515 default:
516 goto badcode;
517 }
518 goto deliver;
519
520 case ICMP_TIMXCEED:
521 if (code > 1)
522 goto badcode;
523 code += PRC_TIMXCEED_INTRANS;
524 goto deliver;
525
526 case ICMP_PARAMPROB:
527 if (code > 1)
528 goto badcode;
529 code = PRC_PARAMPROB;
530 deliver:
531 /*
532 * Problem with datagram; advise higher level routines.
533 */
534 if (icmplen < ICMP_ADVLENMIN || icmplen < ICMP_ADVLEN(icp) ||
535 icp->icmp_ip.ip_hl < (sizeof(struct ip) >> 2)) {
536 ICMPSTAT_INC(icps_badlen);
537 goto freeit;
538 }
539 /* Discard ICMP's in response to multicast packets */
540 if (IN_MULTICAST(ntohl(icp->icmp_ip.ip_dst.s_addr)))
541 goto badcode;
542#ifdef ICMPPRINTFS
543 if (icmpprintfs)
544 printf("deliver to protocol %d\n", icp->icmp_ip.ip_p);
545#endif
546 icmpsrc.sin_addr = icp->icmp_ip.ip_dst;
547 /*
548 * XXX if the packet contains [IPv4 AH TCP], we can't make a
549 * notification to TCP layer.
550 */
551 i = sizeof(struct ip) + min(icmplen, ICMP_ADVLENPREF(icp));
553 if (m->m_len < i && (m = m_pullup(m, i)) == NULL) {
554 /* This should actually not happen */
555 ICMPSTAT_INC(icps_tooshort);
556 return (IPPROTO_DONE);
557 }
558 ip = mtod(m, struct ip *);
559 icp = (struct icmp *)(ip + 1);
560 /*
561 * The upper layer handler can rely on:
562 * - The outer IP header has no options.
563 * - The outer IP header, the ICMP header, the inner IP header,
564 * and the first n bytes of the inner payload are contiguous.
565 * n is at least 8, but might be larger based on
566 * ICMP_ADVLENPREF. See its definition in ip_icmp.h.
567 */
568 ctlfunc = inetsw[ip_protox[icp->icmp_ip.ip_p]].pr_ctlinput;
569 if (ctlfunc)
570 (*ctlfunc)(code, (struct sockaddr *)&icmpsrc,
571 (void *)&icp->icmp_ip);
572 break;
573
574 badcode:
575 ICMPSTAT_INC(icps_badcode);
576 break;
577
578 case ICMP_ECHO:
579 if (!V_icmpbmcastecho
580 && (m->m_flags & (M_MCAST | M_BCAST)) != 0) {
581 ICMPSTAT_INC(icps_bmcastecho);
582 break;
583 }
585 goto freeit;
587 goto reflect;
588
589 case ICMP_TSTAMP:
590 if (V_icmptstamprepl == 0)
591 break;
592 if (!V_icmpbmcastecho
593 && (m->m_flags & (M_MCAST | M_BCAST)) != 0) {
594 ICMPSTAT_INC(icps_bmcasttstamp);
595 break;
596 }
597 if (icmplen < ICMP_TSLEN) {
598 ICMPSTAT_INC(icps_badlen);
599 break;
600 }
602 goto freeit;
604 icp->icmp_rtime = iptime();
605 icp->icmp_ttime = icp->icmp_rtime; /* bogus, do later! */
606 goto reflect;
607
608 case ICMP_MASKREQ:
609 if (V_icmpmaskrepl == 0)
610 break;
611 /*
612 * We are not able to respond with all ones broadcast
613 * unless we receive it over a point-to-point interface.
614 */
615 if (icmplen < ICMP_MASKLEN)
616 break;
617 switch (ip->ip_dst.s_addr) {
618 case INADDR_BROADCAST:
619 case INADDR_ANY:
620 icmpdst.sin_addr = ip->ip_src;
621 break;
622
623 default:
624 icmpdst.sin_addr = ip->ip_dst;
625 }
626 ia = (struct in_ifaddr *)ifaof_ifpforaddr(
627 (struct sockaddr *)&icmpdst, m->m_pkthdr.rcvif);
628 if (ia == NULL)
629 break;
630 if (ia->ia_ifp == NULL)
631 break;
633 if (V_icmpmaskfake == 0)
634 icp->icmp_mask = ia->ia_sockmask.sin_addr.s_addr;
635 else
636 icp->icmp_mask = V_icmpmaskfake;
637 if (ip->ip_src.s_addr == 0) {
638 if (ia->ia_ifp->if_flags & IFF_BROADCAST)
639 ip->ip_src = satosin(&ia->ia_broadaddr)->sin_addr;
640 else if (ia->ia_ifp->if_flags & IFF_POINTOPOINT)
641 ip->ip_src = satosin(&ia->ia_dstaddr)->sin_addr;
642 }
643reflect:
644 ICMPSTAT_INC(icps_reflect);
645 ICMPSTAT_INC(icps_outhist[icp->icmp_type]);
646 icmp_reflect(m);
647 return (IPPROTO_DONE);
648
649 case ICMP_REDIRECT:
650 if (V_log_redirect) {
651 u_long src, dst, gw;
652
653 src = ntohl(ip->ip_src.s_addr);
654 dst = ntohl(icp->icmp_ip.ip_dst.s_addr);
655 gw = ntohl(icp->icmp_gwaddr.s_addr);
656 printf("icmp redirect from %d.%d.%d.%d: "
657 "%d.%d.%d.%d => %d.%d.%d.%d\n",
658 (int)(src >> 24), (int)((src >> 16) & 0xff),
659 (int)((src >> 8) & 0xff), (int)(src & 0xff),
660 (int)(dst >> 24), (int)((dst >> 16) & 0xff),
661 (int)((dst >> 8) & 0xff), (int)(dst & 0xff),
662 (int)(gw >> 24), (int)((gw >> 16) & 0xff),
663 (int)((gw >> 8) & 0xff), (int)(gw & 0xff));
664 }
665 /*
666 * RFC1812 says we must ignore ICMP redirects if we
667 * are acting as router.
668 */
670 break;
671 if (code > 3)
672 goto badcode;
673 if (icmplen < ICMP_ADVLENMIN || icmplen < ICMP_ADVLEN(icp) ||
674 icp->icmp_ip.ip_hl < (sizeof(struct ip) >> 2)) {
675 ICMPSTAT_INC(icps_badlen);
676 break;
677 }
678 /*
679 * Short circuit routing redirects to force
680 * immediate change in the kernel's routing
681 * tables. The message is also handed to anyone
682 * listening on a raw socket (e.g. the routing
683 * daemon for use in updating its tables).
684 */
685 icmpgw.sin_addr = ip->ip_src;
686 icmpdst.sin_addr = icp->icmp_gwaddr;
687#ifdef ICMPPRINTFS
688 if (icmpprintfs) {
689 char dstbuf[INET_ADDRSTRLEN];
690 char gwbuf[INET_ADDRSTRLEN];
691
692 printf("redirect dst %s to %s\n",
693 inet_ntoa_r(icp->icmp_ip.ip_dst, dstbuf),
694 inet_ntoa_r(icp->icmp_gwaddr, gwbuf));
695 }
696#endif
697 icmpsrc.sin_addr = icp->icmp_ip.ip_dst;
698
699 /*
700 * RFC 1122 says network (code 0,2) redirects SHOULD
701 * be treated identically to the host redirects.
702 * Given that, ignore network masks.
703 */
704
705 /*
706 * Variable values:
707 * icmpsrc: route destination
708 * icmpdst: route gateway
709 * icmpgw: message source
710 */
711
712 if (icmp_verify_redirect_gateway(&icmpgw, &icmpsrc, &icmpdst,
713 M_GETFIB(m)) != 0) {
714 /* TODO: increment bad redirects here */
715 break;
716 }
717
718 for ( fibnum = 0; fibnum < rt_numfibs; fibnum++) {
719 rib_add_redirect(fibnum, (struct sockaddr *)&icmpsrc,
720 (struct sockaddr *)&icmpdst,
721 (struct sockaddr *)&icmpgw, m->m_pkthdr.rcvif,
722 RTF_GATEWAY, V_redirtimeout);
723 }
724 pfctlinput(PRC_REDIRECT_HOST, (struct sockaddr *)&icmpsrc);
725 break;
726
727 /*
728 * No kernel processing for the following;
729 * just fall through to send to raw listener.
730 */
731 case ICMP_ECHOREPLY:
734 case ICMP_TSTAMPREPLY:
735 case ICMP_IREQREPLY:
736 case ICMP_MASKREPLY:
738 default:
739 break;
740 }
741
742raw:
743 *mp = m;
744 rip_input(mp, offp, proto);
745 return (IPPROTO_DONE);
746
747freeit:
748 m_freem(m);
749 return (IPPROTO_DONE);
750}
751
752/*
753 * Reflect the ip packet back to the source
754 */
755static void
756icmp_reflect(struct mbuf *m)
757{
758 struct ip *ip = mtod(m, struct ip *);
759 struct ifaddr *ifa;
760 struct ifnet *ifp;
761 struct in_ifaddr *ia;
762 struct in_addr t;
763 struct nhop_object *nh;
764 struct mbuf *opts = NULL;
765 int optlen = (ip->ip_hl << 2) - sizeof(struct ip);
766
767 NET_EPOCH_ASSERT();
768
769 if (IN_MULTICAST(ntohl(ip->ip_src.s_addr)) ||
770 IN_EXPERIMENTAL(ntohl(ip->ip_src.s_addr)) ||
771 IN_ZERONET(ntohl(ip->ip_src.s_addr)) ) {
772 m_freem(m); /* Bad return address */
773 ICMPSTAT_INC(icps_badaddr);
774 goto done; /* Ip_output() will check for broadcast */
775 }
776
777 t = ip->ip_dst;
778 ip->ip_dst = ip->ip_src;
779
780 /*
781 * Source selection for ICMP replies:
782 *
783 * If the incoming packet was addressed directly to one of our
784 * own addresses, use dst as the src for the reply.
785 */
786 CK_LIST_FOREACH(ia, INADDR_HASH(t.s_addr), ia_hash) {
787 if (t.s_addr == IA_SIN(ia)->sin_addr.s_addr) {
788 t = IA_SIN(ia)->sin_addr;
789 goto match;
790 }
791 }
792
793 /*
794 * If the incoming packet was addressed to one of our broadcast
795 * addresses, use the first non-broadcast address which corresponds
796 * to the incoming interface.
797 */
798 ifp = m->m_pkthdr.rcvif;
799 if (ifp != NULL && ifp->if_flags & IFF_BROADCAST) {
800 CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
801 if (ifa->ifa_addr->sa_family != AF_INET)
802 continue;
803 ia = ifatoia(ifa);
804 if (satosin(&ia->ia_broadaddr)->sin_addr.s_addr ==
805 t.s_addr) {
806 t = IA_SIN(ia)->sin_addr;
807 goto match;
808 }
809 }
810 }
811 /*
812 * If the packet was transiting through us, use the address of
813 * the interface the packet came through in. If that interface
814 * doesn't have a suitable IP address, the normal selection
815 * criteria apply.
816 */
817 if (V_icmp_rfi && ifp != NULL) {
818 CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
819 if (ifa->ifa_addr->sa_family != AF_INET)
820 continue;
821 ia = ifatoia(ifa);
822 t = IA_SIN(ia)->sin_addr;
823 goto match;
824 }
825 }
826 /*
827 * If the incoming packet was not addressed directly to us, use
828 * designated interface for icmp replies specified by sysctl
829 * net.inet.icmp.reply_src (default not set). Otherwise continue
830 * with normal source selection.
831 */
832 if (V_reply_src[0] != '\0' && (ifp = ifunit(V_reply_src))) {
833 CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
834 if (ifa->ifa_addr->sa_family != AF_INET)
835 continue;
836 ia = ifatoia(ifa);
837 t = IA_SIN(ia)->sin_addr;
838 goto match;
839 }
840 }
841 /*
842 * If the packet was transiting through us, use the address of
843 * the interface that is the closest to the packet source.
844 * When we don't have a route back to the packet source, stop here
845 * and drop the packet.
846 */
847 nh = fib4_lookup(M_GETFIB(m), ip->ip_dst, 0, NHR_NONE, 0);
848 if (nh == NULL) {
849 m_freem(m);
850 ICMPSTAT_INC(icps_noroute);
851 goto done;
852 }
853 t = IA_SIN(ifatoia(nh->nh_ifa))->sin_addr;
854match:
855#ifdef MAC
856 mac_netinet_icmp_replyinplace(m);
857#endif
858 ip->ip_src = t;
860
861 if (optlen > 0) {
862 u_char *cp;
863 int opt, cnt;
864 u_int len;
865
866 /*
867 * Retrieve any source routing from the incoming packet;
868 * add on any record-route or timestamp options.
869 */
870 cp = (u_char *) (ip + 1);
871 if ((opts = ip_srcroute(m)) == NULL &&
872 (opts = m_gethdr(M_NOWAIT, MT_DATA))) {
873 opts->m_len = sizeof(struct in_addr);
874 mtod(opts, struct in_addr *)->s_addr = 0;
875 }
876 if (opts) {
877#ifdef ICMPPRINTFS
878 if (icmpprintfs)
879 printf("icmp_reflect optlen %d rt %d => ",
880 optlen, opts->m_len);
881#endif
882 for (cnt = optlen; cnt > 0; cnt -= len, cp += len) {
883 opt = cp[IPOPT_OPTVAL];
884 if (opt == IPOPT_EOL)
885 break;
886 if (opt == IPOPT_NOP)
887 len = 1;
888 else {
889 if (cnt < IPOPT_OLEN + sizeof(*cp))
890 break;
891 len = cp[IPOPT_OLEN];
892 if (len < IPOPT_OLEN + sizeof(*cp) ||
893 len > cnt)
894 break;
895 }
896 /*
897 * Should check for overflow, but it "can't happen"
898 */
899 if (opt == IPOPT_RR || opt == IPOPT_TS ||
900 opt == IPOPT_SECURITY) {
901 bcopy((caddr_t)cp,
902 mtod(opts, caddr_t) + opts->m_len, len);
903 opts->m_len += len;
904 }
905 }
906 /* Terminate & pad, if necessary */
907 cnt = opts->m_len % 4;
908 if (cnt) {
909 for (; cnt < 4; cnt++) {
910 *(mtod(opts, caddr_t) + opts->m_len) =
911 IPOPT_EOL;
912 opts->m_len++;
913 }
914 }
915#ifdef ICMPPRINTFS
916 if (icmpprintfs)
917 printf("%d\n", opts->m_len);
918#endif
919 }
921 }
922 m_tag_delete_nonpersistent(m);
923 m->m_flags &= ~(M_BCAST|M_MCAST);
924 icmp_send(m, opts);
925done:
926 if (opts)
927 (void)m_free(opts);
928}
929
930/*
931 * Verifies if redirect message is valid, according to RFC 1122
932 *
933 * @src: sockaddr with address of redirect originator
934 * @dst: sockaddr with destination in question
935 * @gateway: new proposed gateway
936 *
937 * Returns 0 on success.
938 */
939static int
940icmp_verify_redirect_gateway(struct sockaddr_in *src, struct sockaddr_in *dst,
941 struct sockaddr_in *gateway, u_int fibnum)
942{
943 struct nhop_object *nh;
944 struct ifaddr *ifa;
945
946 NET_EPOCH_ASSERT();
947
948 /* Verify the gateway is directly reachable. */
949 if ((ifa = ifa_ifwithnet((struct sockaddr *)gateway, 0, fibnum))==NULL)
950 return (ENETUNREACH);
951
952 /* TODO: fib-aware. */
953 if (ifa_ifwithaddr_check((struct sockaddr *)gateway))
954 return (EHOSTUNREACH);
955
956 nh = fib4_lookup(fibnum, dst->sin_addr, 0, NHR_NONE, 0);
957 if (nh == NULL)
958 return (EINVAL);
959
960 /*
961 * If the redirect isn't from our current router for this dst,
962 * it's either old or wrong. If it redirects us to ourselves,
963 * we have a routing loop, perhaps as a result of an interface
964 * going down recently.
965 */
966 if (!sa_equal((struct sockaddr *)src, &nh->gw_sa))
967 return (EINVAL);
968 if (nh->nh_ifa != ifa && ifa->ifa_addr->sa_family != AF_LINK)
969 return (EINVAL);
970
971 /* If host route already exists, ignore redirect. */
972 if (nh->nh_flags & NHF_HOST)
973 return (EEXIST);
974
975 /* If the prefix is directly reachable, ignore redirect. */
976 if (!(nh->nh_flags & NHF_GATEWAY))
977 return (EEXIST);
978
979 return (0);
980}
981
982/*
983 * Send an icmp packet back to the ip level,
984 * after supplying a checksum.
985 */
986static void
987icmp_send(struct mbuf *m, struct mbuf *opts)
988{
989 struct ip *ip = mtod(m, struct ip *);
990 int hlen;
991 struct icmp *icp;
992
993 hlen = ip->ip_hl << 2;
994 m->m_data += hlen;
995 m->m_len -= hlen;
996 icp = mtod(m, struct icmp *);
997 icp->icmp_cksum = 0;
998 icp->icmp_cksum = in_cksum(m, ntohs(ip->ip_len) - hlen);
999 m->m_data -= hlen;
1000 m->m_len += hlen;
1001 m->m_pkthdr.rcvif = (struct ifnet *)0;
1002#ifdef ICMPPRINTFS
1003 if (icmpprintfs) {
1004 char dstbuf[INET_ADDRSTRLEN];
1005 char srcbuf[INET_ADDRSTRLEN];
1006
1007 printf("icmp_send dst %s src %s\n",
1008 inet_ntoa_r(ip->ip_dst, dstbuf),
1009 inet_ntoa_r(ip->ip_src, srcbuf));
1010 }
1011#endif
1012 (void) ip_output(m, opts, NULL, 0, NULL, NULL);
1013}
1014
1015/*
1016 * Return milliseconds since 00:00 UTC in network format.
1017 */
1019iptime(void)
1020{
1021 struct timeval atv;
1022 u_long t;
1023
1024 getmicrotime(&atv);
1025 t = (atv.tv_sec % (24*60*60)) * 1000 + atv.tv_usec / 1000;
1026 return (htonl(t));
1027}
1028
1029/*
1030 * Return the next larger or smaller MTU plateau (table from RFC 1191)
1031 * given current value MTU. If DIR is less than zero, a larger plateau
1032 * is returned; otherwise, a smaller value is returned.
1033 */
1034int
1035ip_next_mtu(int mtu, int dir)
1036{
1037 static int mtutab[] = {
1038 65535, 32000, 17914, 8166, 4352, 2002, 1492, 1280, 1006, 508,
1039 296, 68, 0
1040 };
1041 int i, size;
1042
1043 size = (sizeof mtutab) / (sizeof mtutab[0]);
1044 if (dir >= 0) {
1045 for (i = 0; i < size; i++)
1046 if (mtu > mtutab[i])
1047 return mtutab[i];
1048 } else {
1049 for (i = size - 1; i >= 0; i--)
1050 if (mtu < mtutab[i])
1051 return mtutab[i];
1052 if (mtu == mtutab[0])
1053 return mtutab[0];
1054 }
1055 return 0;
1056}
1057#endif /* INET */
1058
1059/*
1060 * badport_bandlim() - check for ICMP bandwidth limit
1061 *
1062 * Return 0 if it is ok to send an ICMP error response, -1 if we have
1063 * hit our bandwidth limit and it is not ok.
1064 *
1065 * If icmplim is <= 0, the feature is disabled and 0 is returned.
1066 *
1067 * For now we separate the TCP and UDP subsystems w/ different 'which'
1068 * values. We may eventually remove this separation (and simplify the
1069 * code further).
1070 *
1071 * Note that the printing of the error message is delayed so we can
1072 * properly print the icmp error rate that the system was trying to do
1073 * (i.e. 22000/100 pps, etc...). This can cause long delays in printing
1074 * the 'final' error, but it doesn't make sense to solve the printing
1075 * delay with more complex code.
1076 */
1078 const char *descr;
1079 struct counter_rate cr;
1080};
1082 { "icmp unreach response" },
1083 { "icmp ping response" },
1084 { "icmp tstamp response" },
1085 { "closed port RST response" },
1086 { "open port RST response" },
1087 { "icmp6 unreach response" },
1088 { "sctp ootb response" }
1089};
1090#define V_icmp_rates VNET(icmp_rates)
1091
1092static void
1094{
1095
1096 for (int i = 0; i < BANDLIM_MAX; i++) {
1097 V_icmp_rates[i].cr.cr_rate = counter_u64_alloc(M_WAITOK);
1098 V_icmp_rates[i].cr.cr_ticks = ticks;
1099 }
1100}
1101VNET_SYSINIT(icmp_bandlimit, SI_SUB_PROTO_DOMAIN, SI_ORDER_ANY,
1102 icmp_bandlimit_init, NULL);
1103
1104static void
1106{
1107
1108 for (int i = 0; i < BANDLIM_MAX; i++)
1109 counter_u64_free(V_icmp_rates[i].cr.cr_rate);
1110}
1111VNET_SYSUNINIT(icmp_bandlimit, SI_SUB_PROTO_DOMAIN, SI_ORDER_THIRD,
1112 icmp_bandlimit_uninit, NULL);
1113
1114int
1116{
1117 int64_t pps;
1118
1119 if (V_icmplim == 0 || which == BANDLIM_UNLIMITED)
1120 return (0);
1121
1122 KASSERT(which >= 0 && which < BANDLIM_MAX,
1123 ("%s: which %d", __func__, which));
1124
1125 pps = counter_ratecheck(&V_icmp_rates[which].cr, V_icmplim);
1126 if (pps == -1)
1127 return (-1);
1128 if (pps > 0 && V_icmplim_output)
1129 log(LOG_NOTICE, "Limiting %s from %jd to %d packets/sec\n",
1130 V_icmp_rates[which].descr, (intmax_t )pps, V_icmplim);
1131 return (0);
1132}
SYSCTL_UINT(_net_inet_tcp_cc_hystartplusplus, OID_AUTO, minrtt_thresh, CTLFLAG_RW, &hystart_minrtt_thresh, 4000, "HyStarts++ minimum RTT thresh used in clamp (in microseconds)")
VNET_DEFINE(struct cc_algo *, default_cc_ptr)
SYSCTL_STRING(_net_inet_tcp_cc_cdg, OID_AUTO, version, CTLFLAG_RD, CDG_VERSION, sizeof(CDG_VERSION) - 1, "Current algorithm/implementation version number")
#define BANDLIM_ICMP_ECHO
Definition: icmp_var.h:94
#define ICMPCTL_MASKREPL
Definition: icmp_var.h:84
#define ICMPCTL_STATS
Definition: icmp_var.h:85
#define BANDLIM_UNLIMITED
Definition: icmp_var.h:92
#define ICMPCTL_ICMPLIM
Definition: icmp_var.h:86
#define ICMPSTAT_INC(name)
Definition: icmp_var.h:71
#define BANDLIM_ICMP_TSTAMP
Definition: icmp_var.h:95
#define BANDLIM_MAX
Definition: icmp_var.h:100
void kmod_icmpstat_inc(int statnum)
VNET_PCPUSTAT_SYSINIT(arpstat)
SYSCTL_VNET_PCPUSTAT(_net_link_ether_arp, OID_AUTO, stats, struct arpstat, arpstat, "ARP statistics (struct arpstat, net/if_arp.h)")
VNET_PCPUSTAT_DEFINE(struct arpstat, arpstat)
VNET_PCPUSTAT_SYSUNINIT(igmpstat)
__uint32_t uint32_t
Definition: in.h:62
char * inet_ntoa_r(struct in_addr ina, char *buf)
#define INADDR_BROADCAST
Definition: in.h:49
#define INADDR_ANY
Definition: in.h:48
#define IPPROTO_TCP
Definition: in.h:45
#define IPPROTO_ICMP
Definition: in.h:44
#define ifatoia(ifa)
Definition: in.h:680
#define satosin(sa)
Definition: in.h:678
struct nhop_object * fib4_lookup(uint32_t fibnum, struct in_addr dst, uint32_t scopeid, uint32_t flags, uint32_t flowid)
uint32_t iptime(void)
#define IA_SIN(ia)
Definition: in_var.h:96
#define INADDR_HASH(x)
Definition: in_var.h:124
#define IPOPT_OLEN
Definition: ip.h:166
#define IPOPT_NOP
Definition: ip.h:150
#define IPOPT_SECURITY
Definition: ip.h:154
#define IPOPT_RR
Definition: ip.h:152
#define IPOPT_OPTVAL
Definition: ip.h:165
#define IPVERSION
Definition: ip.h:46
#define IPOPT_EOL
Definition: ip.h:149
#define IP_DF
Definition: ip.h:13
#define IP_MF
Definition: ip.h:14
#define IPOPT_TS
Definition: ip.h:153
int badport_bandlim(int which)
Definition: ip_icmp.c:1115
VNET_SYSUNINIT(icmp_bandlimit, SI_SUB_PROTO_DOMAIN, SI_ORDER_THIRD, icmp_bandlimit_uninit, NULL)
#define V_icmplim
Definition: ip_icmp.c:86
#define V_icmplim_output
Definition: ip_icmp.c:92
static void icmp_bandlimit_init(void)
Definition: ip_icmp.c:1093
SYSCTL_INT(_net_inet_icmp, ICMPCTL_ICMPLIM, icmplim, CTLFLAG_VNET|CTLFLAG_RW, &VNET_NAME(icmplim), 0, "Maximum number of ICMP responses per second")
__FBSDID("$FreeBSD$")
#define V_icmp_rates
Definition: ip_icmp.c:1090
static void icmp_bandlimit_uninit(void)
Definition: ip_icmp.c:1105
VNET_DEFINE_STATIC(int, icmplim)
VNET_SYSINIT(icmp_bandlimit, SI_SUB_PROTO_DOMAIN, SI_ORDER_ANY, icmp_bandlimit_init, NULL)
#define ICMP_UNREACH_NET_PROHIB
Definition: ip_icmp.h:164
#define ICMP_ADVLEN(p)
Definition: ip_icmp.h:139
#define ICMP_UNREACH_HOST
Definition: ip_icmp.h:156
#define ICMP_UNREACH_NET_UNKNOWN
Definition: ip_icmp.h:161
#define ICMP_UNREACH_NEEDFRAG
Definition: ip_icmp.h:159
#define ICMP_ROUTERADVERT
Definition: ip_icmp.h:179
#define ICMP_ROUTERSOLICIT
Definition: ip_icmp.h:182
int ip_next_mtu(int, int)
#define ICMP_UNREACH_ISOLATED
Definition: ip_icmp.h:163
#define ICMP_MAXTYPE
Definition: ip_icmp.h:209
#define ICMP_REDIRECT
Definition: ip_icmp.h:172
#define ICMP_MINLEN
Definition: ip_icmp.h:135
#define ICMP_UNREACH_TOSHOST
Definition: ip_icmp.h:167
#define ICMP_UNREACH_HOST_PRECEDENCE
Definition: ip_icmp.h:169
int icmp_input(struct mbuf **, int *, int)
#define ICMP_TSTAMP
Definition: ip_icmp.h:190
#define ICMP_UNREACH_PROTOCOL
Definition: ip_icmp.h:157
#define ICMP_MASKLEN
Definition: ip_icmp.h:137
#define ICMP_UNREACH_SRCFAIL
Definition: ip_icmp.h:160
#define ICMP_ADVLENPREF(p)
Definition: ip_icmp.h:148
#define ICMP_ECHOREPLY
Definition: ip_icmp.h:153
#define ICMP_SOURCEQUENCH
Definition: ip_icmp.h:171
#define ICMP_TIMXCEED
Definition: ip_icmp.h:183
#define ICMP_UNREACH_PRECEDENCE_CUTOFF
Definition: ip_icmp.h:170
void icmp_error(struct mbuf *, int, int, uint32_t, int)
#define ICMP_INFOTYPE(type)
Definition: ip_icmp.h:211
#define ICMP_PARAMPROB
Definition: ip_icmp.h:186
#define ICMP_ADVLENMIN
Definition: ip_icmp.h:138
#define ICMP_IREQREPLY
Definition: ip_icmp.h:193
#define ICMP_TSLEN
Definition: ip_icmp.h:136
#define ICMP_UNREACH_TOSNET
Definition: ip_icmp.h:166
#define ICMP_UNREACH_HOST_UNKNOWN
Definition: ip_icmp.h:162
#define ICMP_UNREACH_FILTER_PROHIB
Definition: ip_icmp.h:168
#define ICMP_MASKREQ
Definition: ip_icmp.h:194
#define ICMP_UNREACH
Definition: ip_icmp.h:154
#define ICMP_ECHO
Definition: ip_icmp.h:178
#define ICMP_UNREACH_NET
Definition: ip_icmp.h:155
#define ICMP_UNREACH_HOST_PROHIB
Definition: ip_icmp.h:165
#define ICMP_MASKREPLY
Definition: ip_icmp.h:195
#define ICMP_UNREACH_PORT
Definition: ip_icmp.h:158
#define ICMP_TSTAMPREPLY
Definition: ip_icmp.h:191
struct protosw inetsw[]
u_char ip_protox[IPPROTO_MAX]
Definition: ip_input.c:167
void ip_stripoptions(struct mbuf *m)
Definition: ip_options.c:483
struct mbuf * ip_srcroute(struct mbuf *m0)
Definition: ip_options.c:426
int ip_output(struct mbuf *m, struct mbuf *opt, struct route *ro, int flags, struct ip_moptions *imo, struct inpcb *inp)
Definition: ip_output.c:320
#define V_ipforwarding
Definition: ip_var.h:203
#define V_drop_redirect
Definition: ip_var.h:211
#define V_ip_defttl
Definition: ip_var.h:202
int rip_input(struct mbuf **, int *, int)
#define SCTP_INITIATION
Definition: sctp.h:432
#define IPPROTO_SCTP
struct counter_rate cr
Definition: ip_icmp.c:1079
const char * descr
Definition: ip_icmp.c:1078
Definition: ip_icmp.h:65
u_char icmp_code
Definition: ip_icmp.h:67
u_char icmp_type
Definition: ip_icmp.h:66
u_short icmp_cksum
Definition: ip_icmp.h:68
Definition: in.h:83
in_addr_t s_addr
Definition: in.h:84
struct sockaddr_in ia_sockmask
Definition: in_var.h:87
struct sockaddr_in ia_dstaddr
Definition: in_var.h:85
Definition: ip.h:51
u_char ip_p
Definition: ip.h:69
struct in_addr ip_src ip_dst
Definition: ip.h:71
u_char ip_hl
Definition: ip.h:53
u_short ip_len
Definition: ip.h:61
u_char ip_ttl
Definition: ip.h:68
u_short ip_off
Definition: ip.h:63
uint8_t chunk_type
Definition: sctp.h:60
Definition: sctp.h:48
uint32_t v_tag
Definition: sctp.h:51
Definition: in.h:97
struct in_addr sin_addr
Definition: in.h:101
u_long raw[1]
Definition: tcp_lro.h:0