Господа хорошие, кто тыкал эту прелесть, не подскажете? Я шлю реквест в сокет, хочу у него про гейтвей разузнать. Он мне отвечает. Но в одном реквесте содержится 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++;
}
}
Или вот вам паста.