LINUX.ORG.RU

Networking -> netlink/rtnetlink -> routing

 , ,


0

2

Господа хорошие, кто тыкал эту прелесть, не подскажете? Я шлю реквест в сокет, хочу у него про гейтвей разузнать. Он мне отвечает. Но в одном реквесте содержится 10, насколько я смог проверить, идентичных хедеров и, соответственно, идентичная дата. Вопрос: почему там больше одного хедера, зачем мне лишние и ЧЯДНТ?

КодЬ длинный, в нём куча мусора с печатями и не только, но рабочий. И на выходе показывает в удобоваримом виде пакеты.

#include <errno.h>
#include <stdio.h>
#include <memory.h>
#include <net/if.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <linux/rtnetlink.h>
#include <sys/types.h>
#include <unistd.h>

char buf[2000];

int seq = 0;

struct nl_req {
    struct nlmsghdr hdr;
    struct rtmsg msg;
};

int main(void)
{
    int rtnl_sock = -1;
    if ((rtnl_sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE)) < 0)
        return -1;

    int pid = getpid();

    struct sockaddr_nl local;
    memset(&local, 0, sizeof(local));
    local.nl_family = AF_NETLINK;
    local.nl_pid = pid;

    struct sockaddr_nl kernel;
    memset(&kernel, 0, sizeof(kernel));
    kernel.nl_family = AF_NETLINK;
    kernel.nl_pid = 0;

    if (bind(rtnl_sock, (struct sockaddr *)&local, sizeof(local)) == -1)
    {
        perror("socket binding");
        return -1;
    }

    struct nl_req nlReq;
    memset(&nlReq, 0, sizeof(nlReq));

    /* Fill message */
    nlReq.hdr.nlmsg_len     = NLMSG_LENGTH(sizeof(struct rtmsg));
    nlReq.hdr.nlmsg_type    = RTM_GETROUTE;
    nlReq.hdr.nlmsg_flags   = NLM_F_REQUEST | NLM_F_DUMP | NLM_F_MATCH;
    nlReq.hdr.nlmsg_seq     = seq++;
    nlReq.hdr.nlmsg_pid     = pid;

    nlReq.msg.rtm_family    = AF_INET;
    nlReq.msg.rtm_type      = RTN_UNICAST;
    nlReq.msg.rtm_table     = RT_TABLE_MAIN;
    nlReq.msg.rtm_scope     = RT_SCOPE_SITE;
    nlReq.msg.rtm_protocol  = RTPROT_KERNEL;

    /* Send message */
    sendto(rtnl_sock, (void *)&nlReq, nlReq.hdr.nlmsg_len, 0, (struct sockaddr *)&kernel, sizeof(kernel));


    int packet = 1;
    while(1)
    {
        int len = recv(rtnl_sock, buf, sizeof(buf), MSG_DONTWAIT); //, NULL, NULL);
        if (len == -1)
        {
            perror("recv");
            return -1;
        }

        struct nlmsghdr *hdr;
        hdr = (struct nlmsghdr *)buf;

        printf("\Packet recieved: --%d--\n"\
                "--------------------------------------\n" \
                "Read from socket %d bytes\n", packet, len);

        char data_buff[32];
        int i = 0;

        for (; NLMSG_OK(hdr, len); NLMSG_NEXT(hdr, len)) {

            if (hdr->nlmsg_type == NLMSG_DONE)
            {
                printf("\nGot NLMSG_DONE\n; nlmsg seq is: %d", hdr->nlmsg_seq);
                break;
            }

            if (hdr->nlmsg_type == NLMSG_ERROR)
            {
                printf("\nGot NLMSG_ERROR\n; nlmsg seq is: %d", hdr->nlmsg_seq);
                break;
            }

            printf("\n%d) header---------\nnlmsg type is: %d\n\n", i, hdr->nlmsg_type);

            struct  rtmsg *route_entry  = (struct rtmsg *)NLMSG_DATA(hdr);
            struct rtattr *route_attr   = (struct rtattr *)RTM_RTA(route_entry);
            int route_attr_len          = RTM_PAYLOAD(hdr);

            printf("\tntmsghdr.nlmsg_pid: 0x%x\n", hdr->nlmsg_pid);
            printf("\tntmsghdr.flags: 0x%x\n", hdr->nlmsg_flags);
            printf("\trtmsg.rtm_scope: 0x%x\n", route_entry->rtm_scope);
            printf("\trtmsg.rtm_flags: 0x%x\n", route_entry->rtm_flags);
            printf("\trtmsg.rtm_tos: 0x%x\n", route_entry->rtm_tos);
            printf("\trtmsg.rtm_src_len: 0x%x\n", route_entry->rtm_src_len);
            printf("\trtmsg.rtm_dst_len: 0x%x\n", route_entry->rtm_dst_len);
            printf("\trtmsg.rtm_table: 0x%x\n", route_entry->rtm_table);
            printf("\trtmsg.rtm_family: 0x%x\n", route_entry->rtm_family);
            printf("\trtmsg.rtm_protocol: 0x%x\n", route_entry->rtm_protocol);


            int j = 0;

            for (; RTA_OK(route_attr, route_attr_len); route_attr = RTA_NEXT(route_attr, route_attr_len))
            {
                char *ptr = (char *)RTA_DATA(route_attr);
                switch(route_attr->rta_type) {
                case RTA_GATEWAY:
                    inet_ntop(AF_INET, RTA_DATA(route_attr), data_buff, sizeof(data_buff));
                    printf("\t%d entry)) Gateway address is: %s\n", j, data_buff);
                    break;
                case RTA_PRIORITY:
                    printf("\t%d entry)) Priority is: 0x%x\n", j, *ptr);
                    break;
                case RTA_TABLE:
                    inet_ntop(AF_INET, RTA_DATA(route_attr), data_buff, sizeof(data_buff));
                    printf("\t%d entry)) Table ID is: %s\n", j, data_buff);
                    break;
                case RTA_OIF:
                    printf("\t%d entry)) Ouput IF index: 0x%x\n", j, *ptr);
                    break;
                case RTA_DST:
                    inet_ntop(AF_INET, RTA_DATA(route_attr), data_buff, sizeof(data_buff));
                    printf("\t%d entry)) Destination is: %s\n", j, data_buff);
                    break;
                case RTA_PREF:
                    printf("\t%d entry)) Preference is: 0x%x\n", j, *ptr);
                    break;
                case RTA_CACHEINFO:
                    printf("\t%d entry)) Cache info is: 0x%x\n", j, *ptr);
                    break;
                default:
                    printf("\t%d entry)) rta_type == %d; value is: %x\n", j, route_attr->rta_type, *ptr);
                    break;
                }
                j++;
            }
            i++;
        }
        printf("\nPacket ends here\n--------------------------------------\n\n\n");
        packet++;
        }
}

Или вот вам паста.



Последнее исправление: LuxInTenebr1s (всего исправлений: 4)

Ответ на: комментарий от anonymous

Ты мог случайно обнаружить, что вопрос затерялся где-то в месте, которое начинается с «но». Но. Я поправлю сообщение.

LuxInTenebr1s
() автор топика
--- test.c	2018-03-31 13:40:43.071189013 +0300
+++ test2.c	2018-03-31 13:42:18.268817197 +0300
@@ -81,7 +81,7 @@
         char data_buff[32];
         int i = 0;

-        for (; NLMSG_OK(hdr, len); NLMSG_NEXT(hdr, len)) {
+        for (; NLMSG_OK(hdr, len); hdr = NLMSG_NEXT(hdr, len)) {

             if (hdr->nlmsg_type == NLMSG_DONE)
             {

как минимум. Остальное не смотрел, могут быть ещё и другие проблемы.

Deleted
()
Последнее исправление: Deleted (всего исправлений: 1)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.