Changeset View
Changeset View
Standalone View
Standalone View
sys/netinet/raw_ip.c
Show First 20 Lines • Show All 448 Lines • ▼ Show 20 Lines | |||||
{ | { | ||||
struct ip *ip; | struct ip *ip; | ||||
int error; | int error; | ||||
struct inpcb *inp = sotoinpcb(so); | struct inpcb *inp = sotoinpcb(so); | ||||
va_list ap; | va_list ap; | ||||
u_long dst; | u_long dst; | ||||
int flags = ((so->so_options & SO_DONTROUTE) ? IP_ROUTETOIF : 0) | | int flags = ((so->so_options & SO_DONTROUTE) ? IP_ROUTETOIF : 0) | | ||||
IP_ALLOWBROADCAST; | IP_ALLOWBROADCAST; | ||||
int cnt; | |||||
u_char opttype, optlen, *cp; | |||||
va_start(ap, so); | va_start(ap, so); | ||||
dst = va_arg(ap, u_long); | dst = va_arg(ap, u_long); | ||||
va_end(ap); | va_end(ap); | ||||
/* | /* | ||||
* If the user handed us a complete IP packet, use it. Otherwise, | * If the user handed us a complete IP packet, use it. Otherwise, | ||||
* allocate an mbuf for a header and fill it in. | * allocate an mbuf for a header and fill it in. | ||||
▲ Show 20 Lines • Show All 57 Lines • ▼ Show 20 Lines | if ((inp->inp_flags & INP_HDRINCL) == 0) { | ||||
* and don't allow packet length sizes that will crash. | * and don't allow packet length sizes that will crash. | ||||
*/ | */ | ||||
if (((ip->ip_hl != (sizeof (*ip) >> 2)) && inp->inp_options) | if (((ip->ip_hl != (sizeof (*ip) >> 2)) && inp->inp_options) | ||||
|| (ntohs(ip->ip_len) != m->m_pkthdr.len) | || (ntohs(ip->ip_len) != m->m_pkthdr.len) | ||||
|| (ntohs(ip->ip_len) < (ip->ip_hl << 2))) { | || (ntohs(ip->ip_len) < (ip->ip_hl << 2))) { | ||||
INP_RUNLOCK(inp); | INP_RUNLOCK(inp); | ||||
m_freem(m); | m_freem(m); | ||||
return (EINVAL); | return (EINVAL); | ||||
} | |||||
/* | |||||
* Don't allow IP options which do not have the required | |||||
* structure as specified in section 3.1 of RFC 791 on | |||||
* pages 15-23. | |||||
*/ | |||||
cp = (u_char *)(ip + 1); | |||||
cnt = (ip->ip_hl << 2) - sizeof (struct ip); | |||||
for (; cnt > 0; cnt -= optlen, cp += optlen) { | |||||
opttype = cp[IPOPT_OPTVAL]; | |||||
if (opttype == IPOPT_EOL) | |||||
break; | |||||
if (opttype == IPOPT_NOP) { | |||||
optlen = 1; | |||||
continue; | |||||
} | |||||
if (cnt < IPOPT_OLEN + sizeof(u_char)) { | |||||
INP_RUNLOCK(inp); | |||||
m_freem(m); | |||||
return (EINVAL); | |||||
} | |||||
optlen = cp[IPOPT_OLEN]; | |||||
if (optlen < IPOPT_OLEN + sizeof(u_char) || | |||||
optlen > cnt) { | |||||
INP_RUNLOCK(inp); | |||||
m_freem(m); | |||||
return (EINVAL); | |||||
} | |||||
} | } | ||||
/* | /* | ||||
* This doesn't allow application to specify ID of zero, | * This doesn't allow application to specify ID of zero, | ||||
* but we got this limitation from the beginning of history. | * but we got this limitation from the beginning of history. | ||||
*/ | */ | ||||
if (ip->ip_id == 0) | if (ip->ip_id == 0) | ||||
ip_fillid(ip); | ip_fillid(ip); | ||||
▲ Show 20 Lines • Show All 612 Lines • Show Last 20 Lines |