/*
* The olsr.org Optimized Link-State Routing daemon (olsrd)
* Copyright (c) 2004, Thomas Lopatic (thomas@lopatic.de)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* * Neither the name of olsr.org, olsrd nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* Visit http://www.olsr.org for more information.
*
* If you find this software useful feel free to make a donation
* to the project. For more information see the website or contact
* the copyright holders.
*
* $Id: net.c,v 1.22 2007/04/25 22:24:09 bernd67 Exp $
*/
#if defined WINCE
#include <sys/types.h> // for time_t
#endif
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <iphlpapi.h>
#undef interface
#include <stdio.h>
#include <stdlib.h>
#include "defs.h"
#include "net_os.h"
#if defined WINCE
#define WIDE_STRING(s) L##s
#else
#define WIDE_STRING(s) s
#endif
void WinSockPError(char *Str);
void PError(char *);
void DisableIcmpRedirects(void);
int disable_ip_forwarding(int Ver);
int
gethemusocket(struct sockaddr_in *pin)
{
int sock;
OLSR_PRINTF(1, " Connecting to switch daemon port 10150...");
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
perror("hcsocket");
return (-1);
}
/* connect to PORT on HOST */
if (connect(sock,(struct sockaddr *) pin, sizeof(*pin)) < 0)
{
printf("FAILED\n");
fprintf(stderr, "Error connecting %d - %s\n", errno, strerror(errno));
printf("connection refused\n");
closesocket(sock);
return (-1);
}
printf("OK\n");
/* Keep TCP socket blocking */
return (sock);
}
int getsocket(struct sockaddr *Addr, int BuffSize, char *Int __attribute__((unused)))
{
int Sock;
int On = 1;
unsigned long Len;
Sock = socket(AF_INET, SOCK_DGRAM, 0);
if (Sock < 0)
{
WinSockPError("getsocket/socket()");
return -1;
}
if (setsockopt(Sock, SOL_SOCKET, SO_BROADCAST,
(char *)&On, sizeof (On)) < 0)
{
WinSockPError("getsocket/setsockopt(SO_BROADCAST)");
closesocket(Sock);
return -1;
}
while (BuffSize > 8192)
{
if (setsockopt(Sock, SOL_SOCKET, SO_RCVBUF, (char *)&BuffSize,
sizeof (BuffSize)) == 0)
break;
BuffSize -= 1024;
}
if (BuffSize <= 8192)
fprintf(stderr, "Cannot set IPv4 socket receive buffer.\n");
if (bind(Sock, Addr, sizeof (struct sockaddr_in)) < 0)
{
WinSockPError("getsocket/bind()");
closesocket(Sock);
return -1;
}
if (WSAIoctl(Sock, FIONBIO, &On, sizeof (On), NULL, 0, &Len, NULL, NULL) < 0)
{
WinSockPError("WSAIoctl");
closesocket(Sock);
return -1;
}
return Sock;
}
int getsocket6(struct sockaddr_in6 *Addr, int BuffSize, char *Int __attribute__((unused)))
{
int Sock;
int On = 1;
Sock = socket(AF_INET6, SOCK_DGRAM, 0);
if (Sock < 0)
{
WinSockPError("getsocket6/socket()");
return -1;
}
if (setsockopt(Sock, SOL_SOCKET, SO_BROADCAST,
(char *)&On, sizeof (On)) < 0)
{
WinSockPError("getsocket6/setsockopt(SO_BROADCAST)");
closesocket(Sock);
return -1;
}
while (BuffSize > 8192)
{
if (setsockopt(Sock, SOL_SOCKET, SO_RCVBUF, (char *)&BuffSize,
sizeof (BuffSize)) == 0)
break;
BuffSize -= 1024;
}
if (BuffSize <= 8192)
fprintf(stderr, "Cannot set IPv6 socket receive buffer.\n");
if (bind(Sock, (struct sockaddr *)Addr, sizeof (struct sockaddr_in6)) < 0)
{
WinSockPError("getsocket6/bind()");
closesocket(Sock);
return -1;
}
return Sock;
}
static OVERLAPPED RouterOver;
int enable_ip_forwarding(int Ver)
{
HMODULE Lib;
unsigned int __stdcall (*EnableRouter)(HANDLE *Hand, OVERLAPPED *Over);
HANDLE Hand;
Ver = Ver;
Lib = LoadLibrary(WIDE_STRING("iphlpapi.dll"));
if (Lib == NULL)
return 0;
EnableRouter = (unsigned int __stdcall (*)(HANDLE *, OVERLAPPED *))
GetProcAddress(Lib, WIDE_STRING("EnableRouter"));
if (EnableRouter == NULL)
return 0;
memset(&RouterOver, 0, sizeof (OVERLAPPED));
RouterOver.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
if (RouterOver.hEvent == NULL)
{
PError("CreateEvent()");
return -1;
}
if (EnableRouter(&Hand, &RouterOver) != ERROR_IO_PENDING)
{
PError("EnableRouter()");
return -1;
}
OLSR_PRINTF(3, "Routing enabled.\n");
return 0;
}
int disable_ip_forwarding(int Ver)
{
HMODULE Lib;
unsigned int __stdcall (*UnenableRouter)(OVERLAPPED *Over,
unsigned int *Count);
unsigned int Count;
Ver = Ver;
Lib = LoadLibrary(WIDE_STRING("iphlpapi.dll"));
if (Lib == NULL)
return 0;
UnenableRouter = (unsigned int __stdcall (*)(OVERLAPPED *, unsigned int *))
GetProcAddress(Lib, WIDE_STRING("UnenableRouter"));
if (UnenableRouter == NULL)
return 0;
if (UnenableRouter(&RouterOver, &Count) != NO_ERROR)
{
PError("UnenableRouter()");
return -1;
}
OLSR_PRINTF(3, "Routing disabled, count = %u.\n", Count);
return 0;
}
int restore_settings(int Ver)
{
disable_ip_forwarding(Ver);
return 0;
}
static int SetEnableRedirKey(unsigned long New)
{
#if !defined WINCE
HKEY Key;
unsigned long Type;
unsigned long Len;
unsigned long Old;
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
"SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters",
0, KEY_READ | KEY_WRITE, &Key) != ERROR_SUCCESS)
return -1;
Len = sizeof (Old);
if (RegQueryValueEx(Key, "EnableICMPRedirect", NULL, &Type,
(unsigned char *)&Old, &Len) != ERROR_SUCCESS ||
Type != REG_DWORD)
Old = 1;
if (RegSetValueEx(Key, "EnableICMPRedirect", 0, REG_DWORD,
(unsigned char *)&New, sizeof (New)))
{
RegCloseKey(Key);
return -1;
}
RegCloseKey(Key);
return Old;
#else
return 0;
#endif
}
void DisableIcmpRedirects(void)
{
int Res;
Res = SetEnableRedirKey(0);
if (Res != 1)
return;
fprintf(stderr, "\n*** IMPORTANT *** IMPORTANT *** IMPORTANT *** IMPORTANT *** IMPORTANT ***\n\n");
#if 0
if (Res < 0)
{
fprintf(stderr, "Cannot disable ICMP redirect processing in the registry.\n");
fprintf(stderr, "Please disable it manually. Continuing in 3 seconds...\n");
Sleep(3000);
return;
}
#endif
fprintf(stderr, "I have disabled ICMP redirect processing in the registry for you.\n");
fprintf(stderr, "REBOOT NOW, so that these changes take effect. Exiting...\n\n");
exit(0);
}
int join_mcast(struct interface *Nic, int Sock)
{
/* See linux/in6.h */
struct ipv6_mreq McastReq;
COPY_IP(&McastReq.ipv6mr_multiaddr, &Nic->int6_multaddr.sin6_addr);
McastReq.ipv6mr_interface = Nic->if_index;
OLSR_PRINTF(3, "Interface %s joining multicast %s...", Nic->int_name, olsr_ip_to_string((union olsr_ip_addr *)&Nic->int6_multaddr.sin6_addr));
/* Send multicast */
if(setsockopt(Sock,
IPPROTO_IPV6,
IPV6_ADD_MEMBERSHIP,
(char *)&McastReq,
sizeof(struct ipv6_mreq))
< 0)
{
perror("Join multicast");
return -1;
}
/* Old libc fix */
#ifdef IPV6_JOIN_GROUP
/* Join reciever group */
if(setsockopt(Sock,
IPPROTO_IPV6,
IPV6_JOIN_GROUP,
(char *)&McastReq,
sizeof(struct ipv6_mreq))
< 0)
#else
/* Join reciever group */
if(setsockopt(Sock,
IPPROTO_IPV6,
IPV6_ADD_MEMBERSHIP,
(char *)&McastReq,
sizeof(struct ipv6_mreq))
< 0)
#endif
{
perror("Join multicast send");
return -1;
}
if(setsockopt(Sock,
IPPROTO_IPV6,
IPV6_MULTICAST_IF,
(char *)&McastReq.ipv6mr_interface,
sizeof(McastReq.ipv6mr_interface))
< 0)
{
perror("Set multicast if");
return -1;
}
OLSR_PRINTF(3, "OK\n");
return 0;
}
/**
* Wrapper for sendto(2)
*/
ssize_t
olsr_sendto(int s,
const void *buf,
size_t len,
int flags,
const struct sockaddr *to,
socklen_t tolen)
{
return sendto(s, buf, len, flags, to, tolen);
}
/**
* Wrapper for recvfrom(2)
*/
ssize_t
olsr_recvfrom(int s,
void *buf,
size_t len,
int flags __attribute__((unused)),
struct sockaddr *from,
socklen_t *fromlen)
{
return recvfrom(s,
buf,
len,
0,
from,
fromlen);
}
/**
* Wrapper for select(2)
*/
int
olsr_select(int nfds,
fd_set *readfds,
fd_set *writefds,
fd_set *exceptfds,
struct timeval *timeout)
{
return select(nfds,
readfds,
writefds,
exceptfds,
timeout);
}
syntax highlighted by Code2HTML, v. 0.9.1