Beispiel #1
0
void
key_setsadbsens(void)
{
	struct sadb_sens m_sens;
	u_char buf[64];
	u_int s, i, slen, ilen, len;

	/* make sens & integ */
	s = htonl(0x01234567);
	i = htonl(0x89abcdef);
	slen = sizeof(s);
	ilen = sizeof(i);
	memcpy(buf, &s, slen);
	memcpy(buf + slen, &i, ilen);

	len = sizeof(m_sens) + PFKEY_ALIGN8(slen) + PFKEY_ALIGN8(ilen);
	m_sens.sadb_sens_len = PFKEY_UNIT64(len);
	m_sens.sadb_sens_exttype = SADB_EXT_SENSITIVITY;
	m_sens.sadb_sens_dpd = 1;
	m_sens.sadb_sens_sens_level = 2;
	m_sens.sadb_sens_sens_len = PFKEY_ALIGN8(slen);
	m_sens.sadb_sens_integ_level = 3;
	m_sens.sadb_sens_integ_len = PFKEY_ALIGN8(ilen);
	m_sens.sadb_sens_reserved = 0;

	key_setsadbextbuf(m_buf, m_len,
			(caddr_t)&m_sens, sizeof(struct sadb_sens),
			buf, slen + ilen);
	m_len += len;
}
Beispiel #2
0
void
key_setsadbprop(void)
{
	struct sadb_prop m_prop;
	struct sadb_comb *m_comb;
	u_char buf[256];
	u_int len = sizeof(m_prop) + sizeof(m_comb) * 2;

	/* make prop & comb */
	m_prop.sadb_prop_len = PFKEY_UNIT64(len);
	m_prop.sadb_prop_exttype = SADB_EXT_PROPOSAL;
	m_prop.sadb_prop_replay = 0;
	m_prop.sadb_prop_reserved[0] = 0;
	m_prop.sadb_prop_reserved[1] = 0;
	m_prop.sadb_prop_reserved[2] = 0;

	/* the 1st is ESP DES-CBC HMAC-MD5 */
	m_comb = (struct sadb_comb *)buf;
	m_comb->sadb_comb_auth = SADB_AALG_MD5HMAC;
	m_comb->sadb_comb_encrypt = SADB_EALG_DESCBC;
	m_comb->sadb_comb_flags = 0;
	m_comb->sadb_comb_auth_minbits = 8;
	m_comb->sadb_comb_auth_maxbits = 96;
	m_comb->sadb_comb_encrypt_minbits = 64;
	m_comb->sadb_comb_encrypt_maxbits = 64;
	m_comb->sadb_comb_reserved = 0;
	m_comb->sadb_comb_soft_allocations = 0;
	m_comb->sadb_comb_hard_allocations = 0;
	m_comb->sadb_comb_soft_bytes = 0;
	m_comb->sadb_comb_hard_bytes = 0;
	m_comb->sadb_comb_soft_addtime = 0;
	m_comb->sadb_comb_hard_addtime = 0;
	m_comb->sadb_comb_soft_usetime = 0;
	m_comb->sadb_comb_hard_usetime = 0;

	/* the 2st is ESP 3DES-CBC and AH HMAC-SHA1 */
	m_comb = (struct sadb_comb *)(buf + sizeof(*m_comb));
	m_comb->sadb_comb_auth = SADB_AALG_SHA1HMAC;
	m_comb->sadb_comb_encrypt = SADB_EALG_3DESCBC;
	m_comb->sadb_comb_flags = 0;
	m_comb->sadb_comb_auth_minbits = 8;
	m_comb->sadb_comb_auth_maxbits = 96;
	m_comb->sadb_comb_encrypt_minbits = 64;
	m_comb->sadb_comb_encrypt_maxbits = 64;
	m_comb->sadb_comb_reserved = 0;
	m_comb->sadb_comb_soft_allocations = 0;
	m_comb->sadb_comb_hard_allocations = 0;
	m_comb->sadb_comb_soft_bytes = 0;
	m_comb->sadb_comb_hard_bytes = 0;
	m_comb->sadb_comb_soft_addtime = 0;
	m_comb->sadb_comb_hard_addtime = 0;
	m_comb->sadb_comb_soft_usetime = 0;
	m_comb->sadb_comb_hard_usetime = 0;

	key_setsadbextbuf(m_buf, m_len,
			(caddr_t)&m_prop, sizeof(struct sadb_prop),
			buf, sizeof(*m_comb) * 2);
	m_len += len;
}
Beispiel #3
0
void
key_setspirange(void)
{
	struct sadb_spirange m_spi;

	m_spi.sadb_spirange_len = PFKEY_UNIT64(sizeof(m_spi));
	m_spi.sadb_spirange_exttype = SADB_EXT_SPIRANGE;
	m_spi.sadb_spirange_min = 0x00001000;
	m_spi.sadb_spirange_max = 0x00002000;
	m_spi.sadb_spirange_reserved = 0;

	memcpy(m_buf + m_len, &m_spi, sizeof(struct sadb_spirange));
	m_len += sizeof(struct sadb_spirange);
}
Beispiel #4
0
void
key_setsadblft(u_int ext, u_int time)
{
	struct sadb_lifetime m_lft;

	m_lft.sadb_lifetime_len = PFKEY_UNIT64(sizeof(m_lft));
	m_lft.sadb_lifetime_exttype = ext;
	m_lft.sadb_lifetime_allocations = 0x2;
	m_lft.sadb_lifetime_bytes = 0x1000;
	m_lft.sadb_lifetime_addtime = time;
	m_lft.sadb_lifetime_usetime = 0x0020;

	memcpy(m_buf + m_len, &m_lft, sizeof(struct sadb_lifetime));
	m_len += sizeof(struct sadb_lifetime);
}
Beispiel #5
0
static void
sendkeyshort(u_int type)
{
	struct sadb_msg msg;

	msg.sadb_msg_version = PF_KEY_V2;
	msg.sadb_msg_type = type;
	msg.sadb_msg_errno = 0;
	msg.sadb_msg_satype = SADB_SATYPE_UNSPEC;
	msg.sadb_msg_len = PFKEY_UNIT64(sizeof(msg));
	msg.sadb_msg_reserved = 0;
	msg.sadb_msg_seq = 0;
	msg.sadb_msg_pid = getpid();

	sendkeymsg((char *)&msg, sizeof(msg));
}
Beispiel #6
0
void
key_setsadbaddr(u_int ext, u_int af, caddr_t str)
{
	struct sadb_address m_addr;
	u_int len;
	struct addrinfo hints, *res;
	const char *serv;
	int plen;

	switch (af) {
	case AF_INET:
		plen = sizeof(struct in_addr) << 3;
		break;
	case AF_INET6:
		plen = sizeof(struct in6_addr) << 3;
		break;
	default:
		/* XXX bark */
		exit(1);
	}

	/* make sockaddr buffer */
	memset(&hints, 0, sizeof(hints));
	hints.ai_family = af;
	hints.ai_socktype = SOCK_DGRAM;	/*dummy*/
	hints.ai_flags = AI_NUMERICHOST;
	serv = (ext == SADB_EXT_ADDRESS_PROXY ? "0" : "4660");	/*0x1234*/
	if (getaddrinfo(str, serv, &hints, &res) != 0 || res->ai_next) {
		/* XXX bark */
		exit(1);
	}
	
	len = sizeof(struct sadb_address) + PFKEY_ALIGN8(res->ai_addrlen);
	m_addr.sadb_address_len = PFKEY_UNIT64(len);
	m_addr.sadb_address_exttype = ext;
	m_addr.sadb_address_proto =
		(ext == SADB_EXT_ADDRESS_PROXY ? 0 : IPPROTO_TCP);
	m_addr.sadb_address_prefixlen = plen;
	m_addr.sadb_address_reserved = 0;

	key_setsadbextbuf(m_buf, m_len,
			(caddr_t)&m_addr, sizeof(struct sadb_address),
			(caddr_t)res->ai_addr, res->ai_addrlen);
	m_len += len;

	freeaddrinfo(res);
}
Beispiel #7
0
void
key_setsadbsa(void)
{
	struct sadb_sa m_sa;

	m_sa.sadb_sa_len = PFKEY_UNIT64(sizeof(struct sadb_sa));
	m_sa.sadb_sa_exttype = SADB_EXT_SA;
	m_sa.sadb_sa_spi = htonl(0x12345678);
	m_sa.sadb_sa_replay = 4;
	m_sa.sadb_sa_state = 0;
	m_sa.sadb_sa_auth = SADB_AALG_MD5HMAC;
	m_sa.sadb_sa_encrypt = SADB_EALG_DESCBC;
	m_sa.sadb_sa_flags = 0;

	memcpy(m_buf + m_len, &m_sa, sizeof(struct sadb_sa));
	m_len += sizeof(struct sadb_sa);
}
Beispiel #8
0
void
key_setsadbkey(u_int ext, caddr_t str)
{
	struct sadb_key m_key;
	u_int keylen = strlen(str);
	u_int len;

	len = sizeof(struct sadb_key) + PFKEY_ALIGN8(keylen);
	m_key.sadb_key_len = PFKEY_UNIT64(len);
	m_key.sadb_key_exttype = ext;
	m_key.sadb_key_bits = keylen * 8;
	m_key.sadb_key_reserved = 0;

	key_setsadbextbuf(m_buf, m_len,
			(caddr_t)&m_key, sizeof(struct sadb_key),
			str, keylen);
	m_len += len;
}
Beispiel #9
0
void
key_setsadbid(u_int ext, caddr_t str)
{
	struct sadb_ident m_id;
	u_int idlen = strlen(str), len;

	len = sizeof(m_id) + PFKEY_ALIGN8(idlen);
	m_id.sadb_ident_len = PFKEY_UNIT64(len);
	m_id.sadb_ident_exttype = ext;
	m_id.sadb_ident_type = SADB_IDENTTYPE_USERFQDN;
	m_id.sadb_ident_reserved = 0;
	m_id.sadb_ident_id = getpid();

	key_setsadbextbuf(m_buf, m_len,
			(caddr_t)&m_id, sizeof(struct sadb_ident),
			str, idlen);
	m_len += len;
}
Beispiel #10
0
int
setsockopt_bypass(int fd, int family)
{
	struct sadb_x_policy policy;
	int level, optname;

	switch (family) {
	case AF_INET:
		level = IPPROTO_IP;
		optname = IP_IPSEC_POLICY;
		break;
#ifdef INET6
	case AF_INET6:
		level = IPPROTO_IPV6;
		optname = IPV6_IPSEC_POLICY;
		break;
#endif
	default:
		plog(PLOG_INTERR, PLOGLOC, NULL,
		     "unsupported address family (%d)\n", family);
		return -1;
	}

	memset(&policy, 0, sizeof(policy));
	policy.sadb_x_policy_len = PFKEY_UNIT64(sizeof(policy));
	policy.sadb_x_policy_exttype = SADB_X_EXT_POLICY;
	policy.sadb_x_policy_type = IPSEC_POLICY_BYPASS;
	policy.sadb_x_policy_dir = IPSEC_DIR_INBOUND;
	if (setsockopt(fd, level, optname, &policy, sizeof(policy)) == -1) {
		plog(PLOG_INTERR, PLOGLOC, 0,
		     "setsockopt: %s\n", strerror(errno));
		return -1;
	}
	policy.sadb_x_policy_dir = IPSEC_DIR_OUTBOUND;
	if (setsockopt(fd, level, optname, &policy, sizeof(policy)) == -1) {
		plog(PLOG_INTERR, PLOGLOC, 0,
		     "setsockopt: %s\n", strerror(errno));
		return -1;
	}
	return 0;
}
Beispiel #11
0
/*
 * send message to the socket.
 */
