| version 1.130.2.9, 2002/05/04 19:51:50 |
version 1.130.2.10, 2002/06/20 03:48:44 |
|
|
| /* |
/* |
| * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. |
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. |
| * All rights reserved. |
* All rights reserved. |
| * |
* |
| * Redistribution and use in source and binary forms, with or without |
* Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions |
* modification, are permitted provided that the following conditions |
| * are met: |
* are met: |
|
|
| * 3. Neither the name of the project nor the names of its contributors |
* 3. Neither the name of the project nor the names of its contributors |
| * may be used to endorse or promote products derived from this software |
* may be used to endorse or promote products derived from this software |
| * without specific prior written permission. |
* without specific prior written permission. |
| * |
* |
| * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND |
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND |
| * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
| Line 168 __KERNEL_RCSID(0, "$NetBSD$"); |
|
| Line 168 __KERNEL_RCSID(0, "$NetBSD$"); |
|
| #define IPALLOWSRCRT 1 /* allow source-routed packets */ |
#define IPALLOWSRCRT 1 /* allow source-routed packets */ |
| #endif |
#endif |
| #ifndef IPMTUDISC |
#ifndef IPMTUDISC |
| #define IPMTUDISC 0 |
#define IPMTUDISC 1 |
| #endif |
#endif |
| #ifndef IPMTUDISCTIMEOUT |
#ifndef IPMTUDISCTIMEOUT |
| #define IPMTUDISCTIMEOUT (10 * 60) /* as per RFC 1191 */ |
#define IPMTUDISCTIMEOUT (10 * 60) /* as per RFC 1191 */ |
| Line 201 struct rttimer_queue *ip_mtudisc_timeout |
|
| Line 201 struct rttimer_queue *ip_mtudisc_timeout |
|
| |
|
| extern struct domain inetdomain; |
extern struct domain inetdomain; |
| int ipqmaxlen = IFQ_MAXLEN; |
int ipqmaxlen = IFQ_MAXLEN; |
| |
u_long in_ifaddrhash; /* size of hash table - 1 */ |
| |
int in_ifaddrentries; /* total number of addrs */ |
| struct in_ifaddrhead in_ifaddr; |
struct in_ifaddrhead in_ifaddr; |
| struct in_ifaddrhashhead *in_ifaddrhashtbl; |
struct in_ifaddrhashhead *in_ifaddrhashtbl; |
| struct ifqueue ipintrq; |
struct ifqueue ipintrq; |
|
|
| int s; |
int s; |
| |
|
| /* |
/* |
| * Use splvm() -- we're bloking things that would cause |
* Use splvm() -- we're blocking things that would cause |
| * mbuf allocation. |
* mbuf allocation. |
| */ |
*/ |
| s = splvm(); |
s = splvm(); |
|
|
| in_ifaddrhashtbl = hashinit(IN_IFADDR_HASH_SIZE, HASH_LIST, M_IFADDR, |
in_ifaddrhashtbl = hashinit(IN_IFADDR_HASH_SIZE, HASH_LIST, M_IFADDR, |
| M_WAITOK, &in_ifaddrhash); |
M_WAITOK, &in_ifaddrhash); |
| if (ip_mtudisc != 0) |
if (ip_mtudisc != 0) |
| ip_mtudisc_timeout_q = |
ip_mtudisc_timeout_q = |
| rt_timer_queue_create(ip_mtudisc_timeout); |
rt_timer_queue_create(ip_mtudisc_timeout); |
| #ifdef GATEWAY |
#ifdef GATEWAY |
| ipflow_init(); |
ipflow_init(); |
| Line 509 ip_input(struct mbuf *m) |
|
| Line 511 ip_input(struct mbuf *m) |
|
| } |
} |
| |
|
| #ifdef IPSEC |
#ifdef IPSEC |
| /* ipflow (IP fast fowarding) is not compatible with IPsec. */ |
/* ipflow (IP fast forwarding) is not compatible with IPsec. */ |
| m->m_flags &= ~M_CANFASTFWD; |
m->m_flags &= ~M_CANFASTFWD; |
| #else |
#else |
| /* |
/* |
| Line 858 ip_reass(ipqe, fp) |
|
| Line 860 ip_reass(ipqe, fp) |
|
| fp->ipq_ttl = IPFRAGTTL; |
fp->ipq_ttl = IPFRAGTTL; |
| fp->ipq_p = ipqe->ipqe_ip->ip_p; |
fp->ipq_p = ipqe->ipqe_ip->ip_p; |
| fp->ipq_id = ipqe->ipqe_ip->ip_id; |
fp->ipq_id = ipqe->ipqe_ip->ip_id; |
| LIST_INIT(&fp->ipq_fragq); |
TAILQ_INIT(&fp->ipq_fragq); |
| fp->ipq_src = ipqe->ipqe_ip->ip_src; |
fp->ipq_src = ipqe->ipqe_ip->ip_src; |
| fp->ipq_dst = ipqe->ipqe_ip->ip_dst; |
fp->ipq_dst = ipqe->ipqe_ip->ip_dst; |
| p = NULL; |
p = NULL; |
| Line 868 ip_reass(ipqe, fp) |
|
| Line 870 ip_reass(ipqe, fp) |
|
| /* |
/* |
| * Find a segment which begins after this one does. |
* Find a segment which begins after this one does. |
| */ |
*/ |
| for (p = NULL, q = LIST_FIRST(&fp->ipq_fragq); q != NULL; |
for (p = NULL, q = TAILQ_FIRST(&fp->ipq_fragq); q != NULL; |
| p = q, q = LIST_NEXT(q, ipqe_q)) |
p = q, q = TAILQ_NEXT(q, ipqe_q)) |
| if (q->ipqe_ip->ip_off > ipqe->ipqe_ip->ip_off) |
if (q->ipqe_ip->ip_off > ipqe->ipqe_ip->ip_off) |
| break; |
break; |
| |
|
| Line 904 ip_reass(ipqe, fp) |
|
| Line 906 ip_reass(ipqe, fp) |
|
| m_adj(q->ipqe_m, i); |
m_adj(q->ipqe_m, i); |
| break; |
break; |
| } |
} |
| nq = LIST_NEXT(q, ipqe_q); |
nq = TAILQ_NEXT(q, ipqe_q); |
| m_freem(q->ipqe_m); |
m_freem(q->ipqe_m); |
| LIST_REMOVE(q, ipqe_q); |
TAILQ_REMOVE(&fp->ipq_fragq, q, ipqe_q); |
| pool_put(&ipqent_pool, q); |
pool_put(&ipqent_pool, q); |
| } |
} |
| |
|
|
|
| * check for complete reassembly. |
* check for complete reassembly. |
| */ |
*/ |
| if (p == NULL) { |
if (p == NULL) { |
| LIST_INSERT_HEAD(&fp->ipq_fragq, ipqe, ipqe_q); |
TAILQ_INSERT_HEAD(&fp->ipq_fragq, ipqe, ipqe_q); |
| } else { |
} else { |
| LIST_INSERT_AFTER(p, ipqe, ipqe_q); |
TAILQ_INSERT_AFTER(&fp->ipq_fragq, p, ipqe, ipqe_q); |
| } |
} |
| next = 0; |
next = 0; |
| for (p = NULL, q = LIST_FIRST(&fp->ipq_fragq); q != NULL; |
for (p = NULL, q = TAILQ_FIRST(&fp->ipq_fragq); q != NULL; |
| p = q, q = LIST_NEXT(q, ipqe_q)) { |
p = q, q = TAILQ_NEXT(q, ipqe_q)) { |
| if (q->ipqe_ip->ip_off != next) |
if (q->ipqe_ip->ip_off != next) |
| return (0); |
return (0); |
| next += q->ipqe_ip->ip_len; |
next += q->ipqe_ip->ip_len; |
|
|
| * Reassembly is complete. Check for a bogus message size and |
* Reassembly is complete. Check for a bogus message size and |
| * concatenate fragments. |
* concatenate fragments. |
| */ |
*/ |
| q = LIST_FIRST(&fp->ipq_fragq); |
q = TAILQ_FIRST(&fp->ipq_fragq); |
| ip = q->ipqe_ip; |
ip = q->ipqe_ip; |
| if ((next + (ip->ip_hl << 2)) > IP_MAXPACKET) { |
if ((next + (ip->ip_hl << 2)) > IP_MAXPACKET) { |
| ipstat.ips_toolong++; |
ipstat.ips_toolong++; |
|
|
| t = m->m_next; |
t = m->m_next; |
| m->m_next = 0; |
m->m_next = 0; |
| m_cat(m, t); |
m_cat(m, t); |
| nq = LIST_NEXT(q, ipqe_q); |
nq = TAILQ_NEXT(q, ipqe_q); |
| pool_put(&ipqent_pool, q); |
pool_put(&ipqent_pool, q); |
| for (q = nq; q != NULL; q = nq) { |
for (q = nq; q != NULL; q = nq) { |
| t = q->ipqe_m; |
t = q->ipqe_m; |
| nq = LIST_NEXT(q, ipqe_q); |
nq = TAILQ_NEXT(q, ipqe_q); |
| pool_put(&ipqent_pool, q); |
pool_put(&ipqent_pool, q); |
| m_cat(m, t); |
m_cat(m, t); |
| } |
} |
|
|
| |
|
| IPQ_LOCK_CHECK(); |
IPQ_LOCK_CHECK(); |
| |
|
| for (q = LIST_FIRST(&fp->ipq_fragq); q != NULL; q = p) { |
for (q = TAILQ_FIRST(&fp->ipq_fragq); q != NULL; q = p) { |
| p = LIST_NEXT(q, ipqe_q); |
p = TAILQ_NEXT(q, ipqe_q); |
| m_freem(q->ipqe_m); |
m_freem(q->ipqe_m); |
| LIST_REMOVE(q, ipqe_q); |
TAILQ_REMOVE(&fp->ipq_fragq, q, ipqe_q); |
| pool_put(&ipqent_pool, q); |
pool_put(&ipqent_pool, q); |
| } |
} |
| LIST_REMOVE(fp, ipq_q); |
LIST_REMOVE(fp, ipq_q); |
| Line 1660 ip_forward(m, srcrt) |
|
| Line 1662 ip_forward(m, srcrt) |
|
| ro = &sp->req->sav->sah->sa_route; |
ro = &sp->req->sav->sah->sa_route; |
| if (ro->ro_rt && ro->ro_rt->rt_ifp) { |
if (ro->ro_rt && ro->ro_rt->rt_ifp) { |
| dummyifp.if_mtu = |
dummyifp.if_mtu = |
| |
ro->ro_rt->rt_rmx.rmx_mtu ? |
| |
ro->ro_rt->rt_rmx.rmx_mtu : |
| ro->ro_rt->rt_ifp->if_mtu; |
ro->ro_rt->rt_ifp->if_mtu; |
| dummyifp.if_mtu -= ipsechdr; |
dummyifp.if_mtu -= ipsechdr; |
| destifp = &dummyifp; |
destifp = &dummyifp; |
| Line 1679 ip_forward(m, srcrt) |
|
| Line 1683 ip_forward(m, srcrt) |
|
| * a router should not generate ICMP_SOURCEQUENCH as |
* a router should not generate ICMP_SOURCEQUENCH as |
| * required in RFC1812 Requirements for IP Version 4 Routers. |
* required in RFC1812 Requirements for IP Version 4 Routers. |
| * source quench could be a big problem under DoS attacks, |
* source quench could be a big problem under DoS attacks, |
| * or the underlying interface is rate-limited. |
* or if the underlying interface is rate-limited. |
| */ |
*/ |
| if (mcopy) |
if (mcopy) |
| m_freem(mcopy); |
m_freem(mcopy); |
| Line 1803 ip_sysctl(name, namelen, oldp, oldlenp, |
|
| Line 1807 ip_sysctl(name, namelen, oldp, oldlenp, |
|
| error = sysctl_int(oldp, oldlenp, newp, newlen, |
error = sysctl_int(oldp, oldlenp, newp, newlen, |
| &ip_mtudisc); |
&ip_mtudisc); |
| if (ip_mtudisc != 0 && ip_mtudisc_timeout_q == NULL) { |
if (ip_mtudisc != 0 && ip_mtudisc_timeout_q == NULL) { |
| ip_mtudisc_timeout_q = |
ip_mtudisc_timeout_q = |
| rt_timer_queue_create(ip_mtudisc_timeout); |
rt_timer_queue_create(ip_mtudisc_timeout); |
| } else if (ip_mtudisc == 0 && ip_mtudisc_timeout_q != NULL) { |
} else if (ip_mtudisc == 0 && ip_mtudisc_timeout_q != NULL) { |
| rt_timer_queue_destroy(ip_mtudisc_timeout_q, TRUE); |
rt_timer_queue_destroy(ip_mtudisc_timeout_q, TRUE); |
| Line 1840 ip_sysctl(name, namelen, oldp, oldlenp, |
|
| Line 1844 ip_sysctl(name, namelen, oldp, oldlenp, |
|
| error = sysctl_int(oldp, oldlenp, newp, newlen, |
error = sysctl_int(oldp, oldlenp, newp, newlen, |
| &ip_mtudisc_timeout); |
&ip_mtudisc_timeout); |
| if (ip_mtudisc_timeout_q != NULL) |
if (ip_mtudisc_timeout_q != NULL) |
| rt_timer_queue_change(ip_mtudisc_timeout_q, |
rt_timer_queue_change(ip_mtudisc_timeout_q, |
| ip_mtudisc_timeout); |
ip_mtudisc_timeout); |
| return (error); |
return (error); |
| #ifdef GATEWAY |
#ifdef GATEWAY |