From 718e3744195351130f4ce7dbe0613f4b3e23df93 Mon Sep 17 00:00:00 2001 From: paul Date: Fri, 13 Dec 2002 20:15:29 +0000 Subject: Initial revision --- zebra/rtread_proc.c | 169 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 169 insertions(+) create mode 100644 zebra/rtread_proc.c (limited to 'zebra/rtread_proc.c') diff --git a/zebra/rtread_proc.c b/zebra/rtread_proc.c new file mode 100644 index 00000000..320152e7 --- /dev/null +++ b/zebra/rtread_proc.c @@ -0,0 +1,169 @@ +/* + * Kernel routing readup by /proc filesystem + * Copyright (C) 1997 Kunihiro Ishiguro + * + * This file is part of GNU Zebra. + * + * GNU Zebra is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * GNU Zebra is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Zebra; see the file COPYING. If not, write to the Free + * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#include + +#include "prefix.h" +#include "log.h" +#include "if.h" +#include "rib.h" + +/* Proc file system to read IPv4 routing table. */ +#ifndef _PATH_PROCNET_ROUTE +#define _PATH_PROCNET_ROUTE "/proc/net/route" +#endif /* _PATH_PROCNET_ROUTE */ + +/* Proc file system to read IPv6 routing table. */ +#ifndef _PATH_PROCNET_ROUTE6 +#define _PATH_PROCNET_ROUTE6 "/proc/net/ipv6_route" +#endif /* _PATH_PROCNET_ROUTE6 */ + +/* To read interface's name */ +#define INTERFACE_NAMSIZ 20 + +/* Reading buffer for one routing entry. */ +#define RT_BUFSIZ 1024 + +/* Kernel routing table read up by /proc filesystem. */ +int +proc_route_read () +{ + FILE *fp; + char buf[RT_BUFSIZ]; + char iface[INTERFACE_NAMSIZ], dest[9], gate[9], mask[9]; + int flags, refcnt, use, metric, mtu, window, rtt; + + /* Open /proc filesystem */ + fp = fopen (_PATH_PROCNET_ROUTE, "r"); + if (fp == NULL) + { + zlog_warn ("Can't open %s : %s\n", _PATH_PROCNET_ROUTE, strerror (errno)); + return -1; + } + + /* Drop first label line. */ + fgets (buf, RT_BUFSIZ, fp); + + while (fgets (buf, RT_BUFSIZ, fp) != NULL) + { + int n; + struct prefix_ipv4 p; + struct in_addr tmpmask; + struct in_addr gateway; + u_char zebra_flags = 0; + + n = sscanf (buf, "%s %s %s %x %d %d %d %s %d %d %d", + iface, dest, gate, &flags, &refcnt, &use, &metric, + mask, &mtu, &window, &rtt); + if (n != 11) + { + zlog_warn ("can't read all of routing information\n"); + continue; + } + if (! (flags & RTF_UP)) + continue; + if (! (flags & RTF_GATEWAY)) + continue; + + if (flags & RTF_DYNAMIC) + zebra_flags |= ZEBRA_FLAG_SELFROUTE; + + p.family = AF_INET; + sscanf (dest, "%lX", (unsigned long *)&p.prefix); + sscanf (mask, "%lX", (unsigned long *)&tmpmask); + p.prefixlen = ip_masklen (tmpmask); + sscanf (gate, "%lX", (unsigned long *)&gateway); + + rib_add_ipv4 (ZEBRA_ROUTE_KERNEL, zebra_flags, &p, &gateway, 0, 0, 0, 0); + } + + return 0; +} + +#ifdef HAVE_IPV6 +int +proc_ipv6_route_read () +{ + FILE *fp; + char buf [RT_BUFSIZ]; + + /* Open /proc filesystem */ + fp = fopen (_PATH_PROCNET_ROUTE6, "r"); + if (fp == NULL) + { + zlog_warn ("Can't open %s : %s", _PATH_PROCNET_ROUTE6, + strerror (errno)); + return -1; + } + + /* There is no title line, so we don't drop first line. */ + while (fgets (buf, RT_BUFSIZ, fp) != NULL) + { + int n; + char dest[33], src[33], gate[33]; + char iface[INTERFACE_NAMSIZ]; + int dest_plen, src_plen; + int metric, use, refcnt, flags; + struct prefix_ipv6 p; + struct in6_addr gateway; + u_char zebra_flags = 0; + + /* Linux 2.1.x write this information at net/ipv6/route.c + rt6_info_node () */ + n = sscanf (buf, "%32s %02x %32s %02x %32s %08x %08x %08x %08x %s", + dest, &dest_plen, src, &src_plen, gate, + &metric, &use, &refcnt, &flags, iface); + + if (n != 10) + { + /* zlog_warn ("can't read all of routing information %d\n%s\n", n, buf); */ + continue; + } + + if (! (flags & RTF_UP)) + continue; + if (! (flags & RTF_GATEWAY)) + continue; + + if (flags & RTF_DYNAMIC) + zebra_flags |= ZEBRA_FLAG_SELFROUTE; + + p.family = AF_INET6; + str2in6_addr (dest, &p.prefix); + str2in6_addr (gate, &gateway); + p.prefixlen = dest_plen; + + rib_add_ipv6 (ZEBRA_ROUTE_KERNEL, zebra_flags, &p, &gateway, 0, 0); + } + + return 0; +} +#endif /* HAVE_IPV6 */ + +void +route_read () +{ + proc_route_read (); +#ifdef HAVE_IPV6 + proc_ipv6_route_read (); +#endif /* HAVE_IPV6 */ +} -- cgit v1.2.1