fe0dac151eded45f79975455b4cacda22cbde797
[olsrd.git] / src / win32 / net.c
1 /* 
2  * OLSR ad-hoc routing table management protocol
3  * Copyright (C) 2004 Thomas Lopatic (thomas@lopatic.de)
4  *
5  * Derived from its Linux counterpart.
6  * Copyright (C) 2003 Andreas T√łnnesen (andreto@ifi.uio.no)
7  *
8  * This file is part of the olsr.org OLSR daemon.
9  *
10  * olsr.org is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * olsr.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with olsr.org; if not, write to the Free Software
22  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
23  *
24  * $Id: net.c,v 1.5 2004/11/05 14:33:31 tlopatic Exp $
25  *
26  */
27
28 #include <stdio.h>
29
30 #define WIN32_LEAN_AND_MEAN
31 #include <windows.h>
32 #include <winsock2.h>
33 #include <ws2tcpip.h>
34 #include <iphlpapi.h>
35 #undef interface
36
37 void WinSockPError(char *Str);
38 void PError(char *);
39
40 int olsr_printf(int, char *, ...);
41
42 int getsocket(struct sockaddr *Addr, int BuffSize, char *Int)
43 {
44   int Sock;
45   int On = 1;
46   unsigned long Len;
47
48   Sock = socket(AF_INET, SOCK_DGRAM, 0);
49
50   if (Sock < 0)
51   {
52     WinSockPError("getsocket/socket()");
53     return -1;
54   }
55
56   if (setsockopt(Sock, SOL_SOCKET, SO_BROADCAST,
57                  (char *)&On, sizeof (On)) < 0)
58   {
59     WinSockPError("getsocket/setsockopt(SO_BROADCAST)");
60     closesocket(Sock);
61     return -1;
62   }
63
64   while (BuffSize > 8192)
65   {
66     if (setsockopt(Sock, SOL_SOCKET, SO_RCVBUF, (char *)&BuffSize,
67                    sizeof (BuffSize)) == 0)
68       break;
69
70     BuffSize -= 1024;
71   }
72
73   if (BuffSize <= 8192) 
74     fprintf(stderr, "Cannot set IPv4 socket receive buffer.\n");
75
76   if (bind(Sock, Addr, sizeof (struct sockaddr_in)) < 0)
77   {
78     WinSockPError("getsocket/bind()");
79     closesocket(Sock);
80     return -1;
81   }
82
83   if (WSAIoctl(Sock, FIONBIO, &On, sizeof (On), NULL, 0, &Len, NULL, NULL) < 0)
84   {
85     WinSockPError("WSAIoctl");
86     closesocket(Sock);
87     return -1;
88   }
89
90   return Sock;
91 }
92
93 int getsocket6(struct sockaddr_in6 *Addr, int BuffSize, char *Int)
94 {
95   int Sock;
96   int On = 1;
97
98   Sock = socket(AF_INET6, SOCK_DGRAM, 0);
99
100   if (Sock < 0)
101   {
102     WinSockPError("getsocket6/socket()");
103     return -1;
104   }
105
106   if (setsockopt(Sock, SOL_SOCKET, SO_BROADCAST,
107                  (char *)&On, sizeof (On)) < 0)
108   {
109     WinSockPError("getsocket6/setsockopt(SO_BROADCAST)");
110     closesocket(Sock);
111     return -1;
112   }
113
114   while (BuffSize > 8192)
115   {
116     if (setsockopt(Sock, SOL_SOCKET, SO_RCVBUF, (char *)&BuffSize,
117                    sizeof (BuffSize)) == 0)
118       break;
119
120     BuffSize -= 1024;
121   }
122
123   if (BuffSize <= 8192) 
124     fprintf(stderr, "Cannot set IPv6 socket receive buffer.\n");
125
126   if (bind(Sock, (struct sockaddr *)Addr, sizeof (struct sockaddr_in6)) < 0)
127   {
128     WinSockPError("getsocket6/bind()");
129     closesocket(Sock);
130     return -1;
131   }
132
133   return Sock;
134 }
135
136 static OVERLAPPED RouterOver;
137
138 int enable_ip_forwarding(int Ver)
139 {
140   HMODULE Lib;
141   unsigned int __stdcall (*EnableRouter)(HANDLE *Hand, OVERLAPPED *Over);
142   HANDLE Hand;
143
144   Ver = Ver;
145   
146   Lib = LoadLibrary("iphlpapi.dll");
147
148   if (Lib == NULL)
149     return 0;
150
151   EnableRouter = (unsigned int _stdcall (*)(HANDLE *, OVERLAPPED *))
152     GetProcAddress(Lib, "EnableRouter");
153
154   if (EnableRouter == NULL)
155     return 0;
156
157   memset(&RouterOver, 0, sizeof (OVERLAPPED));
158
159   RouterOver.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
160
161   if (RouterOver.hEvent == NULL)
162   {
163     PError("CreateEvent()");
164     return -1;
165   }
166   
167   if (EnableRouter(&Hand, &RouterOver) != ERROR_IO_PENDING)
168   {
169     PError("EnableRouter()");
170     return -1;
171   }
172
173   olsr_printf(3, "Routing enabled.\n");
174
175   return 0;
176 }
177
178 int disable_ip_forwarding(int Ver)
179 {
180   HMODULE Lib;
181   unsigned int  __stdcall (*UnenableRouter)(OVERLAPPED *Over,
182                                             unsigned int *Count);
183   unsigned int Count;
184
185   Ver = Ver;
186   
187   Lib = LoadLibrary("iphlpapi.dll");
188
189   if (Lib == NULL)
190     return 0;
191
192   UnenableRouter = (unsigned int _stdcall (*)(OVERLAPPED *, unsigned int *))
193     GetProcAddress(Lib, "UnenableRouter");
194
195   if (UnenableRouter == NULL)
196     return 0;
197
198   if (UnenableRouter(&RouterOver, &Count) != NO_ERROR)
199   {
200     PError("UnenableRouter()");
201     return -1;
202   }
203
204   olsr_printf(3, "Routing disabled, count = %u.\n", Count);
205
206   return 0;
207 }
208
209 int restore_settings(int Ver)
210 {
211   disable_ip_forwarding(Ver);
212
213   return 0;
214 }