static int
key_sendup0(struct rawcb *rp, struct mbuf *m, int promisc, int canwait)
{
	struct keycb *kp = (struct keycb *)rp;
	struct mbuf *n;
	int error = 0;

	if (canwait) {
		if (kp->kp_queue) {
			for (n = kp->kp_queue; n && n->m_nextpkt;
			    n = n->m_nextpkt)
				;
			n->m_nextpkt = m;
			m = kp->kp_queue;
			kp->kp_queue = NULL;
		} else
			m->m_nextpkt = NULL;	/* just for safety */
	} else
		m->m_nextpkt = NULL;

	for (; m && error == 0; m = n) {
		n = m->m_nextpkt;

		if (promisc) {
			struct sadb_msg *pmsg;

			M_PREPEND(m, sizeof(struct sadb_msg), M_NOWAIT);
			if (m && m->m_len < sizeof(struct sadb_msg))
				m = m_pullup(m, sizeof(struct sadb_msg));
			if (!m) {
				pfkeystat.in_nomem++;
				error = ENOBUFS;
				goto recovery;
			}
			m->m_pkthdr.len += sizeof(*pmsg);

			pmsg = mtod(m, struct sadb_msg *);
			bzero(pmsg, sizeof(*pmsg));
			pmsg->sadb_msg_version = PF_KEY_V2;
			pmsg->sadb_msg_type = SADB_X_PROMISC;
			pmsg->sadb_msg_len = PFKEY_UNIT64(m->m_pkthdr.len);
			/* pid and seq? */

			pfkeystat.in_msgtype[pmsg->sadb_msg_type]++;
		}

		if (canwait &&
		    sbspace(&rp->rcb_socket->so_rcv) < m->m_pkthdr.len) {
			error = EAGAIN;
			goto recovery;
		}

		m->m_nextpkt = NULL;

		if (!sbappendaddr(&rp->rcb_socket->so_rcv,
		    (struct sockaddr *)&key_src, m, NULL)) {
			pfkeystat.in_nomem++;
			error = ENOBUFS;
			goto recovery;
		} else {
			sorwakeup(rp->rcb_socket);
			error = 0;
		}
	}
	return (error);

recovery:
	if (kp->kp_queue) {
		/*
		 * insert m to the head of queue, as normally mbuf on the queue
		 * is less important than others.
		 */
		if (m) {
			m->m_nextpkt = kp->kp_queue;
			kp->kp_queue = m;
		}
	} else {
		/* recover the queue */
		if (!m) {
			/* first ENOBUFS case */
			kp->kp_queue = n;
		} else {
			kp->kp_queue = m;
			m->m_nextpkt = n;
		}
	}
	return (error);
}
Beispiel #12
0
void
key_setsadbmsg(u_int type)
{
	struct sadb_msg m_msg;

	memset(&m_msg, 0, sizeof(m_msg));
	m_msg.sadb_msg_version = PF_KEY_V2;
	m_msg.sadb_msg_type = type;
	m_msg.sadb_msg_errno = 0;
	m_msg.sadb_msg_satype = SADB_SATYPE_ESP;
#if 0
	m_msg.sadb_msg_reserved = 0;
#endif
	m_msg.sadb_msg_seq = 0;
	m_msg.sadb_msg_pid = getpid();

	m_len = sizeof(struct sadb_msg);
	memcpy(m_buf, &m_msg, m_len);

	switch (type) {
	case SADB_GETSPI:
		/*<base, address(SD), SPI range>*/
		key_setsadbaddr(SADB_EXT_ADDRESS_SRC, AF_INET, "10.0.3.4");
		key_setsadbaddr(SADB_EXT_ADDRESS_DST, AF_INET, "127.0.0.1");
		key_setspirange();
		/*<base, SA(*), address(SD)>*/
		break;

	case SADB_ADD:
		/* <base, SA, (lifetime(HSC),) address(SD), (address(P),)
		   key(AE), (identity(SD),) (sensitivity)> */
		key_setsadbaddr(SADB_EXT_ADDRESS_PROXY, AF_INET6, "3ffe::1");
	case SADB_UPDATE:
		key_setsadbsa();
		key_setsadblft(SADB_EXT_LIFETIME_HARD, 10);
		key_setsadblft(SADB_EXT_LIFETIME_SOFT, 5);
		key_setsadbaddr(SADB_EXT_ADDRESS_SRC, AF_INET, "192.168.1.1");
		key_setsadbaddr(SADB_EXT_ADDRESS_DST, AF_INET, "10.0.3.4");
		/* XXX key_setsadbkey(SADB_EXT_KEY_AUTH, "abcde"); */
		key_setsadbkey(SADB_EXT_KEY_AUTH, "1234567812345678");
		key_setsadbkey(SADB_EXT_KEY_ENCRYPT, "12345678");
		key_setsadbid(SADB_EXT_IDENTITY_SRC, "*****@*****.**");
		key_setsadbid(SADB_EXT_IDENTITY_DST, "*****@*****.**");
		key_setsadbsens();
		/* <base, SA, (lifetime(HSC),) address(SD), (address(P),)
		  (identity(SD),) (sensitivity)> */
		break;

	case SADB_DELETE:
		/* <base, SA(*), address(SDP)> */
		key_setsadbsa();
		key_setsadbaddr(SADB_EXT_ADDRESS_SRC, AF_INET, "192.168.1.1");
		key_setsadbaddr(SADB_EXT_ADDRESS_DST, AF_INET, "10.0.3.4");
		key_setsadbaddr(SADB_EXT_ADDRESS_PROXY, AF_INET6, "3ffe::1");
		/* <base, SA(*), address(SDP)> */
		break;

	case SADB_GET:
		/* <base, SA(*), address(SDP)> */
		key_setsadbsa();
		key_setsadbaddr(SADB_EXT_ADDRESS_SRC, AF_INET, "192.168.1.1");
		key_setsadbaddr(SADB_EXT_ADDRESS_DST, AF_INET, "10.0.3.4");
		key_setsadbaddr(SADB_EXT_ADDRESS_PROXY, AF_INET6, "3ffe::1");
		/* <base, SA, (lifetime(HSC),) address(SD), (address(P),)
		   key(AE), (identity(SD),) (sensitivity)> */
		break;

	case SADB_ACQUIRE:
		/* <base, address(SD), (address(P),) (identity(SD),)
		   (sensitivity,) proposal> */
		key_setsadbaddr(SADB_EXT_ADDRESS_SRC, AF_INET, "192.168.1.1");
		key_setsadbaddr(SADB_EXT_ADDRESS_DST, AF_INET, "10.0.3.4");
		key_setsadbaddr(SADB_EXT_ADDRESS_PROXY, AF_INET6, "3ffe::1");
		key_setsadbid(SADB_EXT_IDENTITY_SRC, "*****@*****.**");
		key_setsadbid(SADB_EXT_IDENTITY_DST, "*****@*****.**");
		key_setsadbsens();
		key_setsadbprop();
		/* <base, address(SD), (address(P),) (identity(SD),)
		   (sensitivity,) proposal> */
		break;

	case SADB_REGISTER:
		/* <base> */
		/* <base, supported> */
		break;

	case SADB_EXPIRE:
	case SADB_FLUSH:
		break;

	case SADB_DUMP:
		break;

	case SADB_X_PROMISC:
		/* <base> */
		/* <base, base(, others)> */
		break;

	case SADB_X_PCHANGE:
		break;

	/* for SPD management */
	case SADB_X_SPDFLUSH:
	case SADB_X_SPDDUMP:
		break;

	case SADB_X_SPDADD:
#if 0
	    {
		struct sadb_x_policy m_policy;

		m_policy.sadb_x_policy_len = PFKEY_UNIT64(sizeof(m_policy));
		m_policy.sadb_x_policy_exttype = SADB_X_EXT_POLICY;
		m_policy.sadb_x_policy_type = SADB_X_PL_IPSEC;
		m_policy.sadb_x_policy_esp_trans = 1;
		m_policy.sadb_x_policy_ah_trans = 2;
		m_policy.sadb_x_policy_esp_network = 3;
		m_policy.sadb_x_policy_ah_network = 4;
		m_policy.sadb_x_policy_reserved = 0;

		memcpy(m_buf + m_len, &m_policy, sizeof(struct sadb_x_policy));
		m_len += sizeof(struct sadb_x_policy);
	    }
#endif

	case SADB_X_SPDDELETE:
		key_setsadbaddr(SADB_EXT_ADDRESS_SRC, AF_INET, "192.168.1.1");
		key_setsadbaddr(SADB_EXT_ADDRESS_DST, AF_INET, "10.0.3.4");
		break;
	}

	((struct sadb_msg *)m_buf)->sadb_msg_len = PFKEY_UNIT64(m_len);
}
Beispiel #13
0
/*
 * Generate 'spi' array with SPIs matching 'satype', 'srcs', and 'dsts'.
 * Return value is dynamically generated array of SPIs, also number of
 * SPIs through num_spi pointer.
 * On any error, set *num_spi to 0 and return NULL.
 */
