1 1.15 maxv /* $NetBSD: mpls_ttl.c,v 1.15 2018/12/27 14:03:55 maxv Exp $ */ 2 1.1 kefren 3 1.9 maxv /* 4 1.1 kefren * Copyright (c) 2010 The NetBSD Foundation, Inc. 5 1.1 kefren * All rights reserved. 6 1.1 kefren * 7 1.1 kefren * This code is derived from software contributed to The NetBSD Foundation 8 1.1 kefren * by Public Access Networks Corporation ("Panix"). It was developed under 9 1.1 kefren * contract to Panix by Eric Haszlakiewicz and Thor Lancelot Simon. 10 1.1 kefren * 11 1.1 kefren * This code is derived from software contributed to The NetBSD Foundation 12 1.1 kefren * by Jason R. Thorpe of Zembu Labs, Inc. 13 1.1 kefren * 14 1.1 kefren * This code is derived from software contributed to The NetBSD Foundation 15 1.1 kefren * by Mihai Chelaru <kefren (at) NetBSD.org> 16 1.1 kefren * 17 1.1 kefren * Redistribution and use in source and binary forms, with or without 18 1.1 kefren * modification, are permitted provided that the following conditions 19 1.1 kefren * are met: 20 1.1 kefren * 1. Redistributions of source code must retain the above copyright 21 1.1 kefren * notice, this list of conditions and the following disclaimer. 22 1.1 kefren * 2. Redistributions in binary form must reproduce the above copyright 23 1.1 kefren * notice, this list of conditions and the following disclaimer in the 24 1.1 kefren * documentation and/or other materials provided with the distribution. 25 1.1 kefren * 26 1.1 kefren * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 27 1.1 kefren * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 28 1.1 kefren * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 29 1.1 kefren * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 30 1.1 kefren * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 31 1.1 kefren * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 32 1.1 kefren * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 33 1.1 kefren * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 34 1.1 kefren * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 35 1.1 kefren * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 36 1.1 kefren * POSSIBILITY OF SUCH DAMAGE. 37 1.1 kefren */ 38 1.1 kefren 39 1.1 kefren /* 40 1.10 maxv * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 41 1.10 maxv * All rights reserved. 42 1.10 maxv * 43 1.10 maxv * Redistribution and use in source and binary forms, with or without 44 1.10 maxv * modification, are permitted provided that the following conditions 45 1.10 maxv * are met: 46 1.10 maxv * 1. Redistributions of source code must retain the above copyright 47 1.10 maxv * notice, this list of conditions and the following disclaimer. 48 1.10 maxv * 2. Redistributions in binary form must reproduce the above copyright 49 1.10 maxv * notice, this list of conditions and the following disclaimer in the 50 1.10 maxv * documentation and/or other materials provided with the distribution. 51 1.10 maxv * 3. Neither the name of the project nor the names of its contributors 52 1.10 maxv * may be used to endorse or promote products derived from this software 53 1.10 maxv * without specific prior written permission. 54 1.10 maxv * 55 1.10 maxv * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 56 1.10 maxv * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 57 1.10 maxv * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 58 1.10 maxv * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 59 1.10 maxv * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 60 1.10 maxv * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 61 1.10 maxv * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 62 1.10 maxv * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 63 1.10 maxv * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 64 1.10 maxv * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 65 1.10 maxv * SUCH DAMAGE. 66 1.10 maxv */ 67 1.10 maxv 68 1.10 maxv /* 69 1.1 kefren * Copyright (c) 1982, 1986, 1988, 1993 70 1.1 kefren * The Regents of the University of California. All rights reserved. 71 1.1 kefren * 72 1.1 kefren * Redistribution and use in source and binary forms, with or without 73 1.1 kefren * modification, are permitted provided that the following conditions 74 1.1 kefren * are met: 75 1.1 kefren * 1. Redistributions of source code must retain the above copyright 76 1.1 kefren * notice, this list of conditions and the following disclaimer. 77 1.1 kefren * 2. Redistributions in binary form must reproduce the above copyright 78 1.1 kefren * notice, this list of conditions and the following disclaimer in the 79 1.1 kefren * documentation and/or other materials provided with the distribution. 80 1.1 kefren * 3. Neither the name of the University nor the names of its contributors 81 1.1 kefren * may be used to endorse or promote products derived from this software 82 1.1 kefren * without specific prior written permission. 83 1.1 kefren * 84 1.1 kefren * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 85 1.1 kefren * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 86 1.1 kefren * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 87 1.1 kefren * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 88 1.1 kefren * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 89 1.1 kefren * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 90 1.1 kefren * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 91 1.1 kefren * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 92 1.1 kefren * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 93 1.1 kefren * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 94 1.1 kefren * SUCH DAMAGE. 95 1.1 kefren * 96 1.1 kefren * @(#)ip_icmp.c 8.2 (Berkeley) 1/4/94 97 1.1 kefren */ 98 1.1 kefren 99 1.1 kefren #include <sys/cdefs.h> 100 1.15 maxv __KERNEL_RCSID(0, "$NetBSD: mpls_ttl.c,v 1.15 2018/12/27 14:03:55 maxv Exp $"); 101 1.1 kefren 102 1.5 pooka #ifdef _KERNEL_OPT 103 1.1 kefren #include "opt_inet.h" 104 1.1 kefren #include "opt_mpls.h" 105 1.5 pooka #endif 106 1.1 kefren 107 1.1 kefren #include <sys/param.h> 108 1.1 kefren #include <sys/malloc.h> 109 1.1 kefren #include <sys/mbuf.h> 110 1.1 kefren #include <sys/errno.h> 111 1.1 kefren #include <sys/socket.h> 112 1.1 kefren #include <sys/systm.h> 113 1.1 kefren 114 1.1 kefren #include <net/if.h> 115 1.1 kefren #include <net/if_dl.h> 116 1.1 kefren 117 1.1 kefren #include <netinet/in.h> 118 1.1 kefren #include <netinet/in_systm.h> 119 1.1 kefren #include <netinet/ip.h> 120 1.1 kefren #include <netinet/ip_icmp.h> 121 1.1 kefren #include <netinet/icmp_private.h> 122 1.1 kefren #include <netinet/icmp_var.h> 123 1.1 kefren 124 1.1 kefren #include <netmpls/mpls.h> 125 1.1 kefren #include <netmpls/mpls_var.h> 126 1.1 kefren 127 1.1 kefren #ifdef INET 128 1.1 kefren 129 1.1 kefren /* in netinet/ip_icmp.c */ 130 1.1 kefren extern int icmpreturndatabytes; 131 1.1 kefren 132 1.1 kefren /* ICMP Extensions */ 133 1.1 kefren #define MPLS_STACK_ENTRY_CLASS 1 134 1.1 kefren #define MPLS_STACK_ENTRY_C_TYPE 1 135 1.1 kefren 136 1.1 kefren struct mpls_extension { 137 1.10 maxv struct icmp_ext_hdr cmn_hdr; 138 1.1 kefren struct icmp_ext_obj_hdr obj_hdr; 139 1.1 kefren union mpls_shim ms; 140 1.1 kefren } __packed; 141 1.1 kefren 142 1.3 kefren static void mpls_icmp_error(struct mbuf *, int, int, n_long, int, 143 1.9 maxv union mpls_shim *); 144 1.9 maxv static struct mbuf *ip4_check(struct mbuf *); 145 1.1 kefren 146 1.1 kefren /* 147 1.10 maxv * Send an ICMP Extended error message. References: RFC4884 and RFC4950. 148 1.10 maxv * 149 1.12 maxv * XXX: This code is inspired from icmp_error(), and should really be merged 150 1.12 maxv * into it. icmp_error() should handle ICMP Extended error messages. 151 1.11 maxv * 152 1.12 maxv * XXX: It is called only for ICMP_TIMXCEED_INTRANS but code is too general. 153 1.12 maxv * 154 1.12 maxv * XXX: We're not setting the 'length' field of the Extended ICMP header. 155 1.11 maxv * According to RFC4884, we are in 'non-compliant' mode. Moreover, we're 156 1.11 maxv * not computing the checksum of the Extended ICMP header. 157 1.1 kefren */ 158 1.1 kefren static void 159 1.1 kefren mpls_icmp_error(struct mbuf *n, int type, int code, n_long dest, 160 1.1 kefren int destmtu, union mpls_shim *shim) 161 1.1 kefren { 162 1.2 kefren struct ip *oip = mtod(n, struct ip *), *nip; 163 1.2 kefren unsigned oiplen = oip->ip_hl << 2; 164 1.2 kefren struct icmp *icp; 165 1.2 kefren struct mbuf *m; 166 1.2 kefren unsigned icmplen, mblen, packetlen; 167 1.1 kefren struct mpls_extension mpls_icmp_ext; 168 1.9 maxv 169 1.1 kefren memset(&mpls_icmp_ext, 0, sizeof(mpls_icmp_ext)); 170 1.1 kefren mpls_icmp_ext.cmn_hdr.version = ICMP_EXT_VERSION; 171 1.11 maxv mpls_icmp_ext.cmn_hdr.checksum = 0; /* XXX */ 172 1.1 kefren 173 1.9 maxv mpls_icmp_ext.obj_hdr.length = htons(sizeof(union mpls_shim) + 174 1.9 maxv sizeof(struct icmp_ext_obj_hdr)); 175 1.1 kefren mpls_icmp_ext.obj_hdr.class_num = MPLS_STACK_ENTRY_CLASS; 176 1.1 kefren mpls_icmp_ext.obj_hdr.c_type = MPLS_STACK_ENTRY_C_TYPE; 177 1.1 kefren 178 1.1 kefren mpls_icmp_ext.ms.s_addr = shim->s_addr; 179 1.1 kefren 180 1.1 kefren if (type != ICMP_REDIRECT) 181 1.1 kefren ICMP_STATINC(ICMP_STAT_ERROR); 182 1.10 maxv 183 1.1 kefren /* 184 1.1 kefren * Don't send error if the original packet was encrypted. 185 1.1 kefren * Don't send error if not the first fragment of message. 186 1.1 kefren * Don't error if the old packet protocol was ICMP 187 1.1 kefren * error message, only known informational types. 188 1.1 kefren */ 189 1.1 kefren if (n->m_flags & M_DECRYPTED) 190 1.1 kefren goto freeit; 191 1.1 kefren if (oip->ip_off &~ htons(IP_MF|IP_DF)) 192 1.1 kefren goto freeit; 193 1.1 kefren if (oip->ip_p == IPPROTO_ICMP && type != ICMP_REDIRECT && 194 1.1 kefren n->m_len >= oiplen + ICMP_MINLEN && 195 1.1 kefren !ICMP_INFOTYPE(((struct icmp *)((char *)oip + oiplen))->icmp_type)) 196 1.1 kefren { 197 1.1 kefren ICMP_STATINC(ICMP_STAT_OLDICMP); 198 1.1 kefren goto freeit; 199 1.1 kefren } 200 1.10 maxv 201 1.1 kefren /* Don't send error in response to a multicast or broadcast packet */ 202 1.1 kefren if (n->m_flags & (M_BCAST|M_MCAST)) 203 1.1 kefren goto freeit; 204 1.1 kefren 205 1.1 kefren /* 206 1.1 kefren * First, do a rate limitation check. 207 1.1 kefren */ 208 1.1 kefren if (icmp_ratelimit(&oip->ip_src, type, code)) 209 1.1 kefren /* XXX stats */ 210 1.1 kefren goto freeit; 211 1.1 kefren 212 1.1 kefren /* 213 1.1 kefren * Now, formulate icmp message 214 1.1 kefren */ 215 1.14 riastrad icmplen = uimin(ICMP_EXT_OFFSET, ntohs(oip->ip_len)); 216 1.10 maxv 217 1.1 kefren /* 218 1.1 kefren * Defend against mbuf chains shorter than oip->ip_len - oiplen: 219 1.1 kefren */ 220 1.1 kefren mblen = 0; 221 1.1 kefren for (m = n; m && (mblen < icmplen); m = m->m_next) 222 1.1 kefren mblen += m->m_len; 223 1.14 riastrad icmplen = uimin(mblen, icmplen); 224 1.1 kefren 225 1.4 kefren packetlen = sizeof(struct ip) + offsetof(struct icmp, icmp_ip) + 226 1.4 kefren ICMP_EXT_OFFSET + sizeof(mpls_icmp_ext); 227 1.2 kefren 228 1.1 kefren /* 229 1.1 kefren * As we are not required to return everything we have, 230 1.1 kefren * we return whatever we can return at ease. 231 1.1 kefren * 232 1.1 kefren * Note that ICMP datagrams longer than 576 octets are out of spec 233 1.1 kefren * according to RFC1812; the limit on icmpreturndatabytes below in 234 1.1 kefren * icmp_sysctl will keep things below that limit. 235 1.1 kefren */ 236 1.1 kefren 237 1.10 maxv KASSERT(packetlen <= MCLBYTES); 238 1.1 kefren 239 1.1 kefren m = m_gethdr(M_DONTWAIT, MT_HEADER); 240 1.2 kefren if (m && (packetlen > MHLEN)) { 241 1.1 kefren MCLGET(m, M_DONTWAIT); 242 1.1 kefren if ((m->m_flags & M_EXT) == 0) { 243 1.1 kefren m_freem(m); 244 1.1 kefren m = NULL; 245 1.1 kefren } 246 1.1 kefren } 247 1.1 kefren if (m == NULL) 248 1.1 kefren goto freeit; 249 1.10 maxv 250 1.1 kefren MCLAIM(m, n->m_owner); 251 1.2 kefren m->m_len = packetlen; 252 1.1 kefren if ((m->m_flags & M_EXT) == 0) 253 1.15 maxv m_align(m, m->m_len); 254 1.4 kefren m->m_data += sizeof(struct ip); 255 1.4 kefren m->m_len -= sizeof(struct ip); 256 1.4 kefren 257 1.1 kefren icp = mtod(m, struct icmp *); 258 1.1 kefren if ((u_int)type > ICMP_MAXTYPE) 259 1.4 kefren panic("icmp error (mpls_ttl)"); 260 1.1 kefren ICMP_STATINC(ICMP_STAT_OUTHIST + type); 261 1.1 kefren icp->icmp_type = type; 262 1.1 kefren if (type == ICMP_REDIRECT) 263 1.1 kefren icp->icmp_gwaddr.s_addr = dest; 264 1.1 kefren else { 265 1.1 kefren icp->icmp_void = 0; 266 1.1 kefren /* 267 1.1 kefren * The following assignments assume an overlay with the 268 1.1 kefren * zeroed icmp_void field. 269 1.1 kefren */ 270 1.1 kefren if (type == ICMP_PARAMPROB) { 271 1.1 kefren icp->icmp_pptr = code; 272 1.1 kefren code = 0; 273 1.1 kefren } else if (type == ICMP_UNREACH && 274 1.1 kefren code == ICMP_UNREACH_NEEDFRAG && destmtu) 275 1.1 kefren icp->icmp_nextmtu = htons(destmtu); 276 1.1 kefren } 277 1.1 kefren 278 1.1 kefren icp->icmp_code = code; 279 1.2 kefren 280 1.2 kefren memset(&icp->icmp_ip, 0, ICMP_EXT_OFFSET); 281 1.1 kefren m_copydata(n, 0, icmplen, (char *)&icp->icmp_ip); 282 1.1 kefren 283 1.2 kefren /* Append the extension structure */ 284 1.2 kefren memcpy(((char*)&icp->icmp_ip) + ICMP_EXT_OFFSET, 285 1.1 kefren &mpls_icmp_ext, sizeof(mpls_icmp_ext)); 286 1.1 kefren 287 1.1 kefren /* 288 1.1 kefren * Now, copy old ip header (without options) 289 1.1 kefren * in front of icmp message. 290 1.9 maxv */ 291 1.2 kefren if ((m->m_flags & M_EXT) == 0 && 292 1.2 kefren m->m_data - sizeof(struct ip) < m->m_pktdat) 293 1.2 kefren panic("icmp len"); 294 1.1 kefren m->m_data -= sizeof(struct ip); 295 1.1 kefren m->m_len += sizeof(struct ip); 296 1.1 kefren m->m_pkthdr.len = m->m_len; 297 1.8 ozaki m_copy_rcvif(m, n); 298 1.1 kefren nip = mtod(m, struct ip *); 299 1.1 kefren /* ip_v set in ip_output */ 300 1.1 kefren nip->ip_hl = sizeof(struct ip) >> 2; 301 1.1 kefren nip->ip_tos = 0; 302 1.1 kefren nip->ip_len = htons(m->m_len); 303 1.1 kefren /* ip_id set in ip_output */ 304 1.1 kefren nip->ip_off = htons(0); 305 1.1 kefren /* ip_ttl set in icmp_reflect */ 306 1.1 kefren nip->ip_p = IPPROTO_ICMP; 307 1.1 kefren nip->ip_src = oip->ip_src; 308 1.1 kefren nip->ip_dst = oip->ip_dst; 309 1.1 kefren icmp_reflect(m); 310 1.1 kefren 311 1.1 kefren freeit: 312 1.1 kefren m_freem(n); 313 1.1 kefren } 314 1.1 kefren 315 1.9 maxv static struct mbuf * 316 1.3 kefren ip4_check(struct mbuf *m) 317 1.3 kefren { 318 1.3 kefren struct ip *iph; 319 1.3 kefren int hlen, len; 320 1.3 kefren 321 1.3 kefren if (m->m_len < sizeof(struct ip) && 322 1.3 kefren (m = m_pullup(m, sizeof(struct ip))) == NULL) 323 1.9 maxv return NULL; 324 1.3 kefren 325 1.3 kefren iph = mtod(m, struct ip *); 326 1.3 kefren 327 1.3 kefren if (iph->ip_v != IPVERSION) 328 1.3 kefren goto freeit; 329 1.3 kefren hlen = iph->ip_hl << 2; 330 1.3 kefren if (hlen < sizeof(struct ip)) 331 1.3 kefren goto freeit; 332 1.3 kefren if (hlen > m->m_len) { 333 1.3 kefren if ((m = m_pullup(m, hlen)) == NULL) 334 1.9 maxv return NULL; 335 1.3 kefren iph = mtod(m, struct ip *); 336 1.3 kefren } 337 1.10 maxv 338 1.10 maxv /* 339 1.10 maxv * RFC1122: packets with a multicast source address are 340 1.10 maxv * not allowed. 341 1.10 maxv * RFC1122: 127/8 must not appear on wire. 342 1.10 maxv */ 343 1.3 kefren if (IN_MULTICAST(iph->ip_src.s_addr) || 344 1.3 kefren (ntohl(iph->ip_dst.s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET || 345 1.3 kefren (ntohl(iph->ip_src.s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET || 346 1.3 kefren in_cksum(m, hlen) != 0) 347 1.3 kefren goto freeit; 348 1.3 kefren 349 1.3 kefren len = ntohs(iph->ip_len); 350 1.3 kefren if (len < hlen || m->m_pkthdr.len < len) 351 1.3 kefren goto freeit; 352 1.3 kefren 353 1.9 maxv return m; 354 1.9 maxv 355 1.3 kefren freeit: 356 1.3 kefren m_freem(m); 357 1.9 maxv return NULL; 358 1.3 kefren } 359 1.1 kefren #endif /* INET */ 360 1.1 kefren 361 1.1 kefren struct mbuf * 362 1.1 kefren mpls_ttl_dec(struct mbuf *m) 363 1.1 kefren { 364 1.1 kefren union mpls_shim *mshim; 365 1.1 kefren #ifdef INET 366 1.10 maxv union mpls_shim top_shim, bos_shim; 367 1.1 kefren #endif 368 1.1 kefren 369 1.4 kefren if (__predict_false(m->m_len < sizeof(union mpls_shim) && 370 1.4 kefren (m = m_pullup(m, sizeof(union mpls_shim))) == NULL)) 371 1.1 kefren return NULL; 372 1.1 kefren mshim = mtod(m, union mpls_shim *); 373 1.1 kefren mshim->s_addr = ntohl(mshim->s_addr); 374 1.1 kefren mshim->shim.ttl--; 375 1.1 kefren 376 1.1 kefren if (mshim->shim.ttl == 0) { 377 1.1 kefren if (!mpls_icmp_respond) { 378 1.1 kefren m_freem(m); 379 1.1 kefren return NULL; 380 1.1 kefren } 381 1.1 kefren 382 1.1 kefren #ifdef INET 383 1.1 kefren /* 384 1.9 maxv * Shim ttl exceeded. Send back ICMP type 11 code 0. 385 1.1 kefren */ 386 1.10 maxv bos_shim.s_addr = mshim->s_addr; 387 1.2 kefren top_shim.s_addr = htonl(mshim->s_addr); 388 1.1 kefren m_adj(m, sizeof(union mpls_shim)); 389 1.1 kefren 390 1.1 kefren /* Goto BOS */ 391 1.10 maxv while (bos_shim.shim.bos == 0) { 392 1.1 kefren if (m->m_len < sizeof(union mpls_shim) && 393 1.1 kefren (m = m_pullup(m, sizeof(union mpls_shim))) == NULL) { 394 1.1 kefren m_freem(m); 395 1.1 kefren return NULL; 396 1.1 kefren } 397 1.10 maxv bos_shim.s_addr = ntohl(mtod(m, union mpls_shim *)->s_addr); 398 1.1 kefren m_adj(m, sizeof(union mpls_shim)); 399 1.1 kefren } 400 1.9 maxv 401 1.9 maxv if ((m = ip4_check(m)) != NULL) 402 1.3 kefren mpls_icmp_error(m, ICMP_TIMXCEED, ICMP_TIMXCEED_INTRANS, 403 1.3 kefren 0, 0, &top_shim); 404 1.2 kefren #else 405 1.2 kefren m_freem(m); 406 1.1 kefren #endif 407 1.1 kefren return NULL; 408 1.1 kefren } 409 1.1 kefren 410 1.1 kefren mshim->s_addr = htonl(mshim->s_addr); 411 1.1 kefren 412 1.1 kefren return m; 413 1.1 kefren } 414