]>
git.proxmox.com Git - mirror_frr.git/blob - pimd/mtracebis_routeget.c
2 * Multicast Traceroute for FRRouting
3 * Copyright (C) 2018 Mladen Sablic
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
15 * You should have received a copy of the GNU General Public License along
16 * with this program; see the file COPYING; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
26 #include <asm/types.h>
27 #include <linux/netlink.h>
28 #include <linux/rtnetlink.h>
29 #include <sys/types.h>
31 #include <arpa/inet.h>
34 #include "mtracebis_netlink.h"
35 #include "mtracebis_routeget.h"
37 static int find_dst(struct nlmsghdr
*n
, struct in_addr
*src
, struct in_addr
*gw
)
39 struct rtmsg
*r
= NLMSG_DATA(n
);
40 int len
= n
->nlmsg_len
;
41 struct rtattr
*tb
[RTA_MAX
+ 1];
43 len
-= NLMSG_LENGTH(sizeof(*r
));
45 fprintf(stderr
, "BUG: wrong nlmsg len %d\n", len
);
49 parse_rtattr(tb
, RTA_MAX
, RTM_RTA(r
), len
);
51 src
->s_addr
= *(uint32_t *)RTA_DATA(tb
[RTA_PREFSRC
]);
53 gw
->s_addr
= *(uint32_t *)RTA_DATA(tb
[RTA_GATEWAY
]);
55 return *(int *)RTA_DATA(tb
[RTA_OIF
]);
59 int routeget(struct in_addr dst
, struct in_addr
*src
, struct in_addr
*gw
)
67 struct rtnl_handle rth
= {.fd
= -1};
69 memset(&req
, 0, sizeof(req
));
71 req
.n
.nlmsg_len
= NLMSG_LENGTH(sizeof(struct rtmsg
));
72 req
.n
.nlmsg_flags
= NLM_F_REQUEST
;
73 req
.n
.nlmsg_type
= RTM_GETROUTE
;
74 req
.r
.rtm_family
= AF_INET
;
76 req
.r
.rtm_protocol
= 0;
79 req
.r
.rtm_src_len
= 0;
80 req
.r
.rtm_dst_len
= 0;
83 addattr_l(&req
.n
, sizeof(req
), RTA_DST
, &dst
.s_addr
, 4);
84 req
.r
.rtm_dst_len
= 32;
86 ret
= rtnl_open(&rth
, 0);
88 if (ret
< 0 || rth
.fd
<= 0)
91 if (rtnl_talk(&rth
, &req
.n
, 0, 0, &req
.n
, NULL
, NULL
) < 0) {
96 ret
= find_dst(&req
.n
, src
, gw
);
102 #endif /* __linux__ */