Netlink socket에 대하여

개요

본 예제소스는 Netlink socket을 통해서 NETLINK_XFRM쪽을 Group join (XFRMNLGRP_ACQUIRE, XFRMNLGRP_EXPIRE, XFRMNLGRP_SA, XFRMNLGRP_POLICY, XFRMNLGRP_AEVENTS, XFRMNLGRP_REPORT, XFRMNLGRP_MIGRATE, XFRMNLGRP_MAPPING)하여 Strongswan과 Kernel 의 XFRM모듈과의 교신내용을 모니터링 하는 예제소스를 잠깐 커널소스 보면서 구현해봤습니다.

실제 IPSec협상시 해당 내용이 교신되는 것을 확인할 수 있으며 세부 내용을 전부 파싱하여 보여주도록 해 봤습니다. (참고로 IPSec 연결을 위해서 [https]strongSwan[]을 사용하였습니다.)

어떤 내용이 오고가는지를 확인하는데 도움이 될것 같고 Netlink socket을 다른 부분도 응용하여 구현해볼 수 있을거라 생각됩니다.

IPSsec 관련 모니터링 예제소스 : @netlink_ipsec_monitor-source.tar.gz (8.69 KB)

Hotplug(udev) 장치 Event 예제소스 : @mzudev-source.tar.gz (4.94 KB)

구현사항에 대한 간략한 골격구조 설명

  1. Netlink socket을 XFRM쪽으로 open
    s_socket = socket(PF_NETLINK, SOCK_RAW, NETLINK_XFRM /* 6 - ipsec */);
    


  2. XFRM모듈쪽의 어떤 Group 과 통신할지를 binding
    __u32 s_nl_groups;
    struct sockaddr_nl s_sockaddr_nl;
    
    s_nl_groups |= XFRMNLGRP_ACQUIRE;
    s_nl_groups |= XFRMNLGRP_EXPIRE;
    s_nl_groups |= XFRMNLGRP_SA;
    s_nl_groups |= XFRMNLGRP_POLICY;
    s_nl_groups |= XFRMNLGRP_AEVENTS;
    s_nl_groups |= XFRMNLGRP_REPORT;
    s_nl_groups |= XFRMNLGRP_MIGRATE;
    s_nl_groups |= XFRMNLGRP_MAPPING;
    
    s_sockaddr_nl.nl_family = AF_NETLINK;
    s_sockaddr_nl.nl_pad = (unsigned short)0u;
    s_sockaddr_nl.nl_pid = (pid_t)0;
    s_sockaddr_nl.nl_groups = s_nl_groups; /* Multicast groups mask */
    
    bind(s_socket, (const struct sockaddr *)(&s_sockaddr_nl), (socklen_t)sizeof(s_sockaddr_nl));
    


  3. netlink socket으로부터 Netlink protocol RAW 수신
    socklen_t s_socklen;
    
    s_socklen = (socklen_t)sizeof(s_sockaddr_nl);
    s_recv_bytes = recvfrom(
        s_socket,
        s_buffer,
        s_buffer_size,
        MSG_NOSIGNAL,
        (struct sockaddr *)(&s_sockaddr_nl),
        (socklen_t *)(&s_socklen)
    );
    


  4. 수신된 Netlink protocol RAW data에서 Netlink header 를 통해서 각 요소별 분리
    size_t s_msg_size;
    struct nlmsghdr *s_nlmsghdr;
    size_t s_payload_size;
    void *s_payload;
    
    s_msg_size = (size_t)s_recv_bytes;
    for(s_nlmsghdr = (struct nlmsghdr *)s_buffer;(s_is_break == 0) && NLMSG_OK(s_nlmsghdr, s_msg_size);s_nlmsghdr = NLMSG_NEXT(s_nlmsghdr, s_msg_size)) {            /* Netlink 수신패킷 하나에 여러개의 Netlink header가 탑재될 수 있는데 이를 각 Header 단위로 분리하는 Loop */
        s_payload_size = (size_t)NLMSG_PAYLOAD(s_nlmsghdr, 0); /* Header 내의 실제 Data 크기 */
        s_payload = NLMSG_DATA(s_nlmsghdr); /* Header 내의 실제 Data 위치 포인터 */
    
        switch(s_nlmsghdr->nlmsg_type) { /* 각 메세지의 종류별로 다른 파싱구조를 가지고 있으므로 커널을 참조하여 해당 부분을 파싱해야 합니다. */
            .....
        }
    }
    


실제 VPN 장비에서 VPN연결과정에서 본 예제프로그램으로 Netlink 통신을 수신하여 파싱된 내용을 모니터링한 콘솔내용

내용을 보시려면 여기를 클릭해주세요.



/*

[ FrontPage | PrintView | RawView | RSS ]

Copyright ⓒ MINZKN.COM
All Rights Reserved.

MINZKN

----

*/