This commit is contained in:
Zack Buhman 2026-08-19 22:38:09 -05:00
parent d891ad5a48
commit c9bb6a5965
3 changed files with 85 additions and 3 deletions

View File

@ -10,6 +10,7 @@
#include <linux/netlink.h> #include <linux/netlink.h>
#include <linux/rtnetlink.h> #include <linux/rtnetlink.h>
#include <net/if.h> #include <net/if.h>
#include <arpa/inet.h>
#include "ip4.h" #include "ip4.h"
#include "rtnetlink.h" #include "rtnetlink.h"
@ -103,5 +104,22 @@ int main()
} }
} }
// newroute
{
printf("newroute\n");
uint32_t gateway;
int ret = inet_pton(AF_INET, "192.168.1.1", (void *)&gateway);
assert(ret == 1);
int dret = rtnetlink::send_newroute(fd, if_index.ifr_ifindex, gateway);
if (dret < 0) {
exit(EXIT_FAILURE);
}
int eret = rtnetlink::handle_error(fd);
if (eret < 0) {
exit(EXIT_FAILURE);
}
}
return 0; return 0;
} }

View File

@ -18,7 +18,7 @@ static inline int align4(int len)
return (len + 3) & (~3); return (len + 3) & (~3);
} }
struct newaddr_msg { struct getaddr_msg {
struct nlmsghdr nl; struct nlmsghdr nl;
struct ifaddrmsg ifaddr; struct ifaddrmsg ifaddr;
}; };
@ -32,6 +32,15 @@ struct deladdr_msg {
} attr[2]; } attr[2];
}; };
struct newroute_msg {
struct nlmsghdr nl;
struct rtmsg rt;
struct {
struct rtattr rtattr;
uint32_t value;
} attr[2];
};
namespace rtnetlink { namespace rtnetlink {
bool parse_newaddr(uint8_t const * buf, ssize_t length, bool parse_newaddr(uint8_t const * buf, ssize_t length,
@ -127,9 +136,9 @@ namespace rtnetlink {
int send_getaddr(int fd, uint32_t ifa_index) int send_getaddr(int fd, uint32_t ifa_index)
{ {
const size_t message_length = (sizeof (struct newaddr_msg)); const size_t message_length = (sizeof (struct getaddr_msg));
struct newaddr_msg rtmmsg = { struct getaddr_msg rtmmsg = {
.nl = { .nl = {
.nlmsg_len = message_length, .nlmsg_len = message_length,
.nlmsg_type = RTM_GETADDR, .nlmsg_type = RTM_GETADDR,
@ -218,6 +227,59 @@ namespace rtnetlink {
return 0; return 0;
} }
int send_newroute(int fd, uint32_t ifa_index, uint32_t gateway)
{
const size_t message_length = (sizeof (struct newroute_msg));
struct newroute_msg rtmmsg = {
.nl = {
.nlmsg_len = message_length,
.nlmsg_type = RTM_NEWROUTE,
.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK | NLM_F_EXCL | NLM_F_CREATE,
.nlmsg_seq = 123456,
},
.rt = {
.rtm_family = AF_INET,
.rtm_table = RT_TABLE_MAIN,
.rtm_protocol = RTPROT_BOOT,
.rtm_scope = RT_SCOPE_UNIVERSE,
.rtm_type = RTN_UNICAST,
},
.attr = {
{
.rtattr = { .rta_len = 8, .rta_type = RTA_GATEWAY },
.value = gateway,
},
{
.rtattr = { .rta_len = 8, .rta_type = RTA_OIF },
.value = ifa_index,
}
}
};
struct iovec iov[1] = {
{
.iov_base = &rtmmsg,
.iov_len = message_length,
}
};
struct sockaddr_nl addr = { .nl_family = AF_NETLINK };
struct msghdr msg = {
.msg_name = (void *)&addr,
.msg_namelen = (sizeof (sockaddr_nl)),
.msg_iov = iov,
.msg_iovlen = 1,
};
ssize_t sret = sendmsg(fd, &msg, 0);
if (sret < 0) {
perror("sendmsg");
return -1;
}
return 0;
}
int handle_error(int fd) int handle_error(int fd)
{ {
struct sockaddr_nl addr = { .nl_family = AF_NETLINK }; struct sockaddr_nl addr = { .nl_family = AF_NETLINK };

View File

@ -19,5 +19,7 @@ namespace rtnetlink {
int send_getaddr(int fd, uint32_t ifa_index); int send_getaddr(int fd, uint32_t ifa_index);
int send_typeaddr(int fd, uint16_t nlmsg_type, uint32_t ifa_index, uint8_t ifa_prefixlen, uint32_t local, uint32_t address); int send_typeaddr(int fd, uint16_t nlmsg_type, uint32_t ifa_index, uint8_t ifa_prefixlen, uint32_t local, uint32_t address);
int send_newroute(int fd, uint32_t ifa_index, uint32_t gateway);
int handle_error(int fd); int handle_error(int fd);
} }