#include <string.h>
#include <libkern/libkern.h>
-#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;
/* 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];
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
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
*/
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.");
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) {
}
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");
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, "");
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, "");
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, "");
}
}
-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;
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;
}
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 */
/* 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:
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;
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);