version 1.98, 2000/02/12 17:45:44 |
version 1.112, 2000/05/06 16:35:14 |
|
|
#include <netinet/in_gif.h> |
#include <netinet/in_gif.h> |
#include "gif.h" |
#include "gif.h" |
|
|
|
#ifdef MROUTING |
|
#include <netinet/ip_mroute.h> |
|
#endif |
|
|
#ifdef IPSEC |
#ifdef IPSEC |
#include <netinet6/ipsec.h> |
#include <netinet6/ipsec.h> |
#include <netkey/key.h> |
#include <netkey/key.h> |
Line 194 int ipprintfs = 0; |
|
Line 198 int ipprintfs = 0; |
|
struct rttimer_queue *ip_mtudisc_timeout_q = NULL; |
struct rttimer_queue *ip_mtudisc_timeout_q = NULL; |
|
|
extern struct domain inetdomain; |
extern struct domain inetdomain; |
extern struct protosw inetsw[]; |
|
u_char ip_protox[IPPROTO_MAX]; |
|
int ipqmaxlen = IFQ_MAXLEN; |
int ipqmaxlen = IFQ_MAXLEN; |
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; |
struct ipstat ipstat; |
struct ipstat ipstat; |
u_int16_t ip_id; |
u_int16_t ip_id; |
int ip_defttl; |
|
|
|
struct ipqhead ipq; |
struct ipqhead ipq; |
int ipq_locked; |
int ipq_locked; |
Line 283 static void save_rte __P((u_char *, stru |
|
Line 284 static void save_rte __P((u_char *, stru |
|
void |
void |
ip_init() |
ip_init() |
{ |
{ |
register struct protosw *pr; |
struct protosw *pr; |
register int i; |
int i; |
|
|
pool_init(&ipqent_pool, sizeof(struct ipqent), 0, 0, 0, "ipqepl", |
pool_init(&ipqent_pool, sizeof(struct ipqent), 0, 0, 0, "ipqepl", |
0, NULL, NULL, M_IPQ); |
0, NULL, NULL, M_IPQ); |
|
|
void |
void |
ip_input(struct mbuf *m) |
ip_input(struct mbuf *m) |
{ |
{ |
register struct ip *ip = NULL; |
struct ip *ip = NULL; |
register struct ipq *fp; |
struct ipq *fp; |
register struct in_ifaddr *ia; |
struct in_ifaddr *ia; |
register struct ifaddr *ifa; |
struct ifaddr *ifa; |
struct ipqent *ipqe; |
struct ipqent *ipqe; |
int hlen = 0, mff, len; |
int hlen = 0, mff, len; |
|
int downmatch; |
#ifdef PFIL_HOOKS |
#ifdef PFIL_HOOKS |
struct packet_filter_hook *pfh; |
struct packet_filter_hook *pfh; |
struct mbuf *m0; |
struct mbuf *m0; |
Line 399 ip_input(struct mbuf *m) |
|
Line 401 ip_input(struct mbuf *m) |
|
} |
} |
|
|
/* |
/* |
* RFC1112: packets with a multicast source address are |
* RFC1122: packets with a multicast source address are |
* not allowed. |
* not allowed. |
*/ |
*/ |
if (IN_MULTICAST(ip->ip_src.s_addr)) { |
if (IN_MULTICAST(ip->ip_src.s_addr)) { |
Line 465 ip_input(struct mbuf *m) |
|
Line 467 ip_input(struct mbuf *m) |
|
* in the list may have previously cleared it. |
* in the list may have previously cleared it. |
*/ |
*/ |
m0 = m; |
m0 = m; |
for (pfh = pfil_hook_get(PFIL_IN); pfh; pfh = pfh->pfil_link.tqe_next) |
pfh = pfil_hook_get(PFIL_IN, &inetsw[ip_protox[IPPROTO_IP]].pr_pfh); |
|
for (; pfh; pfh = pfh->pfil_link.tqe_next) |
if (pfh->pfil_func) { |
if (pfh->pfil_func) { |
rv = pfh->pfil_func(ip, hlen, m->m_pkthdr.rcvif, 0, &m0); |
rv = pfh->pfil_func(ip, hlen, |
|
m->m_pkthdr.rcvif, 0, &m0); |
if (rv) |
if (rv) |
return; |
return; |
m = m0; |
m = m0; |
Line 489 ip_input(struct mbuf *m) |
|
Line 493 ip_input(struct mbuf *m) |
|
|
|
/* |
/* |
* Check our list of addresses, to see if the packet is for us. |
* Check our list of addresses, to see if the packet is for us. |
|
* |
|
* Traditional 4.4BSD did not consult IFF_UP at all. |
|
* The behavior here is to treat addresses on !IFF_UP interface |
|
* as not mine. |
*/ |
*/ |
|
downmatch = 0; |
for (ia = IN_IFADDR_HASH(ip->ip_dst.s_addr).lh_first; |
for (ia = IN_IFADDR_HASH(ip->ip_dst.s_addr).lh_first; |
ia != NULL; |
ia != NULL; |
ia = ia->ia_hash.le_next) { |
ia = ia->ia_hash.le_next) { |
if (in_hosteq(ia->ia_addr.sin_addr, ip->ip_dst)) { |
if (in_hosteq(ia->ia_addr.sin_addr, ip->ip_dst)) { |
if ((ia->ia_ifp->if_flags & IFF_UP) != 0) |
if ((ia->ia_ifp->if_flags & IFF_UP) != 0) |
break; |
break; |
else { |
else |
icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_HOST, |
downmatch++; |
0, m->m_pkthdr.rcvif); |
|
return; |
|
} |
|
} |
} |
} |
} |
if (ia != NULL) |
if (ia != NULL) |
Line 591 ip_input(struct mbuf *m) |
|
Line 597 ip_input(struct mbuf *m) |
|
if (ipforwarding == 0) { |
if (ipforwarding == 0) { |
ipstat.ips_cantforward++; |
ipstat.ips_cantforward++; |
m_freem(m); |
m_freem(m); |
} else |
} else { |
|
/* |
|
* If ip_dst matched any of my address on !IFF_UP interface, |
|
* and there's no IFF_UP interface that matches ip_dst, |
|
* send icmp unreach. Forwarding it will result in in-kernel |
|
* forwarding loop till TTL goes to 0. |
|
*/ |
|
if (downmatch) { |
|
icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_HOST, 0, 0); |
|
ipstat.ips_cantforward++; |
|
return; |
|
} |
ip_forward(m, 0); |
ip_forward(m, 0); |
|
} |
return; |
return; |
|
|
ours: |
ours: |
|
|
*/ |
*/ |
struct mbuf * |
struct mbuf * |
ip_reass(ipqe, fp) |
ip_reass(ipqe, fp) |
register struct ipqent *ipqe; |
struct ipqent *ipqe; |
register struct ipq *fp; |
struct ipq *fp; |
{ |
{ |
register struct mbuf *m = ipqe->ipqe_m; |
struct mbuf *m = ipqe->ipqe_m; |
register struct ipqent *nq, *p, *q; |
struct ipqent *nq, *p, *q; |
struct ip *ip; |
struct ip *ip; |
struct mbuf *t; |
struct mbuf *t; |
int hlen = ipqe->ipqe_ip->ip_hl << 2; |
int hlen = ipqe->ipqe_ip->ip_hl << 2; |
|
|
* Make header visible. |
* Make header visible. |
*/ |
*/ |
ip->ip_len = next; |
ip->ip_len = next; |
ip->ip_ttl = 0; /* xxx */ |
|
ip->ip_sum = 0; |
|
ip->ip_src = fp->ipq_src; |
ip->ip_src = fp->ipq_src; |
ip->ip_dst = fp->ipq_dst; |
ip->ip_dst = fp->ipq_dst; |
LIST_REMOVE(fp, ipq_q); |
LIST_REMOVE(fp, ipq_q); |
|
|
m->m_data -= (ip->ip_hl << 2); |
m->m_data -= (ip->ip_hl << 2); |
/* some debugging cruft by sklower, below, will go away soon */ |
/* some debugging cruft by sklower, below, will go away soon */ |
if (m->m_flags & M_PKTHDR) { /* XXX this should be done elsewhere */ |
if (m->m_flags & M_PKTHDR) { /* XXX this should be done elsewhere */ |
register int plen = 0; |
int plen = 0; |
for (t = m; t; t = t->m_next) |
for (t = m; t; t = t->m_next) |
plen += t->m_len; |
plen += t->m_len; |
m->m_pkthdr.len = plen; |
m->m_pkthdr.len = plen; |
|
|
ip_freef(fp) |
ip_freef(fp) |
struct ipq *fp; |
struct ipq *fp; |
{ |
{ |
register struct ipqent *q, *p; |
struct ipqent *q, *p; |
|
|
IPQ_LOCK_CHECK(); |
IPQ_LOCK_CHECK(); |
|
|
|
|
void |
void |
ip_slowtimo() |
ip_slowtimo() |
{ |
{ |
register struct ipq *fp, *nfp; |
struct ipq *fp, *nfp; |
int s = splsoftnet(); |
int s = splsoftnet(); |
|
|
IPQ_LOCK(); |
IPQ_LOCK(); |
|
|
ip_dooptions(m) |
ip_dooptions(m) |
struct mbuf *m; |
struct mbuf *m; |
{ |
{ |
register struct ip *ip = mtod(m, struct ip *); |
struct ip *ip = mtod(m, struct ip *); |
register u_char *cp; |
u_char *cp, *cp0; |
register struct ip_timestamp *ipt; |
struct ip_timestamp *ipt; |
register struct in_ifaddr *ia; |
struct in_ifaddr *ia; |
int opt, optlen, cnt, off, code, type = ICMP_PARAMPROB, forward = 0; |
int opt, optlen, cnt, off, code, type = ICMP_PARAMPROB, forward = 0; |
struct in_addr *sin, dst; |
struct in_addr dst; |
n_time ntime; |
n_time ntime; |
|
|
dst = ip->ip_dst; |
dst = ip->ip_dst; |
|
Line 1013 ip_dooptions(m) |
|
break; |
break; |
} |
} |
off--; /* 0 origin */ |
off--; /* 0 origin */ |
if (off > optlen - sizeof(struct in_addr)) { |
if ((off + sizeof(struct in_addr)) > optlen) { |
/* |
/* |
* End of source route. Should be for us. |
* End of source route. Should be for us. |
*/ |
*/ |
Line 1037 ip_dooptions(m) |
|
Line 1053 ip_dooptions(m) |
|
* If no space remains, ignore. |
* If no space remains, ignore. |
*/ |
*/ |
off--; /* 0 origin */ |
off--; /* 0 origin */ |
if (off > optlen - sizeof(struct in_addr)) |
if ((off + sizeof(struct in_addr)) > optlen) |
break; |
break; |
bcopy((caddr_t)(&ip->ip_dst), (caddr_t)&ipaddr.sin_addr, |
bcopy((caddr_t)(&ip->ip_dst), (caddr_t)&ipaddr.sin_addr, |
sizeof(ipaddr.sin_addr)); |
sizeof(ipaddr.sin_addr)); |
Line 1067 ip_dooptions(m) |
|
Line 1083 ip_dooptions(m) |
|
goto bad; |
goto bad; |
break; |
break; |
} |
} |
sin = (struct in_addr *)(cp + ipt->ipt_ptr - 1); |
cp0 = (cp + ipt->ipt_ptr - 1); |
switch (ipt->ipt_flg) { |
switch (ipt->ipt_flg) { |
|
|
case IPOPT_TS_TSONLY: |
case IPOPT_TS_TSONLY: |
Line 1082 ip_dooptions(m) |
|
Line 1098 ip_dooptions(m) |
|
m->m_pkthdr.rcvif)); |
m->m_pkthdr.rcvif)); |
if (ia == 0) |
if (ia == 0) |
continue; |
continue; |
bcopy((caddr_t)&ia->ia_addr.sin_addr, |
bcopy(&ia->ia_addr.sin_addr, |
(caddr_t)sin, sizeof(struct in_addr)); |
cp0, sizeof(struct in_addr)); |
ipt->ipt_ptr += sizeof(struct in_addr); |
ipt->ipt_ptr += sizeof(struct in_addr); |
break; |
break; |
|
|
Line 1091 ip_dooptions(m) |
|
Line 1107 ip_dooptions(m) |
|
if (ipt->ipt_ptr - 1 + sizeof(n_time) + |
if (ipt->ipt_ptr - 1 + sizeof(n_time) + |
sizeof(struct in_addr) > ipt->ipt_len) |
sizeof(struct in_addr) > ipt->ipt_len) |
goto bad; |
goto bad; |
bcopy((caddr_t)sin, (caddr_t)&ipaddr.sin_addr, |
bcopy(cp0, &ipaddr.sin_addr, |
sizeof(struct in_addr)); |
sizeof(struct in_addr)); |
if (ifatoia(ifa_ifwithaddr(sintosa(&ipaddr))) |
if (ifatoia(ifa_ifwithaddr(sintosa(&ipaddr))) |
== NULL) |
== NULL) |
Line 1103 ip_dooptions(m) |
|
Line 1119 ip_dooptions(m) |
|
goto bad; |
goto bad; |
} |
} |
ntime = iptime(); |
ntime = iptime(); |
bcopy((caddr_t)&ntime, (caddr_t)cp + ipt->ipt_ptr - 1, |
cp0 = (u_char *) &ntime; /* XXX grumble, GCC... */ |
|
bcopy(cp0, (caddr_t)cp + ipt->ipt_ptr - 1, |
sizeof(n_time)); |
sizeof(n_time)); |
ipt->ipt_ptr += sizeof(n_time); |
ipt->ipt_ptr += sizeof(n_time); |
} |
} |
Line 1132 struct in_ifaddr * |
|
Line 1149 struct in_ifaddr * |
|
ip_rtaddr(dst) |
ip_rtaddr(dst) |
struct in_addr dst; |
struct in_addr dst; |
{ |
{ |
register struct sockaddr_in *sin; |
struct sockaddr_in *sin; |
|
|
sin = satosin(&ipforward_rt.ro_dst); |
sin = satosin(&ipforward_rt.ro_dst); |
|
|
Line 1183 save_rte(option, dst) |
|
Line 1200 save_rte(option, dst) |
|
struct mbuf * |
struct mbuf * |
ip_srcroute() |
ip_srcroute() |
{ |
{ |
register struct in_addr *p, *q; |
struct in_addr *p, *q; |
register struct mbuf *m; |
struct mbuf *m; |
|
|
if (ip_nhops == 0) |
if (ip_nhops == 0) |
return ((struct mbuf *)0); |
return ((struct mbuf *)0); |
|
|
*/ |
*/ |
void |
void |
ip_stripoptions(m, mopt) |
ip_stripoptions(m, mopt) |
register struct mbuf *m; |
struct mbuf *m; |
struct mbuf *mopt; |
struct mbuf *mopt; |
{ |
{ |
register int i; |
int i; |
struct ip *ip = mtod(m, struct ip *); |
struct ip *ip = mtod(m, struct ip *); |
register caddr_t opts; |
caddr_t opts; |
int olen; |
int olen; |
|
|
olen = (ip->ip_hl << 2) - sizeof (struct ip); |
olen = (ip->ip_hl << 2) - sizeof (struct ip); |
Line 1300 ip_forward(m, srcrt) |
|
Line 1317 ip_forward(m, srcrt) |
|
struct mbuf *m; |
struct mbuf *m; |
int srcrt; |
int srcrt; |
{ |
{ |
register struct ip *ip = mtod(m, struct ip *); |
struct ip *ip = mtod(m, struct ip *); |
register struct sockaddr_in *sin; |
struct sockaddr_in *sin; |
register struct rtentry *rt; |
struct rtentry *rt; |
int error, type = 0, code = 0; |
int error, type = 0, code = 0; |
struct mbuf *mcopy; |
struct mbuf *mcopy; |
n_long dest; |
n_long dest; |
Line 1388 ip_forward(m, srcrt) |
|
Line 1405 ip_forward(m, srcrt) |
|
} |
} |
|
|
#ifdef IPSEC |
#ifdef IPSEC |
m->m_pkthdr.rcvif = NULL; |
/* Don't lookup socket in forwading case */ |
#endif /*IPSEC*/ |
ipsec_setsocket(m, NULL); |
|
#endif |
error = ip_output(m, (struct mbuf *)0, &ipforward_rt, |
error = ip_output(m, (struct mbuf *)0, &ipforward_rt, |
(IP_FORWARDING | (ip_directedbcast ? IP_ALLOWBROADCAST : 0)), 0); |
(IP_FORWARDING | (ip_directedbcast ? IP_ALLOWBROADCAST : 0)), 0); |
if (error) |
if (error) |
Line 1499 ip_forward(m, srcrt) |
|
Line 1517 ip_forward(m, srcrt) |
|
|
|
void |
void |
ip_savecontrol(inp, mp, ip, m) |
ip_savecontrol(inp, mp, ip, m) |
register struct inpcb *inp; |
struct inpcb *inp; |
register struct mbuf **mp; |
struct mbuf **mp; |
register struct ip *ip; |
struct ip *ip; |
register struct mbuf *m; |
struct mbuf *m; |
{ |
{ |
|
|
if (inp->inp_socket->so_options & SO_TIMESTAMP) { |
if (inp->inp_socket->so_options & SO_TIMESTAMP) { |