| version 1.82.2.7, 2001/05/30 09:44:09 |
version 1.83, 1999/04/07 02:31:05 |
|
|
| |
|
| struct ipqhead ipq; |
struct ipqhead ipq; |
| int ipq_locked; |
int ipq_locked; |
| int ip_nfragpackets = 0; |
|
| int ip_maxfragpackets = 200; |
|
| |
|
| static __inline int ipq_lock_try __P((void)); |
static __inline int ipq_lock_try __P((void)); |
| static __inline void ipq_unlock __P((void)); |
static __inline void ipq_unlock __P((void)); |
|
|
| } |
} |
| ip = mtod(m, struct ip *); |
ip = mtod(m, struct ip *); |
| } |
} |
| |
|
| /* |
|
| * RFC1122: packets with a multicast source address are |
|
| * not allowed. |
|
| */ |
|
| if (IN_MULTICAST(ip->ip_src.s_addr)) { |
|
| /* XXX stat */ |
|
| goto bad; |
|
| } |
|
| |
|
| if (in_cksum(m, hlen) != 0) { |
if (in_cksum(m, hlen) != 0) { |
| ipstat.ips_badsum++; |
ipstat.ips_badsum++; |
| goto bad; |
goto bad; |
|
|
| * 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. |
| */ |
*/ |
| INADDR_TO_IA(ip->ip_dst, ia); |
INADDR_TO_IA(ip->ip_dst, ia); |
| if (ia != NULL) |
if (ia != NULL) { |
| goto ours; |
if (ia->ia_ifp->if_flags & IFF_UP) |
| |
goto ours; |
| |
} |
| if (m->m_pkthdr.rcvif->if_flags & IFF_BROADCAST) { |
if (m->m_pkthdr.rcvif->if_flags & IFF_BROADCAST) { |
| for (ifa = m->m_pkthdr.rcvif->if_addrlist.tqh_first; |
for (ifa = m->m_pkthdr.rcvif->if_addrlist.tqh_first; |
| ifa != NULL; ifa = ifa->ifa_list.tqe_next) { |
ifa != NULL; ifa = ifa->ifa_list.tqe_next) { |
| Line 643 ip_reass(ipqe, fp) |
|
| Line 633 ip_reass(ipqe, fp) |
|
| * If first fragment to arrive, create a reassembly queue. |
* If first fragment to arrive, create a reassembly queue. |
| */ |
*/ |
| if (fp == 0) { |
if (fp == 0) { |
| /* |
|
| * Enforce upper bound on number of fragmented packets |
|
| * for which we attempt reassembly; |
|
| * If maxfrag is 0, never accept fragments. |
|
| * If maxfrag is -1, accept all fragments without limitation. |
|
| */ |
|
| if (ip_maxfragpackets < 0) |
|
| ; |
|
| else if (ip_nfragpackets >= ip_maxfragpackets) |
|
| goto dropfrag; |
|
| ip_nfragpackets++; |
|
| MALLOC(fp, struct ipq *, sizeof (struct ipq), |
MALLOC(fp, struct ipq *, sizeof (struct ipq), |
| M_FTABLE, M_NOWAIT); |
M_FTABLE, M_NOWAIT); |
| if (fp == NULL) |
if (fp == NULL) |
|
|
| ip->ip_dst = fp->ipq_dst; |
ip->ip_dst = fp->ipq_dst; |
| LIST_REMOVE(fp, ipq_q); |
LIST_REMOVE(fp, ipq_q); |
| FREE(fp, M_FTABLE); |
FREE(fp, M_FTABLE); |
| ip_nfragpackets--; |
|
| m->m_len += (ip->ip_hl << 2); |
m->m_len += (ip->ip_hl << 2); |
| 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 */ |
|
|
| } |
} |
| LIST_REMOVE(fp, ipq_q); |
LIST_REMOVE(fp, ipq_q); |
| FREE(fp, M_FTABLE); |
FREE(fp, M_FTABLE); |
| ip_nfragpackets--; |
|
| } |
} |
| |
|
| /* |
/* |
|
|
| ip_freef(fp); |
ip_freef(fp); |
| } |
} |
| } |
} |
| /* |
|
| * If we are over the maximum number of fragments |
|
| * (due to the limit being lowered), drain off |
|
| * enough to get down to the new limit. |
|
| */ |
|
| if (ip_maxfragpackets < 0) |
|
| ; |
|
| else { |
|
| while (ip_nfragpackets > ip_maxfragpackets && ipq.lh_first) |
|
| ip_freef(ipq.lh_first); |
|
| } |
|
| IPQ_UNLOCK(); |
IPQ_UNLOCK(); |
| #ifdef GATEWAY |
#ifdef GATEWAY |
| ipflow_slowtimo(); |
ipflow_slowtimo(); |
|
|
| struct mbuf *m; |
struct mbuf *m; |
| { |
{ |
| register struct ip *ip = mtod(m, struct ip *); |
register struct ip *ip = mtod(m, struct ip *); |
| register u_char *cp, *cp0; |
register u_char *cp; |
| register struct ip_timestamp *ipt; |
register struct ip_timestamp *ipt; |
| register struct in_ifaddr *ia; |
register 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 dst; |
struct in_addr *sin, dst; |
| n_time ntime; |
n_time ntime; |
| |
|
| dst = ip->ip_dst; |
dst = ip->ip_dst; |
|
|
| break; |
break; |
| } |
} |
| off--; /* 0 origin */ |
off--; /* 0 origin */ |
| if ((off + sizeof(struct in_addr)) > optlen) { |
if (off > optlen - sizeof(struct in_addr)) { |
| /* |
/* |
| * End of source route. Should be for us. |
* End of source route. Should be for us. |
| */ |
*/ |
|
|
| * If no space remains, ignore. |
* If no space remains, ignore. |
| */ |
*/ |
| off--; /* 0 origin */ |
off--; /* 0 origin */ |
| if ((off + sizeof(struct in_addr)) > optlen) |
if (off > optlen - sizeof(struct in_addr)) |
| 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 1016 ip_dooptions(m) |
|
|
| goto bad; |
goto bad; |
| break; |
break; |
| } |
} |
| cp0 = (cp + ipt->ipt_ptr - 1); |
sin = (struct in_addr *)(cp + ipt->ipt_ptr - 1); |
| switch (ipt->ipt_flg) { |
switch (ipt->ipt_flg) { |
| |
|
| case IPOPT_TS_TSONLY: |
case IPOPT_TS_TSONLY: |
| Line 1031 ip_dooptions(m) |
|
|
| m->m_pkthdr.rcvif); |
m->m_pkthdr.rcvif); |
| if (ia == 0) |
if (ia == 0) |
| continue; |
continue; |
| bcopy(&ia->ia_addr.sin_addr, |
bcopy((caddr_t)&ia->ia_addr.sin_addr, |
| cp0, sizeof(struct in_addr)); |
(caddr_t)sin, sizeof(struct in_addr)); |
| ipt->ipt_ptr += sizeof(struct in_addr); |
ipt->ipt_ptr += sizeof(struct in_addr); |
| break; |
break; |
| |
|
| Line 1040 ip_dooptions(m) |
|
| Line 1006 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(cp0, &ipaddr.sin_addr, |
bcopy((caddr_t)sin, (caddr_t)&ipaddr.sin_addr, |
| sizeof(struct in_addr)); |
sizeof(struct in_addr)); |
| if (ifa_ifwithaddr((SA)&ipaddr) == 0) |
if (ifa_ifwithaddr((SA)&ipaddr) == 0) |
| continue; |
continue; |
| Line 1051 ip_dooptions(m) |
|
| Line 1017 ip_dooptions(m) |
|
| goto bad; |
goto bad; |
| } |
} |
| ntime = iptime(); |
ntime = iptime(); |
| cp0 = (u_char *) &ntime; /* XXX GCC BUG */ |
bcopy((caddr_t)&ntime, (caddr_t)cp + ipt->ipt_ptr - 1, |
| 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 1264 ip_forward(m, srcrt) |
|
| Line 1229 ip_forward(m, srcrt) |
|
| ntohl(ip->ip_src.s_addr), |
ntohl(ip->ip_src.s_addr), |
| ntohl(ip->ip_dst.s_addr), ip->ip_ttl); |
ntohl(ip->ip_dst.s_addr), ip->ip_ttl); |
| #endif |
#endif |
| if (m->m_flags & (M_BCAST|M_MCAST) || in_canforward(ip->ip_dst) == 0) { |
if (m->m_flags & M_BCAST || in_canforward(ip->ip_dst) == 0) { |
| ipstat.ips_cantforward++; |
ipstat.ips_cantforward++; |
| m_freem(m); |
m_freem(m); |
| return; |
return; |
| Line 1548 ip_sysctl(name, namelen, oldp, oldlenp, |
|
| Line 1513 ip_sysctl(name, namelen, oldp, oldlenp, |
|
| return (error); |
return (error); |
| } |
} |
| #endif |
#endif |
| |
|
| case IPCTL_MAXFRAGPACKETS: |
|
| return (sysctl_int(oldp, oldlenp, newp, newlen, |
|
| &ip_maxfragpackets)); |
|
| |
|
| default: |
default: |
| return (EOPNOTSUPP); |
return (EOPNOTSUPP); |
| } |
} |