Linux/Kernel(커널)
[Kernel] Netlink 메시지 수신 (MPTCP) 예제
i5
2024. 8. 13. 02:34
반응형
#include <linux/netlink.h>
#include <linux/rtnetlink.h>
#include <linux/genetlink.h>
#include <linux/mptcp.h>
#include <sys/socket.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define NETLINK_MPTCP 41 // MPTCP Netlink protocol number
void process_event(struct nlmsghdr *nlh) {
struct mptcp_event *event = NLMSG_DATA(nlh);
switch (event->event) {
case MPTCP_EVENT_CREATED:
printf("MPTCP_EVENT_CREATED: Token=%u\n", event->token);
break;
case MPTCP_EVENT_ESTABLISHED:
printf("MPTCP_EVENT_ESTABLISHED: Token=%u\n", event->token);
break;
case MPTCP_EVENT_CLOSED:
printf("MPTCP_EVENT_CLOSED: Token=%u\n", event->token);
break;
case MPTCP_EVENT_ANNOUNCED:
printf("MPTCP_EVENT_ANNOUNCED: Token=%u\n", event->token);
break;
case MPTCP_EVENT_REMOVED:
printf("MPTCP_EVENT_REMOVED: Token=%u\n", event->token);
break;
case MPTCP_EVENT_JOINED:
printf("MPTCP_EVENT_JOINED: Token=%u\n", event->token);
break;
case MPTCP_EVENT_CLOSED_SUBFLOW:
printf("MPTCP_EVENT_CLOSED_SUBFLOW: Token=%u\n", event->token);
break;
case MPTCP_EVENT_PRIORITY_CHANGED:
printf("MPTCP_EVENT_PRIORITY_CHANGED: Token=%u\n", event->token);
break;
default:
printf("Unknown MPTCP event type: %d\n", event->event);
break;
}
}
int main() {
int sock_fd;
struct sockaddr_nl src_addr;
struct nlmsghdr *nlh = NULL;
struct iovec iov;
struct msghdr msg;
char buffer[8192];
// Netlink 소켓 생성
sock_fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_MPTCP);
if (sock_fd < 0) {
perror("socket");
return -1;
}
memset(&src_addr, 0, sizeof(src_addr));
src_addr.nl_family = AF_NETLINK;
src_addr.nl_pid = getpid(); // 현재 프로세스 ID
src_addr.nl_groups = RTMGRP_LINK; // 수신할 그룹 설정 (필요에 따라 설정)
if (bind(sock_fd, (struct sockaddr *)&src_addr, sizeof(src_addr)) < 0) {
perror("bind");
close(sock_fd);
return -1;
}
memset(&msg, 0, sizeof(msg));
iov.iov_base = buffer;
iov.iov_len = sizeof(buffer);
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
while (1) {
// 메시지 수신
ssize_t len = recvmsg(sock_fd, &msg, 0);
if (len < 0) {
perror("recvmsg");
break;
}
// Netlink 헤더 확인
for (nlh = (struct nlmsghdr *)buffer; NLMSG_OK(nlh, len); nlh = NLMSG_NEXT(nlh, len)) {
// 메시지의 유형이 이벤트인 경우 처리
if (nlh->nlmsg_type == NLMSG_DONE || nlh->nlmsg_type == NLMSG_ERROR) {
break;
}
// 이벤트 메시지 처리
process_event(nlh);
}
}
close(sock_fd);
return 0;
}
반응형