int
ipsec_get_policylen(ipsec_policy_t policy)
{
    u_int16_t aligned_len;
    
    if (policy) {
        memcpy(&aligned_len, policy, sizeof(u_int16_t));
        return PFKEY_UNUNIT64(aligned_len);
    } else
        return -1;
}
示例#2
0
static int
fileproc(const char *filename)
{
	int fd;
	ssize_t len, l;
	u_char *p, *ep;
	struct sadb_msg *msg;
	u_char rbuf[1024 * 32];	/* XXX: Enough ? Should I do MSG_PEEK ? */

	fd = open(filename, O_RDONLY);
	if (fd < 0)
		return -1;

	l = 0;
	while (1) {
		len = read(fd, rbuf + l, sizeof(rbuf) - l);
		if (len < 0) {
			close(fd);
			return -1;
		} else if (len == 0)
			break;
		l += len;
	}

	if (l < sizeof(struct sadb_msg)) {
		close(fd);
		errno = EINVAL;
		return -1;
	}
	close(fd);

	p = rbuf;
	ep = rbuf + l;

	while (p < ep) {
		msg = (struct sadb_msg *)p;
		len = PFKEY_UNUNIT64(msg->sadb_msg_len);
		if (f_verbose) {
			kdebug_sadb((struct sadb_msg *)msg);
			printf("\n");
		}
		postproc(msg, len);
		p += len;
	}

	return 0;
}
示例#3
0
文件: keysock.c 项目: MarginC/kame
key_output(struct mbuf *m, va_alist)
#endif
{
	struct sadb_msg *msg;
	int len, error = 0;
	int s;
	struct socket *so;
	va_list ap;

	va_start(ap, m);
	so = va_arg(ap, struct socket *);
	va_end(ap);

	if (m == 0)
		panic("key_output: NULL pointer was passed.");

	pfkeystat.out_total++;
	pfkeystat.out_bytes += m->m_pkthdr.len;

	len = m->m_pkthdr.len;
	if (len < sizeof(struct sadb_msg)) {
		pfkeystat.out_tooshort++;
		error = EINVAL;
		goto end;
	}

	if (m->m_len < sizeof(struct sadb_msg)) {
		if ((m = m_pullup(m, sizeof(struct sadb_msg))) == 0) {
			pfkeystat.out_nomem++;
			error = ENOBUFS;
			goto end;
		}
	}

	if ((m->m_flags & M_PKTHDR) == 0)
		panic("key_output: not M_PKTHDR ??");

	KEYDEBUG(KEYDEBUG_KEY_DUMP, kdebug_mbuf(m));

	msg = mtod(m, struct sadb_msg *);
	pfkeystat.out_msgtype[msg->sadb_msg_type]++;
	if (len != PFKEY_UNUNIT64(msg->sadb_msg_len)) {
		pfkeystat.out_invlen++;
		error = EINVAL;
		goto end;
	}

	/*XXX giant lock*/
#ifdef __NetBSD__
	s = splsoftnet();
#else
	s = splnet();
#endif
	error = key_parse(m, so);
	m = NULL;
	splx(s);
end:
	if (m)
		m_freem(m);
	return error;
}
示例#4
0
int
sendkeymsg(char *buf, size_t len)
{
	u_char rbuf[1024 * 32];	/* XXX: Enough ? Should I do MSG_PEEK ? */
	ssize_t l;
	struct sadb_msg *msg;

	if (f_notreally) {
		goto end;
	}

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

	if (f_forever)
		shortdump_hdr();
again:
	if (f_verbose) {
		kdebug_sadb((struct sadb_msg *)buf);
		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");
		goto end;
	}

	msg = (struct sadb_msg *)rbuf;
	do {
		if ((l = recv(so, rbuf, sizeof(rbuf), 0)) < 0) {
			perror("recv");
			goto end;
		}

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

		if (f_verbose) {
			kdebug_sadb(msg);
			printf("\n");
		}
		if (postproc(msg, l) < 0)
			break;
	} while (msg->sadb_msg_errno || msg->sadb_msg_seq);

	if (f_forever) {
		fflush(stdout);
		sleep(1);
		goto again;
	}

end:
	return 0;
}
示例#5
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;
}
示例#6
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);
		}
	}
}