Changeset View
Changeset View
Standalone View
Standalone View
sys/netinet/ip_options.c
Show First 20 Lines • Show All 103 Lines • ▼ Show 20 Lines | ip_dooptions(struct mbuf *m, int pass) | ||||
struct ip *ip = mtod(m, struct ip *); | struct ip *ip = mtod(m, struct ip *); | ||||
u_char *cp; | u_char *cp; | ||||
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 *sin, dst; | ||||
uint32_t ntime; | uint32_t ntime; | ||||
struct nhop4_extended nh_ext; | struct nhop4_extended nh_ext; | ||||
struct sockaddr_in ipaddr = { sizeof(ipaddr), AF_INET }; | struct sockaddr_in ipaddr = { sizeof(ipaddr), AF_INET }; | ||||
struct epoch_tracker et; | |||||
NET_EPOCH_ASSERT(); | |||||
/* Ignore or reject packets with IP options. */ | /* Ignore or reject packets with IP options. */ | ||||
if (V_ip_doopts == 0) | if (V_ip_doopts == 0) | ||||
return 0; | return 0; | ||||
else if (V_ip_doopts == 2) { | else if (V_ip_doopts == 2) { | ||||
type = ICMP_UNREACH; | type = ICMP_UNREACH; | ||||
code = ICMP_UNREACH_FILTER_PROHIB; | code = ICMP_UNREACH_FILTER_PROHIB; | ||||
goto bad_unlocked; | goto bad; | ||||
} | } | ||||
NET_EPOCH_ENTER(et); | |||||
dst = ip->ip_dst; | dst = ip->ip_dst; | ||||
cp = (u_char *)(ip + 1); | cp = (u_char *)(ip + 1); | ||||
cnt = (ip->ip_hl << 2) - sizeof (struct ip); | cnt = (ip->ip_hl << 2) - sizeof (struct ip); | ||||
for (; cnt > 0; cnt -= optlen, cp += optlen) { | for (; cnt > 0; cnt -= optlen, cp += optlen) { | ||||
opt = cp[IPOPT_OPTVAL]; | opt = cp[IPOPT_OPTVAL]; | ||||
if (opt == IPOPT_EOL) | if (opt == IPOPT_EOL) | ||||
break; | break; | ||||
if (opt == IPOPT_NOP) | if (opt == IPOPT_NOP) | ||||
▲ Show 20 Lines • Show All 89 Lines • ▼ Show 20 Lines | nosourcerouting: | ||||
* Not acting as a router, so | * Not acting as a router, so | ||||
* silently drop. | * silently drop. | ||||
*/ | */ | ||||
#ifdef IPSTEALTH | #ifdef IPSTEALTH | ||||
dropit: | dropit: | ||||
#endif | #endif | ||||
IPSTAT_INC(ips_cantforward); | IPSTAT_INC(ips_cantforward); | ||||
m_freem(m); | m_freem(m); | ||||
NET_EPOCH_EXIT(et); | |||||
return (1); | return (1); | ||||
} | } | ||||
} | } | ||||
/* | /* | ||||
* locate outgoing interface | * locate outgoing interface | ||||
*/ | */ | ||||
(void)memcpy(&ipaddr.sin_addr, cp + off, | (void)memcpy(&ipaddr.sin_addr, cp + off, | ||||
▲ Show 20 Lines • Show All 138 Lines • ▼ Show 20 Lines | #endif | ||||
code = &cp[IPOPT_OFFSET + 1] - (u_char *)ip; | code = &cp[IPOPT_OFFSET + 1] - (u_char *)ip; | ||||
goto bad; | goto bad; | ||||
} | } | ||||
ntime = iptime(); | ntime = iptime(); | ||||
(void)memcpy(cp + off, &ntime, sizeof(uint32_t)); | (void)memcpy(cp + off, &ntime, sizeof(uint32_t)); | ||||
cp[IPOPT_OFFSET] += sizeof(uint32_t); | cp[IPOPT_OFFSET] += sizeof(uint32_t); | ||||
} | } | ||||
} | } | ||||
NET_EPOCH_EXIT(et); | |||||
if (forward && V_ipforwarding) { | if (forward && V_ipforwarding) { | ||||
ip_forward(m, 1); | ip_forward(m, 1); | ||||
return (1); | return (1); | ||||
} | } | ||||
return (0); | return (0); | ||||
bad: | bad: | ||||
NET_EPOCH_EXIT(et); | |||||
bad_unlocked: | |||||
icmp_error(m, type, code, 0, 0); | icmp_error(m, type, code, 0, 0); | ||||
IPSTAT_INC(ips_badoptions); | IPSTAT_INC(ips_badoptions); | ||||
return (1); | return (1); | ||||
} | } | ||||
/* | /* | ||||
* Save incoming source route for use in replies, to be picked up later by | * Save incoming source route for use in replies, to be picked up later by | ||||
* ip_srcroute if the receiver is interested. | * ip_srcroute if the receiver is interested. | ||||
▲ Show 20 Lines • Show All 365 Lines • Show Last 20 Lines |