2 * Protocol enumeration functions
4 * Copyright (C) 2001 Stefan Leichter
5 * Copyright (C) 2004 Hans Leidekker
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library 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 GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 * The protocol enumeration functions were verified to match Win2k versions
24 * for these protocols: IPX, SPX, SPXII, TCP/IP and UDP/IP.
33 #include <sys/types.h>
34 #ifdef HAVE_ARPA_INET_H
35 #include <arpa/inet.h>
50 #include "wine/unicode.h"
51 #include "wine/debug.h"
53 WINE_DEFAULT_DEBUG_CHANNEL(winsock);
55 /* names of the protocols */
56 static const CHAR NameIpx[] = "IPX";
57 static const CHAR NameSpx[] = "SPX";
58 static const CHAR NameSpxII[] = "SPX II";
59 static const CHAR NameTcp[] = "TCP/IP";
60 static const CHAR NameUdp[] = "UDP/IP";
62 static const WCHAR NameIpxW[] = {'I', 'P', 'X', '\0'};
63 static const WCHAR NameSpxW[] = {'S', 'P', 'X', '\0'};
64 static const WCHAR NameSpxIIW[] = {'S', 'P', 'X', ' ', 'I', 'I', '\0'};
65 static const WCHAR NameTcpW[] = {'T', 'C', 'P', '/', 'I', 'P', '\0'};
66 static const WCHAR NameUdpW[] = {'U', 'D', 'P', '/', 'I', 'P', '\0'};
68 /* Taken from Win2k */
69 static const GUID ProviderIdIP = { 0xe70f1aa0, 0xab8b, 0x11cf,
70 { 0x8c, 0xa3, 0x00, 0x80, 0x5f, 0x48, 0xa1, 0x92 } };
71 static const GUID ProviderIdIPX = { 0x11058240, 0xbe47, 0x11cf,
72 { 0x95, 0xc8, 0x00, 0x80, 0x5f, 0x48, 0xa1, 0x92 } };
73 static const GUID ProviderIdSPX = { 0x11058241, 0xbe47, 0x11cf,
74 { 0x95, 0xc8, 0x00, 0x80, 0x5f, 0x48, 0xa1, 0x92 } };
76 /*****************************************************************************
77 * WINSOCK_EnterSingleProtocolW [internal]
79 * enters the protocol information of one given protocol into the given
83 * 1 if a protocol was entered into the buffer.
84 * SOCKET_ERROR otherwise.
87 * - only implemented for IPX, SPX, SPXII, TCP, UDP
88 * - there is no check that the operating system supports the returned
91 static INT WINSOCK_EnterSingleProtocolW( INT protocol, WSAPROTOCOL_INFOW* info )
93 memset( info, 0, sizeof(WSAPROTOCOL_INFOW) );
94 info->iProtocol = protocol;
99 info->dwServiceFlags1 = XP1_PARTIAL_MESSAGE | XP1_EXPEDITED_DATA |
100 XP1_GRACEFUL_CLOSE | XP1_GUARANTEED_ORDER |
101 XP1_GUARANTEED_DELIVERY;
102 memcpy( &info->ProviderId, &ProviderIdIP, sizeof(GUID) );
103 info->dwCatalogEntryId = 0x3e9;
104 info->ProtocolChain.ChainLen = 1;
106 info->iAddressFamily = WS_AF_INET;
107 info->iMaxSockAddr = 0x10;
108 info->iMinSockAddr = 0x10;
109 info->iSocketType = WS_SOCK_STREAM;
110 strcpyW( info->szProtocol, NameTcpW );
114 info->dwServiceFlags1 = XP1_PARTIAL_MESSAGE | XP1_SUPPORT_BROADCAST |
115 XP1_SUPPORT_MULTIPOINT | XP1_MESSAGE_ORIENTED |
117 memcpy( &info->ProviderId, &ProviderIdIP, sizeof(GUID) );
118 info->dwCatalogEntryId = 0x3ea;
119 info->ProtocolChain.ChainLen = 1;
121 info->iAddressFamily = WS_AF_INET;
122 info->iMaxSockAddr = 0x10;
123 info->iMinSockAddr = 0x10;
124 info->iSocketType = WS_SOCK_DGRAM;
125 info->dwMessageSize = 0xffbb;
126 strcpyW( info->szProtocol, NameUdpW );
130 info->dwServiceFlags1 = XP1_PARTIAL_MESSAGE | XP1_SUPPORT_BROADCAST |
131 XP1_SUPPORT_MULTIPOINT | XP1_MESSAGE_ORIENTED |
133 memcpy( &info->ProviderId, &ProviderIdIPX, sizeof(GUID) );
134 info->dwCatalogEntryId = 0x406;
135 info->ProtocolChain.ChainLen = 1;
137 info->iAddressFamily = WS_AF_IPX;
138 info->iMaxSockAddr = 0x10;
139 info->iMinSockAddr = 0x0e;
140 info->iSocketType = WS_SOCK_DGRAM;
141 info->iProtocolMaxOffset = 0xff;
142 info->dwMessageSize = 0x240;
143 strcpyW( info->szProtocol, NameIpxW );
147 info->dwServiceFlags1 = XP1_IFS_HANDLES | XP1_PSEUDO_STREAM |
148 XP1_MESSAGE_ORIENTED | XP1_GUARANTEED_ORDER |
149 XP1_GUARANTEED_DELIVERY;
150 memcpy( &info->ProviderId, &ProviderIdSPX, sizeof(GUID) );
151 info->dwCatalogEntryId = 0x407;
152 info->ProtocolChain.ChainLen = 1;
154 info->iAddressFamily = WS_AF_IPX;
155 info->iMaxSockAddr = 0x10;
156 info->iMinSockAddr = 0x0e;
157 info->iSocketType = 5;
158 info->dwMessageSize = 0xffffffff;
159 strcpyW( info->szProtocol, NameSpxW );
163 info->dwServiceFlags1 = XP1_IFS_HANDLES | XP1_GRACEFUL_CLOSE |
164 XP1_PSEUDO_STREAM | XP1_MESSAGE_ORIENTED |
165 XP1_GUARANTEED_ORDER | XP1_GUARANTEED_DELIVERY;
166 memcpy( &info->ProviderId, &ProviderIdSPX, sizeof(GUID) );
167 info->dwCatalogEntryId = 0x409;
168 info->ProtocolChain.ChainLen = 1;
170 info->iAddressFamily = WS_AF_IPX;
171 info->iMaxSockAddr = 0x10;
172 info->iMinSockAddr = 0x0e;
173 info->iSocketType = 5;
174 info->dwMessageSize = 0xffffffff;
175 strcpyW( info->szProtocol, NameSpxIIW );
179 if ((protocol == ISOPROTO_TP4) || (protocol == NSPROTO_SPX))
180 FIXME("Protocol <%s> not implemented\n",
181 (protocol == ISOPROTO_TP4) ? "ISOPROTO_TP4" : "NSPROTO_SPX");
183 FIXME("unknown Protocol <0x%08x>\n", protocol);
189 /*****************************************************************************
190 * WINSOCK_EnterSingleProtocolA [internal]
192 * see function WINSOCK_EnterSingleProtocolW
195 static INT WINSOCK_EnterSingleProtocolA( INT protocol, WSAPROTOCOL_INFOA* info )
197 memset( info, 0, sizeof(WSAPROTOCOL_INFOA) );
198 info->iProtocol = protocol;
203 info->dwServiceFlags1 = XP1_IFS_HANDLES | XP1_EXPEDITED_DATA |
204 XP1_GRACEFUL_CLOSE | XP1_GUARANTEED_ORDER |
205 XP1_GUARANTEED_DELIVERY;
206 memcpy( &info->ProviderId, &ProviderIdIP, sizeof(GUID) );
207 info->dwCatalogEntryId = 0x3e9;
208 info->ProtocolChain.ChainLen = 1;
210 info->iAddressFamily = WS_AF_INET;
211 info->iMaxSockAddr = 0x10;
212 info->iMinSockAddr = 0x10;
213 info->iSocketType = WS_SOCK_STREAM;
214 strcpy( info->szProtocol, NameTcp );
218 info->dwServiceFlags1 = XP1_IFS_HANDLES | XP1_SUPPORT_BROADCAST |
219 XP1_SUPPORT_MULTIPOINT | XP1_MESSAGE_ORIENTED |
221 memcpy( &info->ProviderId, &ProviderIdIP, sizeof(GUID) );
222 info->dwCatalogEntryId = 0x3ea;
223 info->ProtocolChain.ChainLen = 1;
225 info->iAddressFamily = WS_AF_INET;
226 info->iMaxSockAddr = 0x10;
227 info->iMinSockAddr = 0x10;
228 info->iSocketType = WS_SOCK_DGRAM;
229 info->dwMessageSize = 0xffbb;
230 strcpy( info->szProtocol, NameUdp );
234 info->dwServiceFlags1 = XP1_IFS_HANDLES | XP1_SUPPORT_BROADCAST |
235 XP1_SUPPORT_MULTIPOINT | XP1_MESSAGE_ORIENTED |
237 memcpy( &info->ProviderId, &ProviderIdIPX, sizeof(GUID) );
238 info->dwCatalogEntryId = 0x406;
239 info->ProtocolChain.ChainLen = 1;
241 info->iAddressFamily = WS_AF_IPX;
242 info->iMaxSockAddr = 0x10;
243 info->iMinSockAddr = 0x0e;
244 info->iSocketType = WS_SOCK_DGRAM;
245 info->iProtocolMaxOffset = 0xff;
246 info->dwMessageSize = 0x240;
247 strcpy( info->szProtocol, NameIpx );
251 info->dwServiceFlags1 = XP1_IFS_HANDLES | XP1_PSEUDO_STREAM |
252 XP1_MESSAGE_ORIENTED | XP1_GUARANTEED_ORDER |
253 XP1_GUARANTEED_DELIVERY;
254 memcpy( &info->ProviderId, &ProviderIdSPX, sizeof(GUID) );
255 info->dwCatalogEntryId = 0x407;
256 info->ProtocolChain.ChainLen = 1;
258 info->iAddressFamily = WS_AF_IPX;
259 info->iMaxSockAddr = 0x10;
260 info->iMinSockAddr = 0x0e;
261 info->iSocketType = 5;
262 info->dwMessageSize = 0xffffffff;
263 strcpy( info->szProtocol, NameSpx );
267 info->dwServiceFlags1 = XP1_IFS_HANDLES | XP1_GRACEFUL_CLOSE |
268 XP1_PSEUDO_STREAM | XP1_MESSAGE_ORIENTED |
269 XP1_GUARANTEED_ORDER | XP1_GUARANTEED_DELIVERY;
270 memcpy( &info->ProviderId, &ProviderIdSPX, sizeof(GUID) );
271 info->dwCatalogEntryId = 0x409;
272 info->ProtocolChain.ChainLen = 1;
274 info->iAddressFamily = WS_AF_IPX;
275 info->iMaxSockAddr = 0x10;
276 info->iMinSockAddr = 0x0e;
277 info->iSocketType = 5;
278 info->dwMessageSize = 0xffffffff;
279 strcpy( info->szProtocol, NameSpxII );
283 if ((protocol == ISOPROTO_TP4) || (protocol == NSPROTO_SPX))
284 FIXME("Protocol <%s> not implemented\n",
285 (protocol == ISOPROTO_TP4) ? "ISOPROTO_TP4" : "NSPROTO_SPX");
287 FIXME("unknown Protocol <0x%08x>\n", protocol);
293 /*****************************************************************************
294 * WSAEnumProtocolsA [WS2_32.@]
296 * see function WSAEnumProtocolsW
298 INT WINAPI WSAEnumProtocolsA( LPINT protocols, LPWSAPROTOCOL_INFOA buffer, LPDWORD len )
302 INT local[] = { WS_IPPROTO_TCP, WS_IPPROTO_UDP, NSPROTO_IPX, NSPROTO_SPX, NSPROTO_SPXII, 0 };
304 if (!protocols) protocols = local;
306 while (protocols[i]) i++;
308 size = i * sizeof(WSAPROTOCOL_INFOA);
310 if (*len < size || !buffer)
313 WSASetLastError(WSAENOBUFS);
317 for (i = 0; protocols[i]; i++)
319 if (WINSOCK_EnterSingleProtocolA( protocols[i], &buffer[i] ) == SOCKET_ERROR)
325 /*****************************************************************************
326 * WSAEnumProtocolsW [WS2_32.@]
328 * Retrieves information about specified set of active network protocols.
331 * protocols [I] Pointer to null-terminated array of protocol id's. NULL
332 * retrieves information on all available protocols.
333 * buffer [I] Pointer to a buffer to be filled with WSAPROTOCOL_INFO
335 * len [I/O] Pointer to a variable specifying buffer size. On output
336 * the variable holds the number of bytes needed when the
337 * specified size is too small.
340 * Success: number of WSAPROTOCOL_INFO structures in buffer.
341 * Failure: SOCKET_ERROR
344 * NT4SP5 does not return SPX if protocols == NULL
347 * - NT4SP5 returns in addition these list of NETBIOS protocols
348 * (address family 17), each entry two times one for socket type 2 and 5
350 * iProtocol szProtocol
351 * 0x80000000 \Device\NwlnkNb
352 * 0xfffffffa \Device\NetBT_CBENT7
353 * 0xfffffffb \Device\Nbf_CBENT7
354 * 0xfffffffc \Device\NetBT_NdisWan5
355 * 0xfffffffd \Device\NetBT_El9202
356 * 0xfffffffe \Device\Nbf_El9202
357 * 0xffffffff \Device\Nbf_NdisWan4
359 * - there is no check that the operating system supports the returned
362 INT WINAPI WSAEnumProtocolsW( LPINT protocols, LPWSAPROTOCOL_INFOW buffer, LPDWORD len )
366 INT local[] = { WS_IPPROTO_TCP, WS_IPPROTO_UDP, NSPROTO_IPX, NSPROTO_SPX, NSPROTO_SPXII, 0 };
368 if (!protocols) protocols = local;
370 while (protocols[i]) i++;
372 size = i * sizeof(WSAPROTOCOL_INFOW);
374 if (*len < size || !buffer)
377 WSASetLastError(WSAENOBUFS);
381 for (i = 0; protocols[i]; i++)
383 if (WINSOCK_EnterSingleProtocolW( protocols[i], &buffer[i] ) == SOCKET_ERROR)
389 /*****************************************************************************
390 * WSCEnumProtocols [WS2_32.@]
393 * protocols [I] Null-terminated array of iProtocol values.
394 * buffer [O] Buffer of WSAPROTOCOL_INFOW structures.
395 * len [I/O] Size of buffer on input/output.
396 * errno [O] Error code.
399 * Success: number of protocols to be reported on.
400 * Failure: SOCKET_ERROR. error is in errno.
403 * Doesn't supply info on layered protocols.
406 INT WINAPI WSCEnumProtocols( LPINT protocols, LPWSAPROTOCOL_INFOW buffer, LPDWORD len, LPINT errno )
408 INT ret = WSAEnumProtocolsW( protocols, buffer, len );
410 if (ret == SOCKET_ERROR) *errno = WSAENOBUFS;