uint32_t *
sendkeymsg_spigrep(unsigned int satype, struct addrinfo *srcs,
    struct addrinfo *dsts, int *num_spi)
{
	struct sadb_msg msg, *m;
	char *buf;
	size_t len;
	ssize_t l;
	u_char rbuf[1024 * 32];
	caddr_t mhp[SADB_EXT_MAX + 1];
	struct sadb_address *saddr;
	struct sockaddr *s;
	struct addrinfo *a;
	struct sadb_sa *sa;
	uint32_t *spi = NULL;
	int max_spi = 0, fail = 0;

	*num_spi = 0;

	if (f_notreally) {
		return NULL;
	}

    {
	struct timeval tv;
	tv.tv_sec = 1;
	tv.tv_usec = 0;
	if (setsockopt(so, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) < 0) {
		perror("setsockopt");
		return NULL;
	}
    }

	msg.sadb_msg_version = PF_KEY_V2;
	msg.sadb_msg_type = SADB_DUMP;
	msg.sadb_msg_errno = 0;
	msg.sadb_msg_satype = satype;
	msg.sadb_msg_len = PFKEY_UNIT64(sizeof(msg));
	msg.sadb_msg_reserved = 0;
	msg.sadb_msg_seq = 0;
	msg.sadb_msg_pid = getpid();
	buf = (char *)&msg;
	len = sizeof(msg);

