X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/b226f5e54a60dc81db17b1260381d7dbfea3cdf1..0a7de7458d150b5d4dffc935ba399be265ef0a1a:/bsd/net/packet_mangler.c diff --git a/bsd/net/packet_mangler.c b/bsd/net/packet_mangler.c index 24d18870a..db7b4e643 100644 --- a/bsd/net/packet_mangler.c +++ b/bsd/net/packet_mangler.c @@ -54,44 +54,44 @@ #include #include -#define MAX_PACKET_MANGLER 1 +#define MAX_PACKET_MANGLER 1 -#define PKT_MNGLR_FLG_IPFILTER_ATTACHED 0x00000001 +#define PKT_MNGLR_FLG_IPFILTER_ATTACHED 0x00000001 -SYSCTL_NODE(_net, OID_AUTO, pktmnglr, CTLFLAG_RW|CTLFLAG_LOCKED, 0, "pktmnglr"); -SYSCTL_INT(_net_pktmnglr, OID_AUTO, log, CTLFLAG_RW|CTLFLAG_LOCKED, - &pkt_mnglr_log_level, 0, ""); +SYSCTL_NODE(_net, OID_AUTO, pktmnglr, CTLFLAG_RW | CTLFLAG_LOCKED, 0, "pktmnglr"); +SYSCTL_INT(_net_pktmnglr, OID_AUTO, log, CTLFLAG_RW | CTLFLAG_LOCKED, + &pkt_mnglr_log_level, 0, ""); /* * The structure packet_mangler represents a user space packet filter * It's created and associated with a kernel control socket instance */ struct packet_mangler { - kern_ctl_ref pkt_mnglr_kcref; - uint32_t pkt_mnglr_kcunit; - uint32_t pkt_mnglr_flags; + kern_ctl_ref pkt_mnglr_kcref; + uint32_t pkt_mnglr_kcunit; + uint32_t pkt_mnglr_flags; /* IP filter related params */ - ipfilter_t pkt_mnglr_ipfref; - ipfilter_t pkt_mnglr_ipfrefv6; - struct ipf_filter pkt_mnglr_ipfilter; + ipfilter_t pkt_mnglr_ipfref; + ipfilter_t pkt_mnglr_ipfrefv6; + struct ipf_filter pkt_mnglr_ipfilter; /* Options */ - uint8_t activate; - Pkt_Mnglr_Flow dir; - struct sockaddr_storage lsaddr; - struct sockaddr_storage rsaddr; - struct sockaddr_storage swap_lsaddr; - struct sockaddr_storage swap_rsaddr; - uint32_t ip_action_mask; - uint16_t lport; - uint16_t rport; - uint32_t proto; - uint32_t proto_action_mask; + uint8_t activate; + Pkt_Mnglr_Flow dir; + struct sockaddr_storage lsaddr; + struct sockaddr_storage rsaddr; + struct sockaddr_storage swap_lsaddr; + struct sockaddr_storage swap_rsaddr; + uint32_t ip_action_mask; + uint16_t lport; + uint16_t rport; + uint32_t proto; + uint32_t proto_action_mask; }; /* Array of all the packet mangler instancesi */ struct packet_mangler **packet_manglers = NULL; -uint32_t pkt_mnglr_active_count = 0; /* Number of active packet filters */ +uint32_t pkt_mnglr_active_count = 0; /* Number of active packet filters */ uint32_t pkt_mnglr_close_wait_timeout = 1000; /* in milliseconds */ static kern_ctl_ref pkt_mnglr_kctlref = NULL; @@ -103,7 +103,7 @@ static lck_grp_t *pkt_mnglr_lck_grp = NULL; /* The lock below protects packet_manglers DS, packet_mangler DS */ decl_lck_rw_data(static, pkt_mnglr_lck_rw); -#define PKT_MNGLR_RW_LCK_MAX 8 +#define PKT_MNGLR_RW_LCK_MAX 8 int pkt_mnglr_rw_nxt_lck = 0; void* pkt_mnglr_rw_lock_history[PKT_MNGLR_RW_LCK_MAX]; @@ -112,9 +112,9 @@ int pkt_mnglr_rw_nxt_unlck = 0; void* pkt_mnglr_rw_unlock_history[PKT_MNGLR_RW_LCK_MAX]; -#define PACKET_MANGLER_ZONE_NAME "packet_mangler" -#define PACKET_MANGLER_ZONE_MAX 10 -static struct zone *packet_mangler_zone = NULL; /* zone for packet_mangler */ +#define PACKET_MANGLER_ZONE_NAME "packet_mangler" +#define PACKET_MANGLER_ZONE_MAX 10 +static struct zone *packet_mangler_zone = NULL; /* zone for packet_mangler */ /* * For troubleshooting @@ -131,24 +131,24 @@ static void pkt_mnglr_rw_lock_shared(lck_rw_t *); static void pkt_mnglr_rw_unlock_shared(lck_rw_t *); static errno_t pktmnglr_ipfilter_output(void *cookie, mbuf_t *data, - ipf_pktopts_t options); + ipf_pktopts_t options); static errno_t pktmnglr_ipfilter_input(void *cookie, mbuf_t *data, - int offset, u_int8_t protocol); + int offset, u_int8_t protocol); static void pktmnglr_ipfilter_detach(void *cookie); static void chksm_update(mbuf_t data); -#define TCP_OPT_MULTIPATH_TCP 30 -#define MPTCP_SBT_VER_OFFSET 2 +#define TCP_OPT_MULTIPATH_TCP 30 +#define MPTCP_SBT_VER_OFFSET 2 -#define MPTCP_SUBTYPE_MPCAPABLE 0x0 -#define MPTCP_SUBTYPE_MPJOIN 0x1 -#define MPTCP_SUBTYPE_DSS 0x2 -#define MPTCP_SUBTYPE_ADD_ADDR 0x3 -#define MPTCP_SUBTYPE_REM_ADDR 0x4 -#define MPTCP_SUBTYPE_MP_PRIO 0x5 -#define MPTCP_SUBTYPE_MP_FAIL 0x6 -#define MPTCP_SUBTYPE_MP_FASTCLOSE 0x7 +#define MPTCP_SUBTYPE_MPCAPABLE 0x0 +#define MPTCP_SUBTYPE_MPJOIN 0x1 +#define MPTCP_SUBTYPE_DSS 0x2 +#define MPTCP_SUBTYPE_ADD_ADDR 0x3 +#define MPTCP_SUBTYPE_REM_ADDR 0x4 +#define MPTCP_SUBTYPE_MP_PRIO 0x5 +#define MPTCP_SUBTYPE_MP_FAIL 0x6 +#define MPTCP_SUBTYPE_MP_FASTCLOSE 0x7 /* * packet filter global read write lock @@ -213,9 +213,9 @@ pkt_mnglr_rw_unlock_shared(lck_rw_t *lck) */ static errno_t pkt_mnglr_ctl_connect(kern_ctl_ref kctlref, struct sockaddr_ctl *sac, - void **unitinfo) + void **unitinfo) { - errno_t error = 0; + errno_t error = 0; struct packet_mangler *p_pkt_mnglr = NULL; PKT_MNGLR_LOG(LOG_NOTICE, "Connecting packet mangler filter."); @@ -249,10 +249,11 @@ pkt_mnglr_ctl_connect(kern_ctl_ref kctlref, struct sockaddr_ctl *sac, goto done; } /* Another thread may have won the race */ - if (packet_manglers != NULL) + if (packet_manglers != NULL) { FREE(tmp, M_TEMP); - else + } else { packet_manglers = tmp; + } } if (sac->sc_unit == 0 || sac->sc_unit > MAX_PACKET_MANGLER) { @@ -292,24 +293,25 @@ pkt_mnglr_ctl_connect(kern_ctl_ref kctlref, struct sockaddr_ctl *sac, } PKT_MNGLR_LOG(LOG_INFO, "Registered packet mangler's IP Filters"); - p_pkt_mnglr->pkt_mnglr_flags |= PKT_MNGLR_FLG_IPFILTER_ATTACHED; + p_pkt_mnglr->pkt_mnglr_flags |= PKT_MNGLR_FLG_IPFILTER_ATTACHED; pkt_mnglr_rw_unlock_exclusive(&pkt_mnglr_lck_rw); done: - if (error != 0 && p_pkt_mnglr != NULL) + if (error != 0 && p_pkt_mnglr != NULL) { zfree(packet_mangler_zone, p_pkt_mnglr); + } PKT_MNGLR_LOG(LOG_INFO, "return %d pkt_mnglr_active_count %u kcunit %u", error, pkt_mnglr_active_count, sac->sc_unit); - return (error); + return error; } static errno_t pkt_mnglr_ctl_disconnect(kern_ctl_ref kctlref, u_int32_t kcunit, void *unitinfo) { #pragma unused(kctlref) - errno_t error = 0; + errno_t error = 0; struct packet_mangler *p_pkt_mnglr; PKT_MNGLR_LOG(LOG_INFO, "Disconnecting packet mangler kernel control"); @@ -355,15 +357,15 @@ done: PKT_MNGLR_LOG(LOG_INFO, "return %d pkt_mnglr_active_count %u kcunit %u", error, pkt_mnglr_active_count, kcunit); - return (error); + return error; } static errno_t pkt_mnglr_ctl_getopt(kern_ctl_ref kctlref, u_int32_t kcunit, void *unitinfo, - int opt, void *data, size_t *len) + int opt, void *data, size_t *len) { #pragma unused(kctlref, opt) - errno_t error = 0; + errno_t error = 0; struct packet_mangler *p_pkt_mnglr = (struct packet_mangler *)unitinfo; PKT_MNGLR_LOG(LOG_NOTICE, ""); @@ -388,128 +390,128 @@ pkt_mnglr_ctl_getopt(kern_ctl_ref kctlref, u_int32_t kcunit, void *unitinfo, goto done; } switch (opt) { - case PKT_MNGLR_OPT_PROTO_ACT_MASK: - if (*len < sizeof(uint32_t)) { - PKT_MNGLR_LOG(LOG_ERR, "PKT_MNGLR_OPT_PROTO_ACT_MASK " - "len too small %lu", *len); - error = EINVAL; - goto done; - } + case PKT_MNGLR_OPT_PROTO_ACT_MASK: + if (*len < sizeof(uint32_t)) { + PKT_MNGLR_LOG(LOG_ERR, "PKT_MNGLR_OPT_PROTO_ACT_MASK " + "len too small %lu", *len); + error = EINVAL; + goto done; + } - if (data != NULL) { - *(uint32_t *)data = p_pkt_mnglr->proto_action_mask; - } - break; - case PKT_MNGLR_OPT_IP_ACT_MASK: - if (*len < sizeof(uint32_t)) { - PKT_MNGLR_LOG(LOG_ERR, "PKT_MNGLR_OPT_IP_ACT_MASK " - "len too small %lu", *len); - error = EINVAL; - goto done; - } + if (data != NULL) { + *(uint32_t *)data = p_pkt_mnglr->proto_action_mask; + } + break; + case PKT_MNGLR_OPT_IP_ACT_MASK: + if (*len < sizeof(uint32_t)) { + PKT_MNGLR_LOG(LOG_ERR, "PKT_MNGLR_OPT_IP_ACT_MASK " + "len too small %lu", *len); + error = EINVAL; + goto done; + } - if (data != NULL) { - *(uint32_t *)data = p_pkt_mnglr->ip_action_mask; - } - break; - case PKT_MNGLR_OPT_LOCAL_IP: - if (*len < sizeof(struct sockaddr_storage)) { - PKT_MNGLR_LOG(LOG_ERR, "PKT_MNGLR_OPT_LOCAL_IP " - "len too small %lu", *len); - error = EINVAL; - goto done; - } + if (data != NULL) { + *(uint32_t *)data = p_pkt_mnglr->ip_action_mask; + } + break; + case PKT_MNGLR_OPT_LOCAL_IP: + if (*len < sizeof(struct sockaddr_storage)) { + PKT_MNGLR_LOG(LOG_ERR, "PKT_MNGLR_OPT_LOCAL_IP " + "len too small %lu", *len); + error = EINVAL; + goto done; + } - if (data != NULL) { - *(struct sockaddr_storage *)data = p_pkt_mnglr->lsaddr; - } - break; - case PKT_MNGLR_OPT_REMOTE_IP: - if (*len < sizeof(struct sockaddr_storage)) { - PKT_MNGLR_LOG(LOG_ERR, "PKT_MNGLR_OPT_REMOTE_IP " - "len too small %lu", *len); - error = EINVAL; - goto done; - } + if (data != NULL) { + *(struct sockaddr_storage *)data = p_pkt_mnglr->lsaddr; + } + break; + case PKT_MNGLR_OPT_REMOTE_IP: + if (*len < sizeof(struct sockaddr_storage)) { + PKT_MNGLR_LOG(LOG_ERR, "PKT_MNGLR_OPT_REMOTE_IP " + "len too small %lu", *len); + error = EINVAL; + goto done; + } - if (data != NULL) { - *(struct sockaddr_storage *)data = p_pkt_mnglr->rsaddr; - } - break; - case PKT_MNGLR_OPT_LOCAL_PORT: - if (*len < sizeof(uint16_t)) { - PKT_MNGLR_LOG(LOG_ERR, "PKT_MNGLR_OPT_LOCAL_PORT " - "len too small %lu", *len); - error = EINVAL; - goto done; - } + if (data != NULL) { + *(struct sockaddr_storage *)data = p_pkt_mnglr->rsaddr; + } + break; + case PKT_MNGLR_OPT_LOCAL_PORT: + if (*len < sizeof(uint16_t)) { + PKT_MNGLR_LOG(LOG_ERR, "PKT_MNGLR_OPT_LOCAL_PORT " + "len too small %lu", *len); + error = EINVAL; + goto done; + } - if (data != NULL) { - *(uint16_t *)data = p_pkt_mnglr->lport; - } - break; - case PKT_MNGLR_OPT_REMOTE_PORT: - if (*len < sizeof(uint16_t)) { - PKT_MNGLR_LOG(LOG_ERR, "PKT_MNGLR_OPT_REMOTE_PORT " - "len too small %lu", *len); - error = EINVAL; - goto done; - } + if (data != NULL) { + *(uint16_t *)data = p_pkt_mnglr->lport; + } + break; + case PKT_MNGLR_OPT_REMOTE_PORT: + if (*len < sizeof(uint16_t)) { + PKT_MNGLR_LOG(LOG_ERR, "PKT_MNGLR_OPT_REMOTE_PORT " + "len too small %lu", *len); + error = EINVAL; + goto done; + } - if (data != NULL) { - *(uint16_t *)data = p_pkt_mnglr->rport; - } - break; - case PKT_MNGLR_OPT_DIRECTION: - if (*len < sizeof(uint32_t)) { - PKT_MNGLR_LOG(LOG_ERR, "PKT_MNGLR_OPT_DIRECTION " - "len too small %lu", *len); - error = EINVAL; - goto done; - } - if (data != NULL) { - *(uint32_t *)data = p_pkt_mnglr->dir; - } - break; - case PKT_MNGLR_OPT_PROTOCOL: - if (*len < sizeof(uint32_t)) { - PKT_MNGLR_LOG(LOG_ERR, "PKT_MNGLR_OPT_PROTOCOL " - "len too small %lu", *len); - error = EINVAL; - goto done; - } - if (data != NULL) { - *(uint32_t *)data = p_pkt_mnglr->proto; - } - break; - case PKT_MNGLR_OPT_ACTIVATE: - if (*len < sizeof(uint8_t)) { - PKT_MNGLR_LOG(LOG_ERR, "PKT_MNGLR_OPT_ACTIVATE " - "len too small %lu", *len); - error = EINVAL; - goto done; - } + if (data != NULL) { + *(uint16_t *)data = p_pkt_mnglr->rport; + } + break; + case PKT_MNGLR_OPT_DIRECTION: + if (*len < sizeof(uint32_t)) { + PKT_MNGLR_LOG(LOG_ERR, "PKT_MNGLR_OPT_DIRECTION " + "len too small %lu", *len); + error = EINVAL; + goto done; + } + if (data != NULL) { + *(uint32_t *)data = p_pkt_mnglr->dir; + } + break; + case PKT_MNGLR_OPT_PROTOCOL: + if (*len < sizeof(uint32_t)) { + PKT_MNGLR_LOG(LOG_ERR, "PKT_MNGLR_OPT_PROTOCOL " + "len too small %lu", *len); + error = EINVAL; + goto done; + } + if (data != NULL) { + *(uint32_t *)data = p_pkt_mnglr->proto; + } + break; + case PKT_MNGLR_OPT_ACTIVATE: + if (*len < sizeof(uint8_t)) { + PKT_MNGLR_LOG(LOG_ERR, "PKT_MNGLR_OPT_ACTIVATE " + "len too small %lu", *len); + error = EINVAL; + goto done; + } - if (data != NULL) { - *(uint8_t *)data = p_pkt_mnglr->activate; - } - break; - default: - error = ENOPROTOOPT; - break; + if (data != NULL) { + *(uint8_t *)data = p_pkt_mnglr->activate; + } + break; + default: + error = ENOPROTOOPT; + break; } done: pkt_mnglr_rw_unlock_shared(&pkt_mnglr_lck_rw); - return (error); + return error; } static errno_t pkt_mnglr_ctl_setopt(kern_ctl_ref kctlref, u_int32_t kcunit, void *unitinfo, - int opt, void *data, size_t len) + int opt, void *data, size_t len) { #pragma unused(kctlref, opt) - errno_t error = 0; + errno_t error = 0; struct packet_mangler *p_pkt_mnglr = (struct packet_mangler *)unitinfo; PKT_MNGLR_LOG(LOG_NOTICE, ""); @@ -534,170 +536,170 @@ pkt_mnglr_ctl_setopt(kern_ctl_ref kctlref, u_int32_t kcunit, void *unitinfo, goto done; } switch (opt) { - case PKT_MNGLR_OPT_PROTO_ACT_MASK: - if (len < sizeof(uint32_t)) { - PKT_MNGLR_LOG(LOG_ERR, "PKT_MNGLR_OPT_PROTO_ACT_MASK " - "len too small %lu", len); - error = EINVAL; - goto done; - } - if (p_pkt_mnglr->proto_action_mask != 0) { - PKT_MNGLR_LOG(LOG_ERR, "PKT_MNGLR_OPT_PROTO_ACT_MASK " - "already set %u", - p_pkt_mnglr->proto_action_mask); - error = EINVAL; - goto done; - } - p_pkt_mnglr->proto_action_mask = *(uint32_t *)data; - PKT_MNGLR_LOG(LOG_INFO, "p_pkt_mnglr->proto_action_mask set to :%d", p_pkt_mnglr->proto_action_mask); - break; - case PKT_MNGLR_OPT_IP_ACT_MASK: - if (len < sizeof(uint32_t)) { - PKT_MNGLR_LOG(LOG_ERR, "PKT_MNGLR_OPT_IP_ACT_MASK " - "len too small %lu", len); - error = EINVAL; - goto done; - } - if (p_pkt_mnglr->ip_action_mask != 0) { - PKT_MNGLR_LOG(LOG_ERR, "PKT_MNGLR_OPT_IP_ACT_MASK " - "already set %u", - p_pkt_mnglr->ip_action_mask); - error = EINVAL; - goto done; - } - p_pkt_mnglr->ip_action_mask = *(uint32_t *)data; - break; - case PKT_MNGLR_OPT_LOCAL_IP: - if (len < sizeof(struct sockaddr_storage)) { - PKT_MNGLR_LOG(LOG_ERR, "PKT_MNGLR_OPT_LOCAL_IP " - "len too small %lu", len); - error = EINVAL; - goto done; - } - if (p_pkt_mnglr->lsaddr.ss_family) { - PKT_MNGLR_LOG(LOG_ERR, "PKT_MNGLR_OPT_LOCAL_IP " - "already set"); - error = EINVAL; - goto done; - } - p_pkt_mnglr->lsaddr = *(struct sockaddr_storage *)data; - break; - case PKT_MNGLR_OPT_REMOTE_IP: - if (len < sizeof(struct sockaddr_storage)) { - PKT_MNGLR_LOG(LOG_ERR, "PKT_MNGLR_OPT_REMOTE_IP " - "len too small %lu", len); - error = EINVAL; - goto done; - } - if (p_pkt_mnglr->rsaddr.ss_family) { - PKT_MNGLR_LOG(LOG_ERR, "PKT_MNGLR_OPT_REMOTE_IP " - "already set"); - error = EINVAL; - goto done; - } + case PKT_MNGLR_OPT_PROTO_ACT_MASK: + if (len < sizeof(uint32_t)) { + PKT_MNGLR_LOG(LOG_ERR, "PKT_MNGLR_OPT_PROTO_ACT_MASK " + "len too small %lu", len); + error = EINVAL; + goto done; + } + if (p_pkt_mnglr->proto_action_mask != 0) { + PKT_MNGLR_LOG(LOG_ERR, "PKT_MNGLR_OPT_PROTO_ACT_MASK " + "already set %u", + p_pkt_mnglr->proto_action_mask); + error = EINVAL; + goto done; + } + p_pkt_mnglr->proto_action_mask = *(uint32_t *)data; + PKT_MNGLR_LOG(LOG_INFO, "p_pkt_mnglr->proto_action_mask set to :%d", p_pkt_mnglr->proto_action_mask); + break; + case PKT_MNGLR_OPT_IP_ACT_MASK: + if (len < sizeof(uint32_t)) { + PKT_MNGLR_LOG(LOG_ERR, "PKT_MNGLR_OPT_IP_ACT_MASK " + "len too small %lu", len); + error = EINVAL; + goto done; + } + if (p_pkt_mnglr->ip_action_mask != 0) { + PKT_MNGLR_LOG(LOG_ERR, "PKT_MNGLR_OPT_IP_ACT_MASK " + "already set %u", + p_pkt_mnglr->ip_action_mask); + error = EINVAL; + goto done; + } + p_pkt_mnglr->ip_action_mask = *(uint32_t *)data; + break; + case PKT_MNGLR_OPT_LOCAL_IP: + if (len < sizeof(struct sockaddr_storage)) { + PKT_MNGLR_LOG(LOG_ERR, "PKT_MNGLR_OPT_LOCAL_IP " + "len too small %lu", len); + error = EINVAL; + goto done; + } + if (p_pkt_mnglr->lsaddr.ss_family) { + PKT_MNGLR_LOG(LOG_ERR, "PKT_MNGLR_OPT_LOCAL_IP " + "already set"); + error = EINVAL; + goto done; + } + p_pkt_mnglr->lsaddr = *(struct sockaddr_storage *)data; + break; + case PKT_MNGLR_OPT_REMOTE_IP: + if (len < sizeof(struct sockaddr_storage)) { + PKT_MNGLR_LOG(LOG_ERR, "PKT_MNGLR_OPT_REMOTE_IP " + "len too small %lu", len); + error = EINVAL; + goto done; + } + if (p_pkt_mnglr->rsaddr.ss_family) { + PKT_MNGLR_LOG(LOG_ERR, "PKT_MNGLR_OPT_REMOTE_IP " + "already set"); + error = EINVAL; + goto done; + } - p_pkt_mnglr->rsaddr = *(struct sockaddr_storage *)data; - PKT_MNGLR_LOG(LOG_INFO, - "Remote IP registered for address family: %d", - p_pkt_mnglr->rsaddr.ss_family); - break; - case PKT_MNGLR_OPT_LOCAL_PORT: - if (len < sizeof(uint16_t)) { - PKT_MNGLR_LOG(LOG_ERR, "PKT_MNGLR_OPT_LOCAL_PORT " - "len too small %lu", len); - error = EINVAL; - goto done; - } - if (p_pkt_mnglr->lport != 0) { - PKT_MNGLR_LOG(LOG_ERR, "PKT_MNGLR_OPT_LOCAL_PORT " - "already set %d", - p_pkt_mnglr->lport); - error = EINVAL; - goto done; - } - p_pkt_mnglr->lport = *(uint16_t *)data; - break; - case PKT_MNGLR_OPT_REMOTE_PORT: - if (len < sizeof(uint16_t)) { - PKT_MNGLR_LOG(LOG_ERR, "PKT_MNGLR_OPT_REMOTE_PORT " - "len too small %lu", len); - error = EINVAL; - goto done; - } - if (p_pkt_mnglr->rport != 0) { - PKT_MNGLR_LOG(LOG_ERR, "PKT_MNGLR_OPT_REMOTE_PORT " - "already set %d", - p_pkt_mnglr->rport); - error = EINVAL; - goto done; - } - p_pkt_mnglr->rport = *(uint16_t *)data; - break; - case PKT_MNGLR_OPT_DIRECTION: - if (len < sizeof(uint32_t)) { - PKT_MNGLR_LOG(LOG_ERR, "PKT_MNGLR_OPT_DIRECTION " - "len too small %lu", len); - error = EINVAL; - goto done; - } - if (p_pkt_mnglr->dir != 0) { - PKT_MNGLR_LOG(LOG_ERR, "PKT_MNGLR_OPT_DIRECTION " - "already set %u", - p_pkt_mnglr->dir); - error = EINVAL; - goto done; - } - p_pkt_mnglr->dir = *(uint32_t *)data; - break; - case PKT_MNGLR_OPT_PROTOCOL: - if (len < sizeof(uint32_t)) { - PKT_MNGLR_LOG(LOG_ERR, "PKT_MNGLR_OPT_PROTOCOL " - "len too small %lu", len); - error = EINVAL; - goto done; - } - if (p_pkt_mnglr->proto != 0) { - PKT_MNGLR_LOG(LOG_ERR, "PKT_MNGLR_OPT_PROTOCOL " - "already set %u", - p_pkt_mnglr->proto); - error = EINVAL; - goto done; - } - p_pkt_mnglr->proto = *(uint32_t *)data; - break; - case PKT_MNGLR_OPT_ACTIVATE: - if (len < sizeof(uint8_t)) { - PKT_MNGLR_LOG(LOG_ERR, "PKT_MNGLR_OPT_ACTIVATE " - "len too small %lu", len); - error = EINVAL; - goto done; - } - if (p_pkt_mnglr->activate != 0) { - PKT_MNGLR_LOG(LOG_ERR, "PKT_MNGLR_OPT_ACTIVATE " - "already set %u", - p_pkt_mnglr->activate); - error = EINVAL; - goto done; - } - p_pkt_mnglr->activate = *(uint8_t *)data; - PKT_MNGLR_LOG(LOG_ERR, "p_pkt_mnglr->activate set to :%d", + p_pkt_mnglr->rsaddr = *(struct sockaddr_storage *)data; + PKT_MNGLR_LOG(LOG_INFO, + "Remote IP registered for address family: %d", + p_pkt_mnglr->rsaddr.ss_family); + break; + case PKT_MNGLR_OPT_LOCAL_PORT: + if (len < sizeof(uint16_t)) { + PKT_MNGLR_LOG(LOG_ERR, "PKT_MNGLR_OPT_LOCAL_PORT " + "len too small %lu", len); + error = EINVAL; + goto done; + } + if (p_pkt_mnglr->lport != 0) { + PKT_MNGLR_LOG(LOG_ERR, "PKT_MNGLR_OPT_LOCAL_PORT " + "already set %d", + p_pkt_mnglr->lport); + error = EINVAL; + goto done; + } + p_pkt_mnglr->lport = *(uint16_t *)data; + break; + case PKT_MNGLR_OPT_REMOTE_PORT: + if (len < sizeof(uint16_t)) { + PKT_MNGLR_LOG(LOG_ERR, "PKT_MNGLR_OPT_REMOTE_PORT " + "len too small %lu", len); + error = EINVAL; + goto done; + } + if (p_pkt_mnglr->rport != 0) { + PKT_MNGLR_LOG(LOG_ERR, "PKT_MNGLR_OPT_REMOTE_PORT " + "already set %d", + p_pkt_mnglr->rport); + error = EINVAL; + goto done; + } + p_pkt_mnglr->rport = *(uint16_t *)data; + break; + case PKT_MNGLR_OPT_DIRECTION: + if (len < sizeof(uint32_t)) { + PKT_MNGLR_LOG(LOG_ERR, "PKT_MNGLR_OPT_DIRECTION " + "len too small %lu", len); + error = EINVAL; + goto done; + } + if (p_pkt_mnglr->dir != 0) { + PKT_MNGLR_LOG(LOG_ERR, "PKT_MNGLR_OPT_DIRECTION " + "already set %u", + p_pkt_mnglr->dir); + error = EINVAL; + goto done; + } + p_pkt_mnglr->dir = *(uint32_t *)data; + break; + case PKT_MNGLR_OPT_PROTOCOL: + if (len < sizeof(uint32_t)) { + PKT_MNGLR_LOG(LOG_ERR, "PKT_MNGLR_OPT_PROTOCOL " + "len too small %lu", len); + error = EINVAL; + goto done; + } + if (p_pkt_mnglr->proto != 0) { + PKT_MNGLR_LOG(LOG_ERR, "PKT_MNGLR_OPT_PROTOCOL " + "already set %u", + p_pkt_mnglr->proto); + error = EINVAL; + goto done; + } + p_pkt_mnglr->proto = *(uint32_t *)data; + break; + case PKT_MNGLR_OPT_ACTIVATE: + if (len < sizeof(uint8_t)) { + PKT_MNGLR_LOG(LOG_ERR, "PKT_MNGLR_OPT_ACTIVATE " + "len too small %lu", len); + error = EINVAL; + goto done; + } + if (p_pkt_mnglr->activate != 0) { + PKT_MNGLR_LOG(LOG_ERR, "PKT_MNGLR_OPT_ACTIVATE " + "already set %u", p_pkt_mnglr->activate); - break; - default: - error = ENOPROTOOPT; - break; + error = EINVAL; + goto done; + } + p_pkt_mnglr->activate = *(uint8_t *)data; + PKT_MNGLR_LOG(LOG_ERR, "p_pkt_mnglr->activate set to :%d", + p_pkt_mnglr->activate); + break; + default: + error = ENOPROTOOPT; + break; } done: pkt_mnglr_rw_unlock_exclusive(&pkt_mnglr_lck_rw); - return (error); + return error; } void pkt_mnglr_init(void) { struct kern_ctl_reg kern_ctl; - errno_t error = 0; + errno_t error = 0; vm_size_t pkt_mnglr_size = 0; PKT_MNGLR_LOG(LOG_NOTICE, ""); @@ -764,7 +766,8 @@ pkt_mnglr_init(void) } } -static errno_t pktmnglr_ipfilter_output(void *cookie, mbuf_t *data, ipf_pktopts_t options) +static errno_t +pktmnglr_ipfilter_output(void *cookie, mbuf_t *data, ipf_pktopts_t options) { struct packet_mangler *p_pkt_mnglr = (struct packet_mangler *)cookie; struct ip ip; @@ -831,9 +834,10 @@ output_done: return 0; } -#define TCP_MAX_OPTLEN 40 +#define TCP_MAX_OPTLEN 40 -static errno_t pktmnglr_ipfilter_input(void *cookie, mbuf_t *data, int offset, u_int8_t protocol) +static errno_t +pktmnglr_ipfilter_input(void *cookie, mbuf_t *data, int offset, u_int8_t protocol) { struct packet_mangler *p_pkt_mnglr = (struct packet_mangler *)cookie; struct ip ip; @@ -908,36 +912,36 @@ static errno_t pktmnglr_ipfilter_input(void *cookie, mbuf_t *data, int offset, u } switch (protocol) { - case IPPROTO_TCP: - if (ip_pld_len < (int) sizeof(tcp)) { - PKT_MNGLR_LOG(LOG_ERR, "IP total len not big enough for TCP: %d", ip_pld_len); - goto drop_it; - } - - error = mbuf_copydata(*data, offset, sizeof(tcp), &tcp); - if (error) { - PKT_MNGLR_LOG(LOG_ERR, "Could not make local TCP header copy"); - goto input_done; - } - - if (p_pkt_mnglr->lport && (p_pkt_mnglr->lport != tcp.th_dport)) { - PKT_MNGLR_LOG(LOG_INFO, "Local port and IP des port do not match"); - goto input_done; - } + case IPPROTO_TCP: + if (ip_pld_len < (int) sizeof(tcp)) { + PKT_MNGLR_LOG(LOG_ERR, "IP total len not big enough for TCP: %d", ip_pld_len); + goto drop_it; + } - if (p_pkt_mnglr->rport && (p_pkt_mnglr->rport != tcp.th_sport)) { - PKT_MNGLR_LOG(LOG_INFO, "Remote port and IP src port do not match"); - goto input_done; - } - break; - case IPPROTO_UDP: + error = mbuf_copydata(*data, offset, sizeof(tcp), &tcp); + if (error) { + PKT_MNGLR_LOG(LOG_ERR, "Could not make local TCP header copy"); goto input_done; - case IPPROTO_ICMP: - goto input_done; - case IPPROTO_ICMPV6: + } + + if (p_pkt_mnglr->lport && (p_pkt_mnglr->lport != tcp.th_dport)) { + PKT_MNGLR_LOG(LOG_INFO, "Local port and IP des port do not match"); goto input_done; - default: + } + + if (p_pkt_mnglr->rport && (p_pkt_mnglr->rport != tcp.th_sport)) { + PKT_MNGLR_LOG(LOG_INFO, "Remote port and IP src port do not match"); goto input_done; + } + break; + case IPPROTO_UDP: + goto input_done; + case IPPROTO_ICMP: + goto input_done; + case IPPROTO_ICMPV6: + goto input_done; + default: + goto input_done; } /* XXX Do IP actions here */ @@ -945,106 +949,106 @@ static errno_t pktmnglr_ipfilter_input(void *cookie, mbuf_t *data, int offset, u /* Protocol actions */ switch (protocol) { - case IPPROTO_TCP: - if (p_pkt_mnglr->proto_action_mask) { - char tcp_opt_buf[TCP_MAX_OPTLEN] = {0}; - int orig_tcp_optlen; - int tcp_optlen = 0; - int i = 0, off; - - off = (tcp.th_off << 2); - - if (off < (int) sizeof(struct tcphdr) || off > ip_pld_len) { - PKT_MNGLR_LOG(LOG_ERR, "TCP header offset is wrong: %d", off); - goto drop_it; - } + case IPPROTO_TCP: + if (p_pkt_mnglr->proto_action_mask) { + char tcp_opt_buf[TCP_MAX_OPTLEN] = {0}; + int orig_tcp_optlen; + int tcp_optlen = 0; + int i = 0, off; + off = (tcp.th_off << 2); - tcp_optlen = off - sizeof(struct tcphdr); + if (off < (int) sizeof(struct tcphdr) || off > ip_pld_len) { + PKT_MNGLR_LOG(LOG_ERR, "TCP header offset is wrong: %d", off); + goto drop_it; + } - PKT_MNGLR_LOG(LOG_INFO, "Packet from F5 is TCP\n"); - PKT_MNGLR_LOG(LOG_INFO, "Optlen: %d\n", tcp_optlen); - orig_tcp_optlen = tcp_optlen; - if (orig_tcp_optlen) { - error = mbuf_copydata(*data, offset+sizeof(struct tcphdr), orig_tcp_optlen, tcp_opt_buf); - if (error) { - PKT_MNGLR_LOG(LOG_ERR, "Failed to copy tcp options: error %d offset %d optlen %d", error, offset, orig_tcp_optlen); - goto input_done; - } + + tcp_optlen = off - sizeof(struct tcphdr); + + PKT_MNGLR_LOG(LOG_INFO, "Packet from F5 is TCP\n"); + PKT_MNGLR_LOG(LOG_INFO, "Optlen: %d\n", tcp_optlen); + orig_tcp_optlen = tcp_optlen; + if (orig_tcp_optlen) { + error = mbuf_copydata(*data, offset + sizeof(struct tcphdr), orig_tcp_optlen, tcp_opt_buf); + if (error) { + PKT_MNGLR_LOG(LOG_ERR, "Failed to copy tcp options: error %d offset %d optlen %d", error, offset, orig_tcp_optlen); + goto input_done; } + } - while (tcp_optlen > 0) { - if (tcp_opt_buf[i] == 0x1) { - PKT_MNGLR_LOG(LOG_INFO, "Skipping NOP\n"); - tcp_optlen--; - i++; - continue; - } else if ((tcp_opt_buf[i] != 0) && (tcp_opt_buf[i] != TCP_OPT_MULTIPATH_TCP)) { - PKT_MNGLR_LOG(LOG_INFO, "Skipping option %x\n", tcp_opt_buf[i]); - - /* Minimum TCP option size is 2 */ - if (tcp_opt_buf[i+1] < 2) { - PKT_MNGLR_LOG(LOG_ERR, "Received suspicious TCP option"); + while (tcp_optlen > 0) { + if (tcp_opt_buf[i] == 0x1) { + PKT_MNGLR_LOG(LOG_INFO, "Skipping NOP\n"); + tcp_optlen--; + i++; + continue; + } else if ((tcp_opt_buf[i] != 0) && (tcp_opt_buf[i] != TCP_OPT_MULTIPATH_TCP)) { + PKT_MNGLR_LOG(LOG_INFO, "Skipping option %x\n", tcp_opt_buf[i]); + + /* Minimum TCP option size is 2 */ + if (tcp_opt_buf[i + 1] < 2) { + PKT_MNGLR_LOG(LOG_ERR, "Received suspicious TCP option"); + goto drop_it; + } + tcp_optlen -= tcp_opt_buf[i + 1]; + i += tcp_opt_buf[i + 1]; + continue; + } else if (tcp_opt_buf[i] == TCP_OPT_MULTIPATH_TCP) { + int j = 0; + unsigned char mptcpoptlen = tcp_opt_buf[i + 1]; + uint8_t sbtver = tcp_opt_buf[i + MPTCP_SBT_VER_OFFSET]; + uint8_t subtype = sbtver >> 4; + + PKT_MNGLR_LOG(LOG_INFO, "Got MPTCP option %x\n", tcp_opt_buf[i]); + PKT_MNGLR_LOG(LOG_INFO, "Got MPTCP subtype %x\n", subtype); + if (subtype == MPTCP_SUBTYPE_DSS) { + PKT_MNGLR_LOG(LOG_INFO, "Got DSS option\n"); + PKT_MNGLR_LOG(LOG_INFO, "Protocol option mask: %d\n", p_pkt_mnglr->proto_action_mask); + if (p_pkt_mnglr->proto_action_mask & + PKT_MNGLR_TCP_ACT_DSS_DROP) { goto drop_it; } - tcp_optlen -= tcp_opt_buf[i+1]; - i += tcp_opt_buf[i+1]; - continue; - } else if (tcp_opt_buf[i] == TCP_OPT_MULTIPATH_TCP) { - int j = 0; - unsigned char mptcpoptlen = tcp_opt_buf[i+1]; - uint8_t sbtver = tcp_opt_buf[i+MPTCP_SBT_VER_OFFSET]; - uint8_t subtype = sbtver >> 4; - - PKT_MNGLR_LOG(LOG_INFO, "Got MPTCP option %x\n", tcp_opt_buf[i]); - PKT_MNGLR_LOG(LOG_INFO, "Got MPTCP subtype %x\n", subtype); - if (subtype == MPTCP_SUBTYPE_DSS) { - PKT_MNGLR_LOG(LOG_INFO, "Got DSS option\n"); - PKT_MNGLR_LOG(LOG_INFO, "Protocol option mask: %d\n", p_pkt_mnglr->proto_action_mask); - if (p_pkt_mnglr->proto_action_mask & - PKT_MNGLR_TCP_ACT_DSS_DROP) { - goto drop_it; - } - } + } - PKT_MNGLR_LOG(LOG_INFO, "Got MPTCP option %x\n", tcp_opt_buf[i]); - for (; j < mptcpoptlen && j < tcp_optlen; j++) { - if (p_pkt_mnglr->proto_action_mask & - PKT_MNGLR_TCP_ACT_NOP_MPTCP) { - tcp_opt_buf[i+j] = 0x1; - } + PKT_MNGLR_LOG(LOG_INFO, "Got MPTCP option %x\n", tcp_opt_buf[i]); + for (; j < mptcpoptlen && j < tcp_optlen; j++) { + if (p_pkt_mnglr->proto_action_mask & + PKT_MNGLR_TCP_ACT_NOP_MPTCP) { + tcp_opt_buf[i + j] = 0x1; } - tcp_optlen -= mptcpoptlen; - i += mptcpoptlen; - } else { - tcp_optlen--; - i++; } + tcp_optlen -= mptcpoptlen; + i += mptcpoptlen; + } else { + tcp_optlen--; + i++; } + } - if (orig_tcp_optlen) { - error = mbuf_copyback(*data, - offset+sizeof(struct tcphdr), - orig_tcp_optlen, tcp_opt_buf, MBUF_WAITOK); + if (orig_tcp_optlen) { + error = mbuf_copyback(*data, + offset + sizeof(struct tcphdr), + orig_tcp_optlen, tcp_opt_buf, MBUF_WAITOK); - if (error) { - PKT_MNGLR_LOG(LOG_ERR, - "Failed to copy tcp options back: error %d offset %d optlen %d", - error, offset, orig_tcp_optlen); - goto input_done; - } + if (error) { + PKT_MNGLR_LOG(LOG_ERR, + "Failed to copy tcp options back: error %d offset %d optlen %d", + error, offset, orig_tcp_optlen); + goto input_done; } } - break; - case IPPROTO_UDP: - /* Don't handle UDP */ - break; - case IPPROTO_ICMP: - break; - case IPPROTO_ICMPV6: - break; - default: - break; + } + break; + case IPPROTO_UDP: + /* Don't handle UDP */ + break; + case IPPROTO_ICMP: + break; + case IPPROTO_ICMPV6: + break; + default: + break; } chksm_update(*data); input_done: @@ -1056,14 +1060,16 @@ drop_it: return EJUSTRETURN; } -static void pktmnglr_ipfilter_detach(void *cookie) +static void +pktmnglr_ipfilter_detach(void *cookie) { #pragma unused(cookie) return; } /* XXX Still need to modify this to use mbuf_copy* macros */ -static void chksm_update(mbuf_t data) +static void +chksm_update(mbuf_t data) { u_int16_t ip_sum; u_int16_t tsum; @@ -1078,26 +1084,28 @@ static void chksm_update(mbuf_t data) ip->ip_sum = 0; err = mbuf_inet_cksum(data, 0, 0, ip->ip_hl << 2, &ip_sum); // ip sum - if (err == 0) + if (err == 0) { ip->ip_sum = ip_sum; + } switch (ip->ip_p) { - case IPPROTO_TCP: - tcp = (struct tcphdr *)(void *)(ptr + (ip->ip_hl << 2)); - tcp->th_sum = 0; - err = mbuf_inet_cksum(data, IPPROTO_TCP, ip->ip_hl << 2, - ntohs(ip->ip_len) - (ip->ip_hl << 2), &tsum); - if (err == 0) - tcp->th_sum = tsum; - break; - case IPPROTO_UDP: - /* Don't handle UDP */ - break; - case IPPROTO_ICMP: - break; - case IPPROTO_ICMPV6: - break; - default: - break; + case IPPROTO_TCP: + tcp = (struct tcphdr *)(void *)(ptr + (ip->ip_hl << 2)); + tcp->th_sum = 0; + err = mbuf_inet_cksum(data, IPPROTO_TCP, ip->ip_hl << 2, + ntohs(ip->ip_len) - (ip->ip_hl << 2), &tsum); + if (err == 0) { + tcp->th_sum = tsum; + } + break; + case IPPROTO_UDP: + /* Don't handle UDP */ + break; + case IPPROTO_ICMP: + break; + case IPPROTO_ICMPV6: + break; + default: + break; } mbuf_clear_csum_performed(data);