반응형

 

 

 

#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;
}
반응형