8b4d3de1a0e402100dfaf19d43f03f6edde9a04e
[olsrd.git] / src / win32 / kernel_routes.c
1
2 /*
3  * The olsr.org Optimized Link-State Routing daemon(olsrd)
4  * Copyright (c) 2004-2009, the olsr.org team - see HISTORY file
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * * Redistributions of source code must retain the above copyright
12  *   notice, this list of conditions and the following disclaimer.
13  * * Redistributions in binary form must reproduce the above copyright
14  *   notice, this list of conditions and the following disclaimer in
15  *   the documentation and/or other materials provided with the
16  *   distribution.
17  * * Neither the name of olsr.org, olsrd nor the names of its
18  *   contributors may be used to endorse or promote products derived
19  *   from this software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32  * POSSIBILITY OF SUCH DAMAGE.
33  *
34  * Visit http://www.olsr.org for more information.
35  *
36  * If you find this software useful feel free to make a donation
37  * to the project. For more information see the website or contact
38  * the copyright holders.
39  *
40  */
41
42 #include <stdio.h>
43 #include "net/route.h"
44
45 #include "kernel_routes.h"
46 #include "net_olsr.h"
47 #include "ipcalc.h"
48 #include "routing_table.h"
49 #include "olsr_logging.h"
50
51 #define WIN32_LEAN_AND_MEAN
52 #include <iprtrmib.h>
53 #include <iphlpapi.h>
54
55 #include <errno.h>
56
57 char *StrError(unsigned int ErrNo);
58
59 /*
60  * Insert a route in the kernel routing table
61  * @param destination the route to add
62  * @return negative on error
63  */
64 int
65 olsr_kernel_add_route(const struct rt_entry *rt, int ip_version)
66 {
67   MIB_IPFORWARDROW Row;
68   union olsr_ip_addr mask;
69   unsigned long Res;
70   struct interface *iface = rt->rt_best->rtp_nexthop.interface;
71
72   if (AF_INET != ip_version) {
73     /*
74      * Not implemented
75      */
76     return -1;
77   }
78
79
80   OLSR_DEBUG(LOG_ROUTING, "KERN: Adding %s\n", olsr_rt_to_string(rt));
81
82   memset(&Row, 0, sizeof(MIB_IPFORWARDROW));
83
84   Row.dwForwardDest = rt->rt_dst.prefix.v4.s_addr;
85
86   if (!olsr_prefix_to_netmask(&mask, rt->rt_dst.prefix_len)) {
87     return -1;
88   } else {
89     Row.dwForwardMask = mask.v4.s_addr;
90   }
91
92   Row.dwForwardPolicy = 0;
93   Row.dwForwardNextHop = rt->rt_best->rtp_nexthop.gateway.v4.s_addr;
94   Row.dwForwardIfIndex = iface->if_index;
95   // MIB_IPROUTE_TYPE_DIRECT and MIB_IPROUTE_TYPE_INDIRECT
96   Row.dwForwardType = (rt->rt_dst.prefix.v4.s_addr == rt->rt_best->rtp_nexthop.gateway.v4.s_addr) ? 3 : 4;
97   Row.dwForwardProto = 3;       // MIB_IPPROTO_NETMGMT
98   Row.dwForwardAge = INFINITE;
99   Row.dwForwardNextHopAS = 0;
100   Row.dwForwardMetric1 = olsr_fib_metric(&rt->rt_best->rtp_metric);
101   Row.dwForwardMetric2 = -1;
102   Row.dwForwardMetric3 = -1;
103   Row.dwForwardMetric4 = -1;
104   Row.dwForwardMetric5 = -1;
105
106   Res = SetIpForwardEntry(&Row);
107
108   if (Res != NO_ERROR) {
109     if (Res != ERROR_NOT_FOUND)
110       OLSR_WARN(LOG_ROUTING, "SetIpForwardEntry() = %08lx, %s", Res, StrError(Res));
111
112     Res = CreateIpForwardEntry(&Row);
113   }
114
115   if (Res != NO_ERROR) {
116     OLSR_WARN(LOG_ROUTING, "CreateIpForwardEntry() = %08lx, %s", Res, StrError(Res));
117
118     // XXX - report error in a different way
119
120     errno = Res;
121
122     return -1;
123   }
124
125   return 0;
126 }
127
128
129 /*
130  * Remove a route from the kernel
131  * @param destination the route to remove
132  * @return negative on error
133  */
134 int
135 olsr_kernel_del_route(const struct rt_entry *rt, int ip_version)
136 {
137   MIB_IPFORWARDROW Row;
138   union olsr_ip_addr mask;
139   unsigned long Res;
140   struct interface *iface = rt->rt_nexthop.interface;
141
142   if (AF_INET != ip_version) {
143     /*
144      * Not implemented
145      */
146     return -1;
147   }
148
149   OLSR_DEBUG(LOG_NETWORKING, "KERN: Deleting %s\n", olsr_rt_to_string(rt));
150
151   memset(&Row, 0, sizeof(Row));
152
153   Row.dwForwardDest = rt->rt_dst.prefix.v4.s_addr;
154
155   if (!olsr_prefix_to_netmask(&mask, rt->rt_dst.prefix_len)) {
156     return -1;
157   }
158   Row.dwForwardMask = mask.v4.s_addr;
159   Row.dwForwardPolicy = 0;
160   Row.dwForwardNextHop = rt->rt_nexthop.gateway.v4.s_addr;
161   Row.dwForwardIfIndex = iface->if_index;
162   // MIB_IPROUTE_TYPE_DIRECT and MIB_IPROUTE_TYPE_INDIRECT
163   Row.dwForwardType = (rt->rt_dst.prefix.v4.s_addr == rt->rt_nexthop.gateway.v4.s_addr) ? 3 : 4;
164   Row.dwForwardProto = 3;       // MIB_IPPROTO_NETMGMT
165   Row.dwForwardAge = INFINITE;
166   Row.dwForwardNextHopAS = 0;
167   Row.dwForwardMetric1 = olsr_fib_metric(&rt->rt_metric);
168   Row.dwForwardMetric2 = -1;
169   Row.dwForwardMetric3 = -1;
170   Row.dwForwardMetric4 = -1;
171   Row.dwForwardMetric5 = -1;
172
173   Res = DeleteIpForwardEntry(&Row);
174
175   if (Res != NO_ERROR) {
176     OLSR_WARN(LOG_NETWORKING, "DeleteIpForwardEntry() = %08lx, %s", Res, StrError(Res));
177
178     // XXX - report error in a different way
179
180     errno = Res;
181
182     return -1;
183   }
184   return 0;
185 }
186
187 /*
188  * Local Variables:
189  * c-basic-offset: 2
190  * indent-tabs-mode: nil
191  * End:
192  */