]>
Commit | Line | Data |
---|---|---|
718e3744 | 1 | /* |
2 | * Kernel routing readup by /proc filesystem | |
3 | * Copyright (C) 1997 Kunihiro Ishiguro | |
4 | * | |
5 | * This file is part of GNU Zebra. | |
6 | * | |
7 | * GNU Zebra is free software; you can redistribute it and/or modify it | |
8 | * under the terms of the GNU General Public License as published by the | |
9 | * Free Software Foundation; either version 2, or (at your option) any | |
10 | * later version. | |
11 | * | |
12 | * GNU Zebra is distributed in the hope that it will be useful, but | |
13 | * WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
15 | * General Public License for more details. | |
16 | * | |
17 | * You should have received a copy of the GNU General Public License | |
18 | * along with GNU Zebra; see the file COPYING. If not, write to the Free | |
19 | * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | |
20 | * 02111-1307, USA. | |
21 | */ | |
22 | ||
23 | #include <zebra.h> | |
24 | ||
25 | #include "prefix.h" | |
26 | #include "log.h" | |
27 | #include "if.h" | |
28 | #include "rib.h" | |
29 | ||
a1ac18c4 | 30 | #include "zebra/zserv.h" |
31 | #include "zebra/rt.h" | |
32 | ||
718e3744 | 33 | /* Proc file system to read IPv4 routing table. */ |
34 | #ifndef _PATH_PROCNET_ROUTE | |
35 | #define _PATH_PROCNET_ROUTE "/proc/net/route" | |
36 | #endif /* _PATH_PROCNET_ROUTE */ | |
37 | ||
38 | /* Proc file system to read IPv6 routing table. */ | |
39 | #ifndef _PATH_PROCNET_ROUTE6 | |
40 | #define _PATH_PROCNET_ROUTE6 "/proc/net/ipv6_route" | |
41 | #endif /* _PATH_PROCNET_ROUTE6 */ | |
42 | ||
43 | /* To read interface's name */ | |
44 | #define INTERFACE_NAMSIZ 20 | |
45 | ||
46 | /* Reading buffer for one routing entry. */ | |
47 | #define RT_BUFSIZ 1024 | |
48 | ||
49 | /* Kernel routing table read up by /proc filesystem. */ | |
a1ac18c4 | 50 | static int |
51 | proc_route_read (void) | |
718e3744 | 52 | { |
53 | FILE *fp; | |
54 | char buf[RT_BUFSIZ]; | |
55 | char iface[INTERFACE_NAMSIZ], dest[9], gate[9], mask[9]; | |
56 | int flags, refcnt, use, metric, mtu, window, rtt; | |
57 | ||
58 | /* Open /proc filesystem */ | |
59 | fp = fopen (_PATH_PROCNET_ROUTE, "r"); | |
60 | if (fp == NULL) | |
61 | { | |
6099b3b5 | 62 | zlog_warn ("Can't open %s : %s\n", _PATH_PROCNET_ROUTE, safe_strerror (errno)); |
718e3744 | 63 | return -1; |
64 | } | |
65 | ||
66 | /* Drop first label line. */ | |
67 | fgets (buf, RT_BUFSIZ, fp); | |
68 | ||
69 | while (fgets (buf, RT_BUFSIZ, fp) != NULL) | |
70 | { | |
71 | int n; | |
72 | struct prefix_ipv4 p; | |
73 | struct in_addr tmpmask; | |
74 | struct in_addr gateway; | |
75 | u_char zebra_flags = 0; | |
76 | ||
77 | n = sscanf (buf, "%s %s %s %x %d %d %d %s %d %d %d", | |
78 | iface, dest, gate, &flags, &refcnt, &use, &metric, | |
79 | mask, &mtu, &window, &rtt); | |
80 | if (n != 11) | |
81 | { | |
82 | zlog_warn ("can't read all of routing information\n"); | |
83 | continue; | |
84 | } | |
85 | if (! (flags & RTF_UP)) | |
86 | continue; | |
87 | if (! (flags & RTF_GATEWAY)) | |
88 | continue; | |
89 | ||
90 | if (flags & RTF_DYNAMIC) | |
91 | zebra_flags |= ZEBRA_FLAG_SELFROUTE; | |
92 | ||
93 | p.family = AF_INET; | |
94 | sscanf (dest, "%lX", (unsigned long *)&p.prefix); | |
95 | sscanf (mask, "%lX", (unsigned long *)&tmpmask); | |
96 | p.prefixlen = ip_masklen (tmpmask); | |
97 | sscanf (gate, "%lX", (unsigned long *)&gateway); | |
98 | ||
99 | rib_add_ipv4 (ZEBRA_ROUTE_KERNEL, zebra_flags, &p, &gateway, 0, 0, 0, 0); | |
100 | } | |
101 | ||
42a66d7c | 102 | fclose (fp); |
718e3744 | 103 | return 0; |
104 | } | |
105 | ||
106 | #ifdef HAVE_IPV6 | |
a1ac18c4 | 107 | static int |
718e3744 | 108 | proc_ipv6_route_read () |
109 | { | |
110 | FILE *fp; | |
111 | char buf [RT_BUFSIZ]; | |
112 | ||
113 | /* Open /proc filesystem */ | |
114 | fp = fopen (_PATH_PROCNET_ROUTE6, "r"); | |
115 | if (fp == NULL) | |
116 | { | |
117 | zlog_warn ("Can't open %s : %s", _PATH_PROCNET_ROUTE6, | |
6099b3b5 | 118 | safe_strerror (errno)); |
718e3744 | 119 | return -1; |
120 | } | |
121 | ||
122 | /* There is no title line, so we don't drop first line. */ | |
123 | while (fgets (buf, RT_BUFSIZ, fp) != NULL) | |
124 | { | |
125 | int n; | |
126 | char dest[33], src[33], gate[33]; | |
127 | char iface[INTERFACE_NAMSIZ]; | |
128 | int dest_plen, src_plen; | |
129 | int metric, use, refcnt, flags; | |
130 | struct prefix_ipv6 p; | |
131 | struct in6_addr gateway; | |
132 | u_char zebra_flags = 0; | |
133 | ||
134 | /* Linux 2.1.x write this information at net/ipv6/route.c | |
135 | rt6_info_node () */ | |
136 | n = sscanf (buf, "%32s %02x %32s %02x %32s %08x %08x %08x %08x %s", | |
137 | dest, &dest_plen, src, &src_plen, gate, | |
138 | &metric, &use, &refcnt, &flags, iface); | |
139 | ||
140 | if (n != 10) | |
141 | { | |
142 | /* zlog_warn ("can't read all of routing information %d\n%s\n", n, buf); */ | |
143 | continue; | |
144 | } | |
145 | ||
146 | if (! (flags & RTF_UP)) | |
147 | continue; | |
148 | if (! (flags & RTF_GATEWAY)) | |
149 | continue; | |
150 | ||
151 | if (flags & RTF_DYNAMIC) | |
152 | zebra_flags |= ZEBRA_FLAG_SELFROUTE; | |
153 | ||
154 | p.family = AF_INET6; | |
155 | str2in6_addr (dest, &p.prefix); | |
156 | str2in6_addr (gate, &gateway); | |
157 | p.prefixlen = dest_plen; | |
158 | ||
159 | rib_add_ipv6 (ZEBRA_ROUTE_KERNEL, zebra_flags, &p, &gateway, 0, 0); | |
160 | } | |
161 | ||
42a66d7c | 162 | fclose (fp); |
718e3744 | 163 | return 0; |
164 | } | |
165 | #endif /* HAVE_IPV6 */ | |
166 | ||
167 | void | |
a1ac18c4 | 168 | route_read (void) |
718e3744 | 169 | { |
170 | proc_route_read (); | |
171 | #ifdef HAVE_IPV6 | |
172 | proc_ipv6_route_read (); | |
173 | #endif /* HAVE_IPV6 */ | |
174 | } |