	if (f_verbose) {
		kdebug_sadb(&msg);
		printf("\n");
	}
	if (f_hexdump) {
		int i;
		for (i = 0; i < len; i++) {
			if (i % 16 == 0)
				printf("%08x: ", i);
			printf("%02x ", buf[i] & 0xff);
			if (i % 16 == 15)
				printf("\n");
		}
		if (len % 16)
			printf("\n");
	}

	if ((l = send(so, buf, len, 0)) < 0) {
		perror("send");
		return NULL;
	}

	m = (struct sadb_msg *)rbuf;
	do {
		if ((l = recv(so, rbuf, sizeof(rbuf), 0)) < 0) {
			perror("recv");
			fail = 1;
			break;
		}

		if (PFKEY_UNUNIT64(m->sadb_msg_len) != l) {
			warnx("invalid keymsg length");
			fail = 1;
			break;
		}

		if (f_verbose) {
			kdebug_sadb(m);
			printf("\n");
		}

		if (m->sadb_msg_type != SADB_DUMP) {
			warnx("unexpected message type");
			fail = 1;
			break;
		}

		if (m->sadb_msg_errno != 0) {
			warnx("error encountered");
			fail = 1;
			break;
		}

		/* match satype */
		if (m->sadb_msg_satype != satype)
			continue;

		pfkey_align(m, mhp);
		pfkey_check(mhp);

		/* match src */
		saddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_SRC];
		if (saddr == NULL)
			continue;
		s = (struct sockaddr *)(saddr + 1);
		for (a = srcs; a; a = a->ai_next)
			if (memcmp(a->ai_addr, s, a->ai_addrlen) == 0)
				break;
		if (a == NULL)
			continue;

