newroute
This commit is contained in:
parent
d891ad5a48
commit
c9bb6a5965
18
netlink.cpp
18
netlink.cpp
@ -10,6 +10,7 @@
|
||||
#include <linux/netlink.h>
|
||||
#include <linux/rtnetlink.h>
|
||||
#include <net/if.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include "ip4.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;
|
||||
}
|
||||
|
||||
@ -18,7 +18,7 @@ static inline int align4(int len)
|
||||
return (len + 3) & (~3);
|
||||
}
|
||||
|
||||
struct newaddr_msg {
|
||||
struct getaddr_msg {
|
||||
struct nlmsghdr nl;
|
||||
struct ifaddrmsg ifaddr;
|
||||
};
|
||||
@ -32,6 +32,15 @@ struct deladdr_msg {
|
||||
} attr[2];
|
||||
};
|
||||
|
||||
struct newroute_msg {
|
||||
struct nlmsghdr nl;
|
||||
struct rtmsg rt;
|
||||
struct {
|
||||
struct rtattr rtattr;
|
||||
uint32_t value;
|
||||
} attr[2];
|
||||
};
|
||||
|
||||
namespace rtnetlink {
|
||||
|
||||
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)
|
||||
{
|
||||
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 = {
|
||||
.nlmsg_len = message_length,
|
||||
.nlmsg_type = RTM_GETADDR,
|
||||
@ -218,6 +227,59 @@ namespace rtnetlink {
|
||||
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)
|
||||
{
|
||||
struct sockaddr_nl addr = { .nl_family = AF_NETLINK };
|
||||
|
||||
@ -19,5 +19,7 @@ namespace rtnetlink {
|
||||
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_newroute(int fd, uint32_t ifa_index, uint32_t gateway);
|
||||
|
||||
int handle_error(int fd);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user