1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
|
#include <stdio.h>
#include <stdlib.h>
#include <sys/sysctl.h>
#include <net/route.h>
#include <sys/socket.h>
#include <netinet/in.h>
/*
mostly ripped. just outputs routes from KRT on NetBSD.
used to look closer at a difference of output from route and netstat.
*/
get_rtaddrs(int addrs, struct sockaddr *sa, struct sockaddr **rti_info)
{
int i;
for (i = 0; i < RTAX_MAX; i++) {
if (addrs & (1 << i)) {
rti_info[i] = sa;
sa = (struct sockaddr *)((char *)(sa) +
RT_ROUNDUP(sa->sa_len));
} else
rti_info[i] = NULL;
}
}
void print_sa6(struct sockaddr *sa) {
int i=0;
struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *)sa;
struct in6_addr *in6 = &sa6->sin6_addr;
if(sa) {
for(i=0;i<16;i++) {
printf("%02x",(unsigned char)in6->s6_addr[i]);
i++;
printf("%02x",(unsigned char)in6->s6_addr[i]);
if(i != 15) printf(":");
}
} else {
printf("none");
}
printf("\n");
}
void p_rtentry(struct rt_msghdr *rtm) {
struct sockadrr *sa = (rtm+1);
struct sockaddr *rti_info[RTAX_MAX];
struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *)sa;
struct in6_addr *in6 = &sa6->sin6_addr;
get_rtaddrs(rtm->rtm_addrs, sa, rti_info);
printf("addr: ");
print_sa6(rti_info[RTAX_DST]);
printf("mask: ");
print_sa6(rti_info[RTAX_NETMASK]);
printf("gate: ");
print_sa6(rti_info[RTAX_GATEWAY]);
printf("\n");
}
int main() {
// sysctl(const int *name, u_int namelen, void *oldp, size_t *oldlenp,
// const void *newp, size_t newlen);
int needed;
struct rt_msghdr *rtm;
struct sockaddr *sa;
char *buf,*next,*lim;
int mib[6];
mib[0]=CTL_NET;
mib[1]=PF_ROUTE;
mib[2]=0;
mib[3]=AF_INET6;
mib[4]=NET_RT_DUMP;
mib[5]=0;
sysctl(mib,6,NULL,&needed,NULL,0);
buf=malloc(needed);
sysctl(mib,6,buf,&needed,NULL,0);
lim=buf+needed;
if (buf) {
for (next = buf; next < lim; next += rtm->rtm_msglen) {
rtm = (struct rt_msghdr *)next;
sa = (struct sockaddr *)(rtm + 1);
if (sa->sa_family != AF_INET6)
continue;
p_rtentry(rtm);
}
free(buf);
buf = NULL;
}
}
|