		/* match dst */
		saddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_DST];
		if (saddr == NULL)
			continue;
		s = (struct sockaddr *)(saddr + 1);
		for (a = dsts; a; a = a->ai_next)
			if (memcmp(a->ai_addr, s, a->ai_addrlen) == 0)
				break;
		if (a == NULL)
			continue;

		if (*num_spi >= max_spi) {
			max_spi += 512;
			spi = realloc(spi, max_spi * sizeof(uint32_t));
		}

		sa = (struct sadb_sa *)mhp[SADB_EXT_SA];
		if (sa != NULL)
			spi[(*num_spi)++] = (uint32_t)ntohl(sa->sadb_sa_spi);

		m = (struct sadb_msg *)((caddr_t)m + PFKEY_UNUNIT64(m->sadb_msg_len));

		if (f_verbose) {
			kdebug_sadb(m);
			printf("\n");
		}

	} while (m->sadb_msg_seq);

	if (fail) {
		free(spi);
		*num_spi = 0;
		return NULL;
	}

	return spi;
}
Beispiel #14
0
static void __dead
promisc(void)
{
	struct sadb_msg msg;
	u_char rbuf[1024 * 32];	/* XXX: Enough ? Should I do MSG_PEEK ? */
	ssize_t l;

	msg.sadb_msg_version = PF_KEY_V2;
	msg.sadb_msg_type = SADB_X_PROMISC;
	msg.sadb_msg_errno = 0;
	msg.sadb_msg_satype = 1;
	msg.sadb_msg_len = PFKEY_UNIT64(sizeof(msg));
	msg.sadb_msg_reserved = 0;
	msg.sadb_msg_seq = 0;
	msg.sadb_msg_pid = getpid();

	if ((l = send(so, &msg, sizeof(msg), 0)) < 0) {
		err(1, "send");
	}

	while (1) {
		struct sadb_msg *base;

		if ((l = recv(so, rbuf, sizeof(*base), MSG_PEEK)) < 0) {
			err(1, "recv");
		}

		if (l != sizeof(*base))
			continue;

		base = (struct sadb_msg *)rbuf;
		if ((l = recv(so, rbuf, PFKEY_UNUNIT64(base->sadb_msg_len),
				0)) < 0) {
			err(1, "recv");
		}
		printdate();
		if (f_hexdump) {
			int i;
			for (i = 0; i < l; i++) {
				if (i % 16 == 0)
					printf("%08x: ", i);
				printf("%02x ", rbuf[i] & 0xff);
				if (i % 16 == 15)
					printf("\n");
			}
			if (l % 16)
				printf("\n");
		}
		/* adjust base pointer for promisc mode */
		if (base->sadb_msg_type == SADB_X_PROMISC) {
			if ((ssize_t)sizeof(*base) < l)
				base++;
			else
				base = NULL;
		}
		if (base) {
			kdebug_sadb(base);
			printf("\n");
			fflush(stdout);
		}
	}
}
Beispiel #15
0
// This function fills in policy0 and policylen0 according to the given parameters
// The full implementation can be found in racoon
// direction IPSEC_DIR_INBOUND | IPSEC_DIR_OUTBOUND
int getsadbpolicy(caddr_t *policy0, int *policylen0, int direction,
		  struct sockaddr *src, struct sockaddr *dst, u_int mode, int cmd)
{
	struct sadb_x_policy *xpl;
	struct sadb_x_ipsecrequest *xisr;
	struct saproto *pr;
	caddr_t policy, p;
	int policylen;
	int xisrlen, src_len, dst_len;
	u_int satype;
	HIP_DEBUG("\n");
	/* get policy buffer size */
	policylen = sizeof(struct sadb_x_policy);
	if (cmd != SADB_X_SPDDELETE) {
		xisrlen = sizeof(*xisr);
		xisrlen += (sysdep_sa_len(src) + sysdep_sa_len(dst));
		policylen += PFKEY_ALIGN8(xisrlen);
	}

	/* make policy structure */
	policy = malloc(policylen);
	if (!policy) {
		HIP_ERROR("Cannot allocate memory for policy\n");
		return -ENOMEM;
	}

	xpl = (struct sadb_x_policy *)policy;
	xpl->sadb_x_policy_len = PFKEY_UNIT64(policylen);
	xpl->sadb_x_policy_exttype = SADB_X_EXT_POLICY;
	xpl->sadb_x_policy_type = IPSEC_POLICY_IPSEC;
	xpl->sadb_x_policy_dir = direction;
	xpl->sadb_x_policy_id = 0;

	//xpl->sadb_x_policy_priority = PRIORITY_DEFAULT;

	if (cmd == SADB_X_SPDDELETE)
		goto end;

	xisr = (struct sadb_x_ipsecrequest *)(xpl + 1);

	xisr->sadb_x_ipsecrequest_proto = SADB_SATYPE_ESP;
	xisr->sadb_x_ipsecrequest_mode = mode;
	xisr->sadb_x_ipsecrequest_level = IPSEC_LEVEL_REQUIRE;
	xisr->sadb_x_ipsecrequest_reqid = 0;
	p = (caddr_t)(xisr + 1);

	xisrlen = sizeof(*xisr);

	src_len = sysdep_sa_len(src);
	dst_len = sysdep_sa_len(dst);
	xisrlen += src_len + dst_len;

	memcpy(p, src, src_len);
	p += src_len;

	memcpy(p, dst, dst_len);
	p += dst_len;

	xisr->sadb_x_ipsecrequest_len = PFKEY_ALIGN8(xisrlen);
end:
	*policy0 = policy;
	*policylen0 = policylen;
	return 0;
}