📄 pfkey.c
字号:
int len;
if ((len = pfkey_send_x1(so, SADB_ADD, satype, mode, src, dst, spi,
reqid, wsize,
keymat, e_type, e_keylen, a_type, a_keylen, flags,
l_alloc, l_bytes, l_addtime, l_usetime, seq)) < 0)
return -1;
return len;
}
/*
* sending SADB_DELETE message to the kernel.
* OUT:
* positive: success and return length sent.
* -1 : error occured, and set errno.
*/
int
pfkey_send_delete(so, satype, mode, src, dst, spi)
int so;
u_int satype, mode;
struct sockaddr *src, *dst;
u_int32_t spi;
{
int len;
if ((len = pfkey_send_x2(so, SADB_DELETE, satype, mode, src, dst, spi)) < 0)
return -1;
return len;
}
/*
* sending SADB_DELETE without spi to the kernel. This is
* the "delete all" request (an extension also present in
* Solaris).
*
* OUT:
* positive: success and return length sent
* -1 : error occured, and set errno
*/
int
pfkey_send_delete_all(so, satype, mode, src, dst)
int so;
u_int satype, mode;
struct sockaddr *src, *dst;
{
struct sadb_msg *newmsg;
int len;
caddr_t p;
int plen;
caddr_t ep;
/* validity check */
if (src == NULL || dst == NULL) {
__ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
return -1;
}
if (src->sa_family != dst->sa_family) {
__ipsec_errcode = EIPSEC_FAMILY_MISMATCH;
return -1;
}
switch (src->sa_family) {
case AF_INET:
plen = sizeof(struct in_addr) << 3;
break;
case AF_INET6:
plen = sizeof(struct in6_addr) << 3;
break;
default:
__ipsec_errcode = EIPSEC_INVAL_FAMILY;
return -1;
}
/* create new sadb_msg to reply. */
len = sizeof(struct sadb_msg)
+ sizeof(struct sadb_address)
+ PFKEY_ALIGN8(src->sa_len)
+ sizeof(struct sadb_address)
+ PFKEY_ALIGN8(dst->sa_len);
if ((newmsg = CALLOC(len, struct sadb_msg *)) == NULL) {
__ipsec_set_strerror(strerror(errno));
return -1;
}
ep = ((caddr_t)newmsg) + len;
p = pfkey_setsadbmsg((caddr_t)newmsg, ep, SADB_DELETE, len, satype, 0,
getpid());
if (!p) {
free(newmsg);
return -1;
}
p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_SRC, src, plen,
IPSEC_ULPROTO_ANY);
if (!p) {
free(newmsg);
return -1;
}
p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_DST, dst, plen,
IPSEC_ULPROTO_ANY);
if (!p || p != ep) {
free(newmsg);
return -1;
}
/* send message */
len = pfkey_send(so, newmsg, len);
free(newmsg);
if (len < 0)
return -1;
__ipsec_errcode = EIPSEC_NO_ERROR;
return len;
}
/*
* sending SADB_GET message to the kernel.
* OUT:
* positive: success and return length sent.
* -1 : error occured, and set errno.
*/
int
pfkey_send_get(so, satype, mode, src, dst, spi)
int so;
u_int satype, mode;
struct sockaddr *src, *dst;
u_int32_t spi;
{
int len;
if ((len = pfkey_send_x2(so, SADB_GET, satype, mode, src, dst, spi)) < 0)
return -1;
return len;
}
/*
* sending SADB_REGISTER message to the kernel.
* OUT:
* positive: success and return length sent.
* -1 : error occured, and set errno.
*/
int
pfkey_send_register(so, satype)
int so;
u_int satype;
{
int len, algno;
if (satype == PF_UNSPEC) {
for (algno = 0;
algno < sizeof(supported_map)/sizeof(supported_map[0]);
algno++) {
if (ipsec_supported[algno]) {
free(ipsec_supported[algno]);
ipsec_supported[algno] = NULL;
}
}
} else {
algno = findsupportedmap(satype);
if (algno == -1) {
__ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
return -1;
}
if (ipsec_supported[algno]) {
free(ipsec_supported[algno]);
ipsec_supported[algno] = NULL;
}
}
if ((len = pfkey_send_x3(so, SADB_REGISTER, satype)) < 0)
return -1;
return len;
}
/*
* receiving SADB_REGISTER message from the kernel, and copy buffer for
* sadb_supported returned into ipsec_supported.
* OUT:
* 0: success and return length sent.
* -1: error occured, and set errno.
*/
int
pfkey_recv_register(so)
int so;
{
pid_t pid = getpid();
struct sadb_msg *newmsg;
int error = -1;
/* receive message */
for (;;) {
if ((newmsg = pfkey_recv(so)) == NULL)
return -1;
if (newmsg->sadb_msg_type == SADB_REGISTER &&
newmsg->sadb_msg_pid == pid)
break;
free(newmsg);
}
/* check and fix */
newmsg->sadb_msg_len = PFKEY_UNUNIT64(newmsg->sadb_msg_len);
error = pfkey_set_supported(newmsg, newmsg->sadb_msg_len);
free(newmsg);
if (error == 0)
__ipsec_errcode = EIPSEC_NO_ERROR;
return error;
}
/*
* receiving SADB_REGISTER message from the kernel, and copy buffer for
* sadb_supported returned into ipsec_supported.
* NOTE: sadb_msg_len must be host order.
* IN:
* tlen: msg length, it's to makeing sure.
* OUT:
* 0: success and return length sent.
* -1: error occured, and set errno.
*/
int
pfkey_set_supported(msg, tlen)
struct sadb_msg *msg;
int tlen;
{
struct sadb_supported *sup;
caddr_t p;
caddr_t ep;
/* validity */
if (msg->sadb_msg_len != tlen) {
__ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
return -1;
}
p = (caddr_t)msg;
ep = p + tlen;
p += sizeof(struct sadb_msg);
while (p < ep) {
sup = (struct sadb_supported *)p;
if (ep < p + sizeof(*sup) ||
PFKEY_EXTLEN(sup) < sizeof(*sup) ||
ep < p + sup->sadb_supported_len) {
/* invalid format */
break;
}
switch (sup->sadb_supported_exttype) {
case SADB_EXT_SUPPORTED_AUTH:
case SADB_EXT_SUPPORTED_ENCRYPT:
break;
default:
__ipsec_errcode = EIPSEC_INVAL_SATYPE;
return -1;
}
/* fixed length */
sup->sadb_supported_len = PFKEY_EXTLEN(sup);
/* set supported map */
if (setsupportedmap(sup) != 0)
return -1;
p += sup->sadb_supported_len;
}
if (p != ep) {
__ipsec_errcode = EIPSEC_INVAL_SATYPE;
return -1;
}
__ipsec_errcode = EIPSEC_NO_ERROR;
return 0;
}
/*
* sending SADB_FLUSH message to the kernel.
* OUT:
* positive: success and return length sent.
* -1 : error occured, and set errno.
*/
int
pfkey_send_flush(so, satype)
int so;
u_int satype;
{
int len;
if ((len = pfkey_send_x3(so, SADB_FLUSH, satype)) < 0)
return -1;
return len;
}
/*
* sending SADB_DUMP message to the kernel.
* OUT:
* positive: success and return length sent.
* -1 : error occured, and set errno.
*/
int
pfkey_send_dump(so, satype)
int so;
u_int satype;
{
int len;
if ((len = pfkey_send_x3(so, SADB_DUMP, satype)) < 0)
return -1;
return len;
}
/*
* sending SADB_X_PROMISC message to the kernel.
* NOTE that this function handles promisc mode toggle only.
* IN:
* flag: set promisc off if zero, set promisc on if non-zero.
* OUT:
* positive: success and return length sent.
* -1 : error occured, and set errno.
* 0 : error occured, and set errno.
* others: a pointer to new allocated buffer in which supported
* algorithms is.
*/
int
pfkey_send_promisc_toggle(so, flag)
int so;
int flag;
{
int len;
if ((len = pfkey_send_x3(so, SADB_X_PROMISC, (flag ? 1 : 0))) < 0)
return -1;
return len;
}
/*
* sending SADB_X_SPDADD message to the kernel.
* OUT:
* positive: success and return length sent.
* -1 : error occured, and set errno.
*/
int
pfkey_send_spdadd(so, src, prefs, dst, prefd, proto, policy, policylen, seq)
int so;
struct sockaddr *src, *dst;
u_int prefs, prefd, proto;
caddr_t policy;
int policylen;
u_int32_t seq;
{
int len;
if ((len = pfkey_send_x4(so, SADB_X_SPDADD,
src, prefs, dst, prefd, proto,
0, 0,
policy, policylen, seq)) < 0)
return -1;
return len;
}
/*
* sending SADB_X_SPDADD message to the kernel.
* OUT:
* positive: success and return length sent.
* -1 : error occured, and set errno.
*/
int
pfkey_send_spdadd2(so, src, prefs, dst, prefd, proto, ltime, vtime,
policy, policylen, seq)
int so;
struct sockaddr *src, *dst;
u_int prefs, prefd, proto;
u_int64_t ltime, vtime;
caddr_t policy;
int policylen;
u_int32_t seq;
{
int len;
if ((len = pfkey_send_x4(so, SADB_X_SPDADD,
src, prefs, dst, prefd, proto,
ltime, vtime,
policy, policylen, seq)) < 0)
return -1;
return len;
}
/*
* sending SADB_X_SPDUPDATE message to the kernel.
* OUT:
* positive: success and return length sent.
* -1 : error occured, and set errno.
*/
int
pfkey_send_spdupdate(so, src, prefs, dst, prefd, proto, policy, policylen, seq)
int so;
struct sockaddr *src, *dst;
u_int prefs, prefd, proto;
caddr_t policy;
int policylen;
u_int32_t seq;
{
int len;
if ((len = pfkey_send_x4(so, SADB_X_SPDUPDATE,
src, prefs, dst, prefd, proto,
0, 0,
policy, policylen, seq)) < 0)
return -1;
return len;
}
/*
* sending SADB_X_SPDUPDATE message to the kernel.
* OUT:
* positive: success and return length sent.
* -1 : error occured, and set errno.
*/
int
pfkey_send_spdupdate2(so, src, prefs, dst, prefd, proto, ltime, vtime,
policy, policylen, seq)
int so;
struct sockaddr *src, *dst;
u_int prefs, prefd, proto;
u_int64_t ltime, vtime;
caddr_t policy;
int policylen;
u_int32_t seq;
{
int len;
if ((len = pfkey_send_x4(so, SADB_X_SPDUPDATE,
src, prefs, dst, prefd, proto,
ltime, vtime,
policy, policylen, seq)) < 0)
return -1;
return len;
}
/*
* sending SADB_X_SPDDELETE message to the kernel.
* OUT:
* positive: success and return length sent.
* -1 : error occured, and set errno.
*/
int
pfkey_send_spddelete(so, src, prefs, dst, prefd, proto, policy, policylen, seq)
int so;
struct sockaddr *src, *dst;
u_int prefs, prefd, proto;
caddr_t policy;
int policylen;
u_int32_t seq;
{
int len;
if (policylen != sizeof(struct sadb_x_policy)) {
__ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
return -1;
}
if ((len = pfkey_send_x4(so, SADB_X_SPDDELETE,
src, prefs, dst, prefd, proto,
0, 0,
policy, policylen, seq)) < 0)
return -1;
return len;
}
/*
* sending SADB_X_SPDDELETE message to the kernel.
* OUT:
* positive: success and return length sent.
* -1 : error occured, and set errno.
*/
int
pfkey_send_spddelete2(so, spid)
int so;
u_int32_t spid;
{
int len;
if ((len = pfkey_send_x5(so, SADB_X_SPDDELETE2, spid)) < 0)
return -1;
return len;
}
/*
* sending SADB_X_SPDGET message to the kernel.
* OUT:
* positive: success and return length sent.
* -1 : error occured, and set errno.
*/
int
pfkey_send_spdget(so, spid)
int so;
u_int32_t spid;
{
int len;
if ((len = pfkey_send_x5(so, SADB_X_SPDGET, spid)) < 0)
return -1;
return len;
}
/*
* sending SADB_X_SPDSETIDX message to the kernel.
* OUT:
* positive: success and return length sent.
* -1 : error occured, and set errno.
*/
int
pfkey_send_spdsetidx(so, src, prefs, dst, prefd, proto, policy, policylen, seq)
int so;
struct sockaddr *src, *dst;
u_int prefs, prefd, proto;
caddr_t policy;
int policylen;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -