用户层通过socket使用XFRM_MSG_GETSA获取xfrm_algo_auth信息的C代码示例
以下是一个使用socket获取xfrm_algo_auth信息的C代码示例:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <sys/socket.h>
#include <linux/xfrm.h>
#define BUF_SIZE 4096
int main(int argc, char *argv[]) {
int sockfd, ret;
char buf[BUF_SIZE];
struct msghdr msg;
struct iovec iov;
struct sockaddr_nl nladdr;
struct nlmsghdr *nlhdr;
struct xfrm_userpolicy_info up_info;
struct xfrm_usersa_info sa_info;
struct xfrm_algo_auth *auth;
int nlgroups = XFRMNLGRP_NONE;
sockfd = socket(AF_NETLINK, SOCK_RAW, NETLINK_XFRM);
if (sockfd < 0) {
perror("socket");
exit(EXIT_FAILURE);
}
memset(&nladdr, 0, sizeof(nladdr));
nladdr.nl_family = AF_NETLINK;
ret = bind(sockfd, (struct sockaddr *)&nladdr, sizeof(nladdr));
if (ret < 0) {
perror("bind");
exit(EXIT_FAILURE);
}
memset(&up_info, 0, sizeof(up_info));
up_info.sel.family = AF_INET;
up_info.sel.saddr.a4 = inet_addr("192.168.1.1");
up_info.sel.prefixlen_d = 32;
up_info.dir = XFRM_POLICY_OUT;
memset(&sa_info, 0, sizeof(sa_info));
sa_info.sel.family = AF_INET;
sa_info.sel.saddr.a4 = inet_addr("192.168.1.1");
sa_info.sel.prefixlen_d = 32;
sa_info.mode = XFRM_MODE_TUNNEL;
sa_info.reqid = 1;
memset(&msg, 0, sizeof(msg));
nlhdr = (struct nlmsghdr *)buf;
nlhdr->nlmsg_len = NLMSG_LENGTH(sizeof(up_info));
nlhdr->nlmsg_type = XFRM_MSG_NEWPOLICY;
nlhdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL;
nlhdr->nlmsg_seq = 1;
nlhdr->nlmsg_pid = getpid();
memcpy(NLMSG_DATA(nlhdr), &up_info, sizeof(up_info));
iov.iov_base = (void *)nlhdr;
iov.iov_len = nlhdr->nlmsg_len;
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
ret = sendmsg(sockfd, &msg, 0);
if (ret < 0) {
perror("sendmsg");
exit(EXIT_FAILURE);
}
memset(&msg, 0, sizeof(msg));
nlhdr = (struct nlmsghdr *)buf;
nlhdr->nlmsg_len = NLMSG_LENGTH(sizeof(sa_info));
nlhdr->nlmsg_type = XFRM_MSG_NEWSA;
nlhdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL;
nlhdr->nlmsg_seq = 2;
nlhdr->nlmsg_pid = getpid();
memcpy(NLMSG_DATA(nlhdr), &sa_info, sizeof(sa_info));
iov.iov_base = (void *)nlhdr;
iov.iov_len = nlhdr->nlmsg_len;
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
ret = sendmsg(sockfd, &msg, 0);
if (ret < 0) {
perror("sendmsg");
exit(EXIT_FAILURE);
}
memset(&msg, 0, sizeof(msg));
nlhdr = (struct nlmsghdr *)buf;
nlhdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct xfrm_usersa_id));
nlhdr->nlmsg_type = XFRM_MSG_GETSA;
nlhdr->nlmsg_flags = NLM_F_REQUEST;
nlhdr->nlmsg_seq = 3;
nlhdr->nlmsg_pid = getpid();
struct xfrm_usersa_id *id = (struct xfrm_usersa_id *)NLMSG_DATA(nlhdr);
id->daddr.a4 = inet_addr("192.168.1.1");
id->spi = 1234;
iov.iov_base = (void *)nlhdr;
iov.iov_len = nlhdr->nlmsg_len;
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
ret = sendmsg(sockfd, &msg, 0);
if (ret < 0) {
perror("sendmsg");
exit(EXIT_FAILURE);
}
memset(&msg, 0, sizeof(msg));
iov.iov_base = buf;
iov.iov_len = BUF_SIZE;
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
msg.msg_name = &nladdr;
msg.msg_namelen = sizeof(nladdr);
ret = recvmsg(sockfd, &msg, 0);
if (ret < 0) {
perror("recvmsg");
exit(EXIT_FAILURE);
}
nlhdr = (struct nlmsghdr *)buf;
while (NLMSG_OK(nlhdr, ret)) {
if (nlhdr->nlmsg_type == XFRM_MSG_NEWSA) {
struct xfrm_usersa_info *sa = (struct xfrm_usersa_info *)NLMSG_DATA(nlhdr);
if (sa->id.daddr.a4 == inet_addr("192.168.1.1") && sa->id.spi == 1234) {
auth = (struct xfrm_algo_auth *)((char *)sa + NLMSG_ALIGN(sa->hdr.len) + sizeof(struct xfrm_algo));
printf("auth algo name: %s\n", auth->alg_name);
printf("auth key length: %d\n", auth->alg_key_len);
break;
}
}
nlhdr = NLMSG_NEXT(nlhdr, ret);
}
memset(&msg, 0, sizeof(msg));
nlhdr = (struct nlmsghdr *)buf;
nlhdr->nlmsg_len = NLMSG_LENGTH(sizeof(up_info));
nlhdr->nlmsg_type = XFRM_MSG_DELPOLICY;
nlhdr->nlmsg_flags = NLM_F_REQUEST;
nlhdr->nlmsg_seq = 4;
nlhdr->nlmsg_pid = getpid();
memcpy(NLMSG_DATA(nlhdr), &up_info, sizeof(up_info));
iov.iov_base = (void *)nlhdr;
iov.iov_len = nlhdr->nlmsg_len;
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
ret = sendmsg(sockfd, &msg, 0);
if (ret < 0) {
perror("sendmsg");
exit(EXIT_FAILURE);
}
memset(&msg, 0, sizeof(msg));
nlhdr = (struct nlmsghdr *)buf;
nlhdr->nlmsg_len = NLMSG_LENGTH(sizeof(sa_info));
nlhdr->nlmsg_type = XFRM_MSG_DELSA;
nlhdr->nlmsg_flags = NLM_F_REQUEST;
nlhdr->nlmsg_seq = 5;
nlhdr->nlmsg_pid = getpid();
memcpy(NLMSG_DATA(nlhdr), &sa_info, sizeof(sa_info));
iov.iov_base = (void *)nlhdr;
iov.iov_len = nlhdr->nlmsg_len;
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
ret = sendmsg(sockfd, &msg, 0);
if (ret < 0) {
perror("sendmsg");
exit(EXIT_FAILURE);
}
close(sockfd);
return 0;
}
该示例创建了一个xfrm policy和一个xfrm sa,并通过socket发送XFRM_MSG_GETSA消息获取xfrm sa的信息,包括xfrm_algo_auth的算法名称和密钥长度。最后删除创建的xfrm policy和xfrm sa
原文地址: https://www.cveoy.top/t/topic/gAZx 著作权归作者所有。请勿转载和采集!