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 30/* Proc file system to read IPv4 routing table. */ 31#ifndef _PATH_PROCNET_ROUTE 32#define _PATH_PROCNET_ROUTE "/proc/net/route" 33#endif /* _PATH_PROCNET_ROUTE */ 34 35/* Proc file system to read IPv6 routing table. */ 36#ifndef _PATH_PROCNET_ROUTE6 37#define _PATH_PROCNET_ROUTE6 "/proc/net/ipv6_route" 38#endif /* _PATH_PROCNET_ROUTE6 */ 39 40/* To read interface's name */ 41#define INTERFACE_NAMSIZ 20 42 43/* Reading buffer for one routing entry. */ 44#define RT_BUFSIZ 1024 45 46/* Kernel routing table read up by /proc filesystem. */ 47int 48proc_route_read () 49{ 50 FILE *fp; 51 char buf[RT_BUFSIZ]; 52 char iface[INTERFACE_NAMSIZ], dest[9], gate[9], mask[9]; 53 int flags, refcnt, use, metric, mtu, window, rtt; 54 55 /* Open /proc filesystem */ 56 fp = fopen (_PATH_PROCNET_ROUTE, "r"); 57 if (fp == NULL) 58 { 59 zlog_warn ("Can't open %s : %s\n", _PATH_PROCNET_ROUTE, strerror (errno)); 60 return -1; 61 } 62 63 /* Drop first label line. */ 64 fgets (buf, RT_BUFSIZ, fp); 65 66 while (fgets (buf, RT_BUFSIZ, fp) != NULL) 67 { 68 int n; 69 struct prefix_ipv4 p; 70 struct in_addr tmpmask; 71 struct in_addr gateway; 72 u_char zebra_flags = 0; 73 74 n = sscanf (buf, "%s %s %s %x %d %d %d %s %d %d %d", 75 iface, dest, gate, &flags, &refcnt, &use, &metric, 76 mask, &mtu, &window, &rtt); 77 if (n != 11) 78 { 79 zlog_warn ("can't read all of routing information\n"); 80 continue; 81 } 82 if (! (flags & RTF_UP)) 83 continue; 84 if (! (flags & RTF_GATEWAY)) 85 continue; 86 87 if (flags & RTF_DYNAMIC) 88 zebra_flags |= ZEBRA_FLAG_SELFROUTE; 89 90 p.family = AF_INET; 91 sscanf (dest, "%lX", (unsigned long *)&p.prefix); 92 sscanf (mask, "%lX", (unsigned long *)&tmpmask); 93 p.prefixlen = ip_masklen (tmpmask); 94 sscanf (gate, "%lX", (unsigned long *)&gateway); 95 96 rib_add_ipv4 (ZEBRA_ROUTE_KERNEL, zebra_flags, &p, &gateway, 0, 0, 0, 0); 97 } 98 99 return 0; 100} 101 102#ifdef HAVE_IPV6 103int 104proc_ipv6_route_read () 105{ 106 FILE *fp; 107 char buf [RT_BUFSIZ]; 108 109 /* Open /proc filesystem */ 110 fp = fopen (_PATH_PROCNET_ROUTE6, "r"); 111 if (fp == NULL) 112 { 113 zlog_warn ("Can't open %s : %s", _PATH_PROCNET_ROUTE6, 114 strerror (errno)); 115 return -1; 116 } 117 118 /* There is no title line, so we don't drop first line. */ 119 while (fgets (buf, RT_BUFSIZ, fp) != NULL) 120 { 121 int n; 122 char dest[33], src[33], gate[33]; 123 char iface[INTERFACE_NAMSIZ]; 124 int dest_plen, src_plen; 125 int metric, use, refcnt, flags; 126 struct prefix_ipv6 p; 127 struct in6_addr gateway; 128 u_char zebra_flags = 0; 129 130 /* Linux 2.1.x write this information at net/ipv6/route.c 131 rt6_info_node () */ 132 n = sscanf (buf, "%32s %02x %32s %02x %32s %08x %08x %08x %08x %s", 133 dest, &dest_plen, src, &src_plen, gate, 134 &metric, &use, &refcnt, &flags, iface); 135 136 if (n != 10) 137 { 138 /* zlog_warn ("can't read all of routing information %d\n%s\n", n, buf); */ 139 continue; 140 } 141 142 if (! (flags & RTF_UP)) 143 continue; 144 if (! (flags & RTF_GATEWAY)) 145 continue; 146 147 if (flags & RTF_DYNAMIC) 148 zebra_flags |= ZEBRA_FLAG_SELFROUTE; 149 150 p.family = AF_INET6; 151 str2in6_addr (dest, &p.prefix); 152 str2in6_addr (gate, &gateway); 153 p.prefixlen = dest_plen; 154 155 rib_add_ipv6 (ZEBRA_ROUTE_KERNEL, zebra_flags, &p, &gateway, 0, 0); 156 } 157 158 return 0; 159} 160#endif /* HAVE_IPV6 */ 161 162void 163route_read () 164{ 165 proc_route_read (); 166#ifdef HAVE_IPV6 167 proc_ipv6_route_read (); 168#endif /* HAVE_IPV6 */ 169} 170