37#include "opt_ipstealth.h"
42#include <sys/domain.h>
43#include <sys/protosw.h>
44#include <sys/socket.h>
46#include <sys/kernel.h>
47#include <sys/syslog.h>
48#include <sys/sysctl.h>
51#include <net/if_types.h>
52#include <net/if_var.h>
55#include <net/route/nhop.h>
56#include <net/netisr.h>
68#include <machine/in_cksum.h>
70#include <sys/socketvar.h>
74 CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(ip_dosourceroute), 0,
75 "Enable forwarding source routed IP packets");
76#define V_ip_dosourceroute VNET(ip_dosourceroute)
79SYSCTL_INT(_net_inet_ip, IPCTL_ACCEPTSOURCEROUTE, accept_sourceroute,
80 CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(ip_acceptsourceroute), 0,
81 "Enable accepting source routed IP packets");
82#define V_ip_acceptsourceroute VNET(ip_acceptsourceroute)
85SYSCTL_INT(_net_inet_ip, OID_AUTO, process_options, CTLFLAG_VNET | CTLFLAG_RW,
86 &VNET_NAME(ip_doopts), 0,
"Enable IP options processing ([LS]SRR, RR, TS)");
105 struct ip *
ip = mtod(m,
struct ip *);
108 int opt, optlen, cnt, off, code, type =
ICMP_PARAMPROB, forward = 0;
111 struct nhop_object *nh;
112 struct sockaddr_in ipaddr = {
sizeof(ipaddr), AF_INET };
126 cp = (u_char *)(
ip + 1);
127 cnt = (
ip->
ip_hl << 2) -
sizeof (
struct ip);
128 for (; cnt > 0; cnt -= optlen, cp += optlen) {
140 if (optlen <
IPOPT_OLEN +
sizeof(*cp) || optlen > cnt) {
160 if (V_ipstealth && pass > 0)
172 if (ifa_ifwithaddr_check((
struct sockaddr *)&ipaddr)
180 goto nosourcerouting;
188 if (off > optlen - (
int)
sizeof(
struct in_addr)) {
193 goto nosourcerouting;
203 char srcbuf[INET_ADDRSTRLEN];
204 char dstbuf[INET_ADDRSTRLEN];
212 "attempted source route from %s "
236 (void)memcpy(&ipaddr.
sin_addr, cp + off,
243#define INA struct in_ifaddr *
244#define SA struct sockaddr *
245 ia = (
INA)ifa_ifwithdstaddr((
SA)&ipaddr,
248 ia = (
INA)ifa_ifwithnet((
SA)&ipaddr, 0,
253 memcpy(cp + off, &(
IA_SIN(ia)->sin_addr),
262 memcpy(cp + off, &(
IA_SIN(nh->nh_ifa)->sin_addr),
276 if (V_ipstealth && pass == 0)
291 if (off > optlen - (
int)
sizeof(
struct in_addr))
300 if ((ia = (
INA)ifa_ifwithaddr((
SA)&ipaddr)) != NULL) {
301 memcpy(cp + off, &(
IA_SIN(ia)->sin_addr),
304 ipaddr.sin_addr, 0, NHR_NONE, 0)) != NULL) {
305 memcpy(cp + off, &(
IA_SIN(nh->nh_ifa)->sin_addr),
317 if (V_ipstealth && pass == 0)
320 code = cp - (u_char *)
ip;
321 if (optlen < 4 || optlen > 40) {
329 if (off > optlen - (
int)
sizeof(int32_t)) {
338 sin = (
struct in_addr *)(cp + off);
345 sizeof(
struct in_addr) > optlen) {
349 ipaddr.sin_addr = dst;
350 ia = (
INA)ifaof_ifpforaddr((
SA)&ipaddr,
354 (void)memcpy(sin, &
IA_SIN(ia)->sin_addr,
362 sizeof(
struct in_addr) > optlen) {
366 (void)memcpy(&ipaddr.sin_addr, sin,
368 if (ifa_ifwithaddr_check((
SA)&ipaddr) == 0)
379 (void)memcpy(cp + off, &ntime,
sizeof(
uint32_t));
404 opts = (
struct ipopt_tag *)m_tag_get(PACKET_TAG_IPOPTIONS,
410 if (olen >
sizeof(opts->
ip_srcrt) - (1 +
sizeof(dst))) {
411 m_tag_free((
struct m_tag *)opts);
417 m_tag_prepend(m, (
struct m_tag *)opts);
432 opts = (
struct ipopt_tag *)m_tag_find(m0, PACKET_TAG_IPOPTIONS, NULL);
438 m = m_get(M_NOWAIT, MT_DATA);
442#define OPTSIZ (sizeof(opts->ip_srcrt.nop) + sizeof(opts->ip_srcrt.srcopt))
452 *(mtod(m,
struct in_addr *)) = *p--;
459 (void)memcpy(mtod(m, caddr_t) +
sizeof(
struct in_addr),
461 q = (
struct in_addr *)(mtod(m, caddr_t) +
475 m_tag_delete(m0, (
struct m_tag *)opts);
485 struct ip *
ip = mtod(m,
struct ip *);
488 olen = (
ip->
ip_hl << 2) -
sizeof(
struct ip);
490 if (m->m_flags & M_PKTHDR)
491 m->m_pkthdr.len -= olen;
495 bcopy((
char *)
ip +
sizeof(
struct ip) + olen, (
ip + 1),
496 (
size_t )(m->m_len -
sizeof(
struct ip)));
511 struct ip *
ip = mtod(m,
struct ip *);
514 optlen = opt->m_len -
sizeof(p->
ipopt_dst);
521 if (!M_WRITABLE(m) || M_LEADINGSPACE(m) < optlen) {
522 n = m_gethdr(M_NOWAIT, MT_DATA);
528 n->m_pkthdr.rcvif = NULL;
529 n->m_pkthdr.len += optlen;
530 m->m_len -=
sizeof(
struct ip);
531 m->m_data +=
sizeof(
struct ip);
534 m->m_len = optlen +
sizeof(
struct ip);
535 m->m_data += max_linkhdr;
536 bcopy(
ip, mtod(m,
void *),
sizeof(
struct ip));
540 m->m_pkthdr.len += optlen;
541 bcopy(
ip, mtod(m,
void *),
sizeof(
struct ip));
543 ip = mtod(m,
struct ip *);
545 *phlen =
sizeof(
struct ip) + optlen;
560 int opt, optlen, cnt;
562 cp = (u_char *)(
ip + 1);
563 dp = (u_char *)(jp + 1);
564 cnt = (
ip->
ip_hl << 2) -
sizeof (
struct ip);
565 for (; cnt > 0; cnt -= optlen, cp += optlen) {
577 (
"ip_optcopy: malformed ipv4 option"));
579 KASSERT(optlen >=
IPOPT_OLEN +
sizeof(*cp) && optlen <= cnt,
580 (
"ip_optcopy: malformed ipv4 option"));
586 bcopy(cp, dp, optlen);
590 for (optlen = dp - (u_char *)(jp+1); optlen & 0x3; optlen++)
605 struct mbuf **pcbopt;
614 (void)m_free(*pcbopt);
616 if (m == NULL || m->m_len == 0) {
625 if (m->m_len %
sizeof(int32_t))
631 if (m->m_data + m->m_len +
sizeof(
struct in_addr) >= &m->m_dat[MLEN])
634 m->m_len +=
sizeof(
struct in_addr);
635 cp = mtod(m, u_char *) +
sizeof(
struct in_addr);
636 bcopy(mtod(m,
void *), cp, (
unsigned)cnt);
637 bzero(mtod(m,
void *),
sizeof(
struct in_addr));
639 for (; cnt > 0; cnt -= optlen, cp += optlen) {
649 if (optlen <
IPOPT_OLEN +
sizeof(*cp) || optlen > cnt)
672 m->m_len -=
sizeof(
struct in_addr);
674 optlen -=
sizeof(
struct in_addr);
720 struct ip *
ip = mtod(m,
struct ip *);
722 int opt, optlen, cnt, found_ra;
725 cp = (u_char *)(
ip + 1);
726 cnt = (
ip->
ip_hl << 2) -
sizeof (
struct ip);
727 for (; cnt > 0; cnt -= optlen, cp += optlen) {
740 if (optlen <
IPOPT_OLEN +
sizeof(*cp) || optlen > cnt)
char * inet_ntoa_r(struct in_addr ina, char *buf)
struct nhop_object * fib4_lookup(uint32_t fibnum, struct in_addr dst, uint32_t scopeid, uint32_t flags, uint32_t flowid)
#define INP_WLOCK_ASSERT(inp)
#define IPOPT_TS_TSANDADDR
#define ICMP_UNREACH_HOST
#define ICMP_UNREACH_SRCFAIL
void icmp_error(struct mbuf *, int, int, uint32_t, int)
#define ICMP_UNREACH_FILTER_PROHIB
VNET_DEFINE_STATIC(int, ip_dosourceroute)
struct mbuf * ip_insertoptions(struct mbuf *m, struct mbuf *opt, int *phlen)
VNET_DEFINE(int, ip_doopts)
void ip_stripoptions(struct mbuf *m)
int ip_pcbopts(struct inpcb *inp, int optname, struct mbuf *m)
struct mbuf * ip_srcroute(struct mbuf *m0)
int ip_optcopy(struct ip *ip, struct ip *jp)
static void save_rte(struct mbuf *m, u_char *, struct in_addr)
SYSCTL_INT(_net_inet_ip, IPCTL_SOURCEROUTE, sourceroute, CTLFLAG_VNET|CTLFLAG_RW, &VNET_NAME(ip_dosourceroute), 0, "Enable forwarding source routed IP packets")
#define V_ip_dosourceroute
int ip_checkrouteralert(struct mbuf *m)
int ip_dooptions(struct mbuf *m, int pass)
#define V_ip_acceptsourceroute
struct mbuf * inp_options
struct in_addr ip_src ip_dst
char ipopt_list[MAX_IPOPTLEN]
char srcopt[IPOPT_OFFSET+1]
struct in_addr route[MAX_IPOPTLEN/sizeof(struct in_addr)]