Initial import
[olsrd.git] / front-end / src / win32 / compat.c
1 /*
2  * Functions for the Windows port
3  * Copyright (C) 2004 Thomas Lopatic (thomas@lopatic.de)
4  *
5  * This file is part of olsrd-unik.
6  *
7  * olsrd-unik is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * olsrd-unik is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with olsrd-unik; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  *
21  */
22
23 /*
24  * Copyright (c) 1996,1999 by Internet Software Consortium.
25  *
26  * Permission to use, copy, modify, and distribute this software for any
27  * purpose with or without fee is hereby granted, provided that the above
28  * copyright notice and this permission notice appear in all copies.
29  *
30  * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
31  * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
32  * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
33  * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
34  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
35  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
36  * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
37  * SOFTWARE.
38  */
39
40 #include <stdio.h>
41 #include <sys/time.h>
42 #include <ctype.h>
43
44 void gettimeofday(struct timeval *TVal, void *TZone)
45 {
46   SYSTEMTIME SysTime;
47   FILETIME FileTime;
48   unsigned __int64 Ticks;
49
50   GetSystemTime(&SysTime);
51   SystemTimeToFileTime(&SysTime, &FileTime);
52
53   Ticks = ((__int64)FileTime.dwHighDateTime << 32) |
54     (__int64)FileTime.dwLowDateTime;
55
56   Ticks -= 116444736000000000LL;
57
58   TVal->tv_sec = (unsigned int)(Ticks / 10000000);
59   TVal->tv_usec = (unsigned int)(Ticks % 10000000) / 10;
60 }
61
62 char *StrError(unsigned int ErrNo)
63 {
64   static char Msg[1000];
65   
66   FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, ErrNo,
67                 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), Msg,
68                 sizeof (Msg), NULL);
69         
70   return Msg;
71 }
72
73 void PError(char *Str)
74 {
75   char Msg[1000];
76   int Len;
77
78   sprintf(Msg, "ERROR - %s: ", Str);
79
80   Len = strlen(Msg);
81
82   FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(),
83                 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), Msg + Len,
84                 sizeof (Msg) - Len, NULL);
85
86   fprintf(stderr, "%s\n", Msg);
87 }
88
89 void WinSockPError(char *Str)
90 {
91   char Msg[1000];
92   int Len;
93
94   sprintf(Msg, "ERROR - %s: ", Str);
95
96   Len = strlen(Msg);
97
98   FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, WSAGetLastError(),
99                 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), Msg + Len,
100                 sizeof (Msg) - Len, NULL);
101
102   fprintf(stderr, "%s\n", Msg);
103 }
104
105 #define NS_INADDRSZ 4
106 #define NS_IN6ADDRSZ 16
107 #define NS_INT16SZ 2
108
109 static char *inet_ntop4(const unsigned char *src, char *dst, int size)
110 {
111   static const char fmt[] = "%u.%u.%u.%u";
112   char tmp[sizeof "255.255.255.255"];
113
114   if (sprintf(tmp, fmt, src[0], src[1], src[2], src[3]) > size)
115     return (NULL);
116
117   return strcpy(dst, tmp);
118 }
119
120 static char *inet_ntop6(const unsigned char *src, char *dst, int size)
121 {
122   char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"], *tp;
123   struct { int base, len; } best, cur;
124   u_int words[NS_IN6ADDRSZ / NS_INT16SZ];
125   int i;
126
127   memset(words, '\0', sizeof words);
128
129   for (i = 0; i < NS_IN6ADDRSZ; i += 2)
130     words[i / 2] = (src[i] << 8) | src[i + 1];
131
132   best.base = -1;
133   cur.base = -1;
134
135   for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++)
136   {
137     if (words[i] == 0)
138     {
139       if (cur.base == -1)
140         cur.base = i, cur.len = 1;
141
142       else
143         cur.len++;
144     }
145
146     else
147     {
148       if (cur.base != -1)
149       {
150         if (best.base == -1 || cur.len > best.len)
151           best = cur;
152
153         cur.base = -1;
154       }
155     }
156   }
157
158   if (cur.base != -1)
159   {
160     if (best.base == -1 || cur.len > best.len)
161       best = cur;
162   }
163
164   if (best.base != -1 && best.len < 2)
165     best.base = -1;
166
167   tp = tmp;
168
169   for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++)
170   {
171     if (best.base != -1 && i >= best.base && i < (best.base + best.len))
172     {
173       if (i == best.base)
174         *tp++ = ':';
175
176       continue;
177     }
178
179     if (i != 0)
180       *tp++ = ':';
181
182     
183     if (i == 6 && best.base == 0 &&
184         (best.len == 6 || (best.len == 5 && words[5] == 0xffff)))
185     {
186       if (!inet_ntop4(src+12, tp, sizeof tmp - (tp - tmp)))
187         return (NULL);
188
189       tp += strlen(tp);
190
191       break;
192     }
193
194     tp += sprintf(tp, "%x", words[i]);
195   }
196
197   if (best.base != -1 && (best.base + best.len) == (NS_IN6ADDRSZ / NS_INT16SZ))
198     *tp++ = ':';
199
200   *tp++ = '\0';
201
202   if ((tp - tmp) > size)
203     return (NULL);
204
205   return strcpy(dst, tmp);
206 }
207
208 char *inet_ntop(int af, void *src, char *dst, int size)
209 {
210   switch (af)
211   {
212   case AF_INET:
213     return (inet_ntop4(src, dst, size));
214
215   case AF_INET6:
216     return (inet_ntop6(src, dst, size));
217
218   default:
219     return (NULL);
220   }
221 }