Import Upstream version 1.2.2
[quagga-debian.git] / zebra / if_sysctl.c
1 /*
2  * Get interface's address and mask information by sysctl() function.
3  * Copyright (C) 1997, 98 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 "if.h"
26 #include "sockunion.h"
27 #include "prefix.h"
28 #include "connected.h"
29 #include "memory.h"
30 #include "ioctl.h"
31 #include "log.h"
32 #include "interface.h"
33 #include "vrf.h"
34
35 #include "zebra/rt.h"
36 #include "zebra/kernel_socket.h"
37 #include "zebra/rib.h"
38
39 void
40 ifstat_update_sysctl (void)
41 {
42   caddr_t ref, buf, end;
43   size_t bufsiz;
44   struct if_msghdr *ifm;
45   struct interface *ifp;
46
47 #define MIBSIZ 6
48   int mib[MIBSIZ] =
49   { 
50     CTL_NET,
51     PF_ROUTE,
52     0,
53     0, /*  AF_INET & AF_INET6 */
54     NET_RT_IFLIST,
55     0 
56   };
57
58   /* Query buffer size. */
59   if (sysctl (mib, MIBSIZ, NULL, &bufsiz, NULL, 0) < 0) 
60     {
61       zlog_warn ("sysctl() error by %s", safe_strerror (errno));
62       return;
63     }
64
65   /* We free this memory at the end of this function. */
66   ref = buf = XMALLOC (MTYPE_TMP, bufsiz);
67
68   /* Fetch interface informations into allocated buffer. */
69   if (sysctl (mib, MIBSIZ, buf, &bufsiz, NULL, 0) < 0) 
70     {
71       zlog (NULL, LOG_WARNING, "sysctl error by %s", safe_strerror (errno));
72       return;
73     }
74
75   /* Parse both interfaces and addresses. */
76   for (end = buf + bufsiz; buf < end; buf += ifm->ifm_msglen) 
77     {
78       ifm = (struct if_msghdr *) buf;
79       if (ifm->ifm_type == RTM_IFINFO)
80         {
81           ifp = if_lookup_by_index (ifm->ifm_index);
82           if (ifp)
83             ifp->stats = ifm->ifm_data;
84         }
85     }
86
87   /* Free sysctl buffer. */
88   XFREE (MTYPE_TMP, ref);
89
90   return;
91 }
92
93 /* Interface listing up function using sysctl(). */
94 void
95 interface_list (struct zebra_vrf *zvrf)
96 {
97   caddr_t ref, buf, end;
98   size_t bufsiz;
99   struct if_msghdr *ifm;
100
101 #define MIBSIZ 6
102   int mib[MIBSIZ] =
103   { 
104     CTL_NET,
105     PF_ROUTE,
106     0,
107     0, /*  AF_INET & AF_INET6 */
108     NET_RT_IFLIST,
109     0 
110   };
111
112   if (zvrf->vrf_id != VRF_DEFAULT)
113     {
114       zlog_warn ("interface_list: ignore VRF %u", zvrf->vrf_id);
115       return;
116     }
117
118   /* Query buffer size. */
119   if (sysctl (mib, MIBSIZ, NULL, &bufsiz, NULL, 0) < 0) 
120     {
121       zlog (NULL, LOG_WARNING, "sysctl() error by %s", safe_strerror (errno));
122       return;
123     }
124
125   /* We free this memory at the end of this function. */
126   ref = buf = XMALLOC (MTYPE_TMP, bufsiz);
127
128   /* Fetch interface informations into allocated buffer. */
129   if (sysctl (mib, MIBSIZ, buf, &bufsiz, NULL, 0) < 0) 
130     {
131       zlog (NULL, LOG_WARNING, "sysctl error by %s", safe_strerror (errno));
132       return;
133     }
134
135   /* Parse both interfaces and addresses. */
136   for (end = buf + bufsiz; buf < end; buf += ifm->ifm_msglen) 
137     {
138       ifm = (struct if_msghdr *) buf;
139
140       switch (ifm->ifm_type) 
141         {
142         case RTM_IFINFO:
143           ifm_read (ifm);
144           break;
145         case RTM_NEWADDR:
146           ifam_read ((struct ifa_msghdr *) ifm);
147           break;
148         default:
149           zlog_info ("interfaces_list(): unexpected message type");
150           XFREE (MTYPE_TMP, ref);
151           return;
152           break;
153         }
154     }
155
156   /* Free sysctl buffer. */
157   XFREE (MTYPE_TMP, ref);
158 }