未找到rt_msghdr结构定义,如何通过UNIX网络API获取路由表信息?
rt_msghdr on Kali Linux 4.14 Hey there, let's clear up this confusion and get you on track to fetching routing table info on your Kali system.
The Root Cause
The rt_msghdr struct you're looking for is a BSD-specific routing message structure—Linux doesn't include it in its header files. Instead, Linux uses the Netlink API (specifically the rtnetlink subsystem) for kernel-user space communication related to routing, which relies on a different set of structures and headers.
Step-by-Step Solution
Switch to the Correct Header File
Replace<net/route.h>with<linux/rtnetlink.h>—this is the standard header for Linux routing operations via Netlink. It defines all the necessary structures likestruct rtmsg(the Linux equivalent of BSD'srt_msghdr) andstruct nlmsghdr(the Netlink message wrapper).Use Linux's Routing API Structures
Instead ofrt_msghdr, you'll work with two key structures:struct nlmsghdr: The top-level Netlink message header that wraps all routing-related payloads.struct rtmsg: The core structure for specifying routing table query parameters (like address family, target route table, etc.).
Example Code Snippet
Here's a minimal example to set up a Netlink socket and send a request to fetch the IPv4 main routing table:#include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/socket.h> #include <linux/rtnetlink.h> #include <unistd.h> int main() { int sockfd; struct sockaddr_nl sa; struct nlmsghdr *nlh; struct rtmsg *rtm; ssize_t recv_len; char buf[8192]; // Create Netlink routing socket sockfd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE); if (sockfd < 0) { perror("Failed to create socket"); exit(EXIT_FAILURE); } // Configure Netlink socket address memset(&sa, 0, sizeof(sa)); sa.nl_family = AF_NETLINK; sa.nl_pid = getpid(); sa.nl_groups = RTMGRP_IPV4_ROUTE; // Allocate and initialize Netlink message nlh = (struct nlmsghdr *)malloc(NLMSG_SPACE(sizeof(struct rtmsg))); if (!nlh) { perror("Failed to allocate memory"); close(sockfd); exit(EXIT_FAILURE); } memset(nlh, 0, NLMSG_SPACE(sizeof(struct rtmsg))); nlh->nlmsg_len = NLMSG_SPACE(sizeof(struct rtmsg)); nlh->nlmsg_type = RTM_GETROUTE; nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP; // Request full table dump nlh->nlmsg_seq = 1; nlh->nlmsg_pid = getpid(); // Populate routing query parameters rtm = NLMSG_DATA(nlh); rtm->rtm_family = AF_INET; // Target IPv4 routing table rtm->rtm_table = RT_TABLE_MAIN; // Query the main route table rtm->rtm_scope = RT_SCOPE_UNIVERSE; // Send the request to the kernel if (sendto(sockfd, nlh, nlh->nlmsg_len, 0, (struct sockaddr *)&sa, sizeof(sa)) < 0) { perror("Failed to send request"); free(nlh); close(sockfd); exit(EXIT_FAILURE); } // Receive and process the response (simplified) recv_len = recv(sockfd, buf, sizeof(buf), 0); if (recv_len < 0) { perror("Failed to receive response"); } else { printf("Received routing table data (length: %zd bytes)\n", recv_len); // Parse the response using the NLMSG_NEXT() macro to iterate over messages } // Cleanup free(nlh); close(sockfd); return 0; }Deepen Your Knowledge with Man Pages
For detailed documentation on allrtnetlinkstructures, message types, and parsing logic, run:man 7 rtnetlinkThis covers everything you need to handle complex routing operations and parse the kernel's response fully.
内容的提问来源于stack exchange,提问作者P.Carlino

