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>
51 #include "wine/unicode.h"
52 #include "wine/debug.h"
54 WINE_DEFAULT_DEBUG_CHANNEL(winsock
);
56 /* names of the protocols */
57 static const CHAR NameIpx
[] = "IPX";
58 static const CHAR NameSpx
[] = "SPX";
59 static const CHAR NameSpxII
[] = "SPX II";
60 static const CHAR NameTcp
[] = "TCP/IP";
61 static const CHAR NameUdp
[] = "UDP/IP";
63 static const WCHAR NameIpxW
[] = {'I', 'P', 'X', '\0'};
64 static const WCHAR NameSpxW
[] = {'S', 'P', 'X', '\0'};
65 static const WCHAR NameSpxIIW
[] = {'S', 'P', 'X', ' ', 'I', 'I', '\0'};
66 static const WCHAR NameTcpW
[] = {'T', 'C', 'P', '/', 'I', 'P', '\0'};
67 static const WCHAR NameUdpW
[] = {'U', 'D', 'P', '/', 'I', 'P', '\0'};
69 /* Taken from Win2k */
70 static const GUID ProviderIdIP
= { 0xe70f1aa0, 0xab8b, 0x11cf,
71 { 0x8c, 0xa3, 0x00, 0x80, 0x5f, 0x48, 0xa1, 0x92 } };
72 static const GUID ProviderIdIPX
= { 0x11058240, 0xbe47, 0x11cf,
73 { 0x95, 0xc8, 0x00, 0x80, 0x5f, 0x48, 0xa1, 0x92 } };
74 static const GUID ProviderIdSPX
= { 0x11058241, 0xbe47, 0x11cf,
75 { 0x95, 0xc8, 0x00, 0x80, 0x5f, 0x48, 0xa1, 0x92 } };
77 /*****************************************************************************
78 * WINSOCK_EnterSingleProtocolW [internal]
80 * enters the protocol information of one given protocol into the given
84 * 1 if a protocol was entered into the buffer.
85 * SOCKET_ERROR otherwise.
88 * - only implemented for IPX, SPX, SPXII, TCP, UDP
89 * - there is no check that the operating system supports the returned
92 static INT
WINSOCK_EnterSingleProtocolW( INT protocol
, WSAPROTOCOL_INFOW
* info
)
94 memset( info
, 0, sizeof(WSAPROTOCOL_INFOW
) );
95 info
->iProtocol
= protocol
;
100 info
->dwServiceFlags1
= XP1_PARTIAL_MESSAGE
| XP1_EXPEDITED_DATA
|
101 XP1_GRACEFUL_CLOSE
| XP1_GUARANTEED_ORDER
|
102 XP1_GUARANTEED_DELIVERY
;
103 memcpy( &info
->ProviderId
, &ProviderIdIP
, sizeof(GUID
) );
104 info
->dwCatalogEntryId
= 0x3e9;
105 info
->ProtocolChain
.ChainLen
= 1;
107 info
->iAddressFamily
= WS_AF_INET
;
108 info
->iMaxSockAddr
= 0x10;
109 info
->iMinSockAddr
= 0x10;
110 info
->iSocketType
= WS_SOCK_STREAM
;
111 strcpyW( info
->szProtocol
, NameTcpW
);
115 info
->dwServiceFlags1
= XP1_PARTIAL_MESSAGE
| XP1_SUPPORT_BROADCAST
|
116 XP1_SUPPORT_MULTIPOINT
| XP1_MESSAGE_ORIENTED
|
118 memcpy( &info
->ProviderId
, &ProviderIdIP
, sizeof(GUID
) );
119 info
->dwCatalogEntryId
= 0x3ea;
120 info
->ProtocolChain
.ChainLen
= 1;
122 info
->iAddressFamily
= WS_AF_INET
;
123 info
->iMaxSockAddr
= 0x10;
124 info
->iMinSockAddr
= 0x10;
125 info
->iSocketType
= WS_SOCK_DGRAM
;
126 info
->dwMessageSize
= 0xffbb;
127 strcpyW( info
->szProtocol
, NameUdpW
);
131 info
->dwServiceFlags1
= XP1_PARTIAL_MESSAGE
| XP1_SUPPORT_BROADCAST
|
132 XP1_SUPPORT_MULTIPOINT
| XP1_MESSAGE_ORIENTED
|
134 memcpy( &info
->ProviderId
, &ProviderIdIPX
, sizeof(GUID
) );
135 info
->dwCatalogEntryId
= 0x406;
136 info
->ProtocolChain
.ChainLen
= 1;
138 info
->iAddressFamily
= WS_AF_IPX
;
139 info
->iMaxSockAddr
= 0x10;
140 info
->iMinSockAddr
= 0x0e;
141 info
->iSocketType
= WS_SOCK_DGRAM
;
142 info
->iProtocolMaxOffset
= 0xff;
143 info
->dwMessageSize
= 0x240;
144 strcpyW( info
->szProtocol
, NameIpxW
);
148 info
->dwServiceFlags1
= XP1_IFS_HANDLES
| XP1_PSEUDO_STREAM
|
149 XP1_MESSAGE_ORIENTED
| XP1_GUARANTEED_ORDER
|
150 XP1_GUARANTEED_DELIVERY
;
151 memcpy( &info
->ProviderId
, &ProviderIdSPX
, sizeof(GUID
) );
152 info
->dwCatalogEntryId
= 0x407;
153 info
->ProtocolChain
.ChainLen
= 1;
155 info
->iAddressFamily
= WS_AF_IPX
;
156 info
->iMaxSockAddr
= 0x10;
157 info
->iMinSockAddr
= 0x0e;
158 info
->iSocketType
= 5;
159 info
->dwMessageSize
= 0xffffffff;
160 strcpyW( info
->szProtocol
, NameSpxW
);
164 info
->dwServiceFlags1
= XP1_IFS_HANDLES
| XP1_GRACEFUL_CLOSE
|
165 XP1_PSEUDO_STREAM
| XP1_MESSAGE_ORIENTED
|
166 XP1_GUARANTEED_ORDER
| XP1_GUARANTEED_DELIVERY
;
167 memcpy( &info
->ProviderId
, &ProviderIdSPX
, sizeof(GUID
) );
168 info
->dwCatalogEntryId
= 0x409;
169 info
->ProtocolChain
.ChainLen
= 1;
171 info
->iAddressFamily
= WS_AF_IPX
;
172 info
->iMaxSockAddr
= 0x10;
173 info
->iMinSockAddr
= 0x0e;
174 info
->iSocketType
= 5;
175 info
->dwMessageSize
= 0xffffffff;
176 strcpyW( info
->szProtocol
, NameSpxIIW
);
180 if ((protocol
== ISOPROTO_TP4
) || (protocol
== NSPROTO_SPX
))
181 FIXME("Protocol <%s> not implemented\n",
182 (protocol
== ISOPROTO_TP4
) ? "ISOPROTO_TP4" : "NSPROTO_SPX");
184 FIXME("unknown Protocol <0x%08x>\n", protocol
);
190 /*****************************************************************************
191 * WINSOCK_EnterSingleProtocolA [internal]
193 * see function WINSOCK_EnterSingleProtocolW
196 static INT
WINSOCK_EnterSingleProtocolA( INT protocol
, WSAPROTOCOL_INFOA
* info
)
198 memset( info
, 0, sizeof(WSAPROTOCOL_INFOA
) );
199 info
->iProtocol
= protocol
;
204 info
->dwServiceFlags1
= XP1_IFS_HANDLES
| XP1_EXPEDITED_DATA
|
205 XP1_GRACEFUL_CLOSE
| XP1_GUARANTEED_ORDER
|
206 XP1_GUARANTEED_DELIVERY
;
207 memcpy( &info
->ProviderId
, &ProviderIdIP
, sizeof(GUID
) );
208 info
->dwCatalogEntryId
= 0x3e9;
209 info
->ProtocolChain
.ChainLen
= 1;
211 info
->iAddressFamily
= WS_AF_INET
;
212 info
->iMaxSockAddr
= 0x10;
213 info
->iMinSockAddr
= 0x10;
214 info
->iSocketType
= WS_SOCK_STREAM
;
215 strcpy( info
->szProtocol
, NameTcp
);
219 info
->dwServiceFlags1
= XP1_IFS_HANDLES
| XP1_SUPPORT_BROADCAST
|
220 XP1_SUPPORT_MULTIPOINT
| XP1_MESSAGE_ORIENTED
|
222 memcpy( &info
->ProviderId
, &ProviderIdIP
, sizeof(GUID
) );
223 info
->dwCatalogEntryId
= 0x3ea;
224 info
->ProtocolChain
.ChainLen
= 1;
226 info
->iAddressFamily
= WS_AF_INET
;
227 info
->iMaxSockAddr
= 0x10;
228 info
->iMinSockAddr
= 0x10;
229 info
->iSocketType
= WS_SOCK_DGRAM
;
230 info
->dwMessageSize
= 0xffbb;
231 strcpy( info
->szProtocol
, NameUdp
);
235 info
->dwServiceFlags1
= XP1_IFS_HANDLES
| XP1_SUPPORT_BROADCAST
|
236 XP1_SUPPORT_MULTIPOINT
| XP1_MESSAGE_ORIENTED
|
238 memcpy( &info
->ProviderId
, &ProviderIdIPX
, sizeof(GUID
) );
239 info
->dwCatalogEntryId
= 0x406;
240 info
->ProtocolChain
.ChainLen
= 1;
242 info
->iAddressFamily
= WS_AF_IPX
;
243 info
->iMaxSockAddr
= 0x10;
244 info
->iMinSockAddr
= 0x0e;
245 info
->iSocketType
= WS_SOCK_DGRAM
;
246 info
->iProtocolMaxOffset
= 0xff;
247 info
->dwMessageSize
= 0x240;
248 strcpy( info
->szProtocol
, NameIpx
);
252 info
->dwServiceFlags1
= XP1_IFS_HANDLES
| XP1_PSEUDO_STREAM
|
253 XP1_MESSAGE_ORIENTED
| XP1_GUARANTEED_ORDER
|
254 XP1_GUARANTEED_DELIVERY
;
255 memcpy( &info
->ProviderId
, &ProviderIdSPX
, sizeof(GUID
) );
256 info
->dwCatalogEntryId
= 0x407;
257 info
->ProtocolChain
.ChainLen
= 1;
259 info
->iAddressFamily
= WS_AF_IPX
;
260 info
->iMaxSockAddr
= 0x10;
261 info
->iMinSockAddr
= 0x0e;
262 info
->iSocketType
= 5;
263 info
->dwMessageSize
= 0xffffffff;
264 strcpy( info
->szProtocol
, NameSpx
);
268 info
->dwServiceFlags1
= XP1_IFS_HANDLES
| XP1_GRACEFUL_CLOSE
|
269 XP1_PSEUDO_STREAM
| XP1_MESSAGE_ORIENTED
|
270 XP1_GUARANTEED_ORDER
| XP1_GUARANTEED_DELIVERY
;
271 memcpy( &info
->ProviderId
, &ProviderIdSPX
, sizeof(GUID
) );
272 info
->dwCatalogEntryId
= 0x409;
273 info
->ProtocolChain
.ChainLen
= 1;
275 info
->iAddressFamily
= WS_AF_IPX
;
276 info
->iMaxSockAddr
= 0x10;
277 info
->iMinSockAddr
= 0x0e;
278 info
->iSocketType
= 5;
279 info
->dwMessageSize
= 0xffffffff;
280 strcpy( info
->szProtocol
, NameSpxII
);
284 if ((protocol
== ISOPROTO_TP4
) || (protocol
== NSPROTO_SPX
))
285 FIXME("Protocol <%s> not implemented\n",
286 (protocol
== ISOPROTO_TP4
) ? "ISOPROTO_TP4" : "NSPROTO_SPX");
288 FIXME("unknown Protocol <0x%08x>\n", protocol
);
294 /*****************************************************************************
295 * WSAEnumProtocolsA [WS2_32.@]
297 * see function WSAEnumProtocolsW
299 INT WINAPI
WSAEnumProtocolsA( LPINT protocols
, LPWSAPROTOCOL_INFOA buffer
, LPDWORD len
)
303 INT local
[] = { WS_IPPROTO_TCP
, WS_IPPROTO_UDP
, NSPROTO_IPX
, NSPROTO_SPX
, NSPROTO_SPXII
, 0 };
308 if (!protocols
) protocols
= local
;
310 while (protocols
[i
]) i
++;
312 size
= i
* sizeof(WSAPROTOCOL_INFOA
);
320 for (i
= 0; protocols
[i
]; i
++)
322 if (WINSOCK_EnterSingleProtocolA( protocols
[i
], &buffer
[i
] ) == SOCKET_ERROR
)
328 /*****************************************************************************
329 * WSAEnumProtocolsW [WS2_32.@]
331 * Retrieves information about specified set of active network protocols.
334 * protocols [I] Pointer to null-terminated array of protocol id's. NULL
335 * retrieves information on all available protocols.
336 * buffer [I] Pointer to a buffer to be filled with WSAPROTOCOL_INFO
338 * len [I/O] Pointer to a variable specifying buffer size. On output
339 * the variable holds the number of bytes needed when the
340 * specified size is too small.
343 * Success: number of WSAPROTOCOL_INFO structures in buffer.
344 * Failure: SOCKET_ERROR
347 * NT4SP5 does not return SPX if protocols == NULL
350 * - NT4SP5 returns in addition these list of NETBIOS protocols
351 * (address family 17), each entry two times one for socket type 2 and 5
353 * iProtocol szProtocol
354 * 0x80000000 \Device\NwlnkNb
355 * 0xfffffffa \Device\NetBT_CBENT7
356 * 0xfffffffb \Device\Nbf_CBENT7
357 * 0xfffffffc \Device\NetBT_NdisWan5
358 * 0xfffffffd \Device\NetBT_El9202
359 * 0xfffffffe \Device\Nbf_El9202
360 * 0xffffffff \Device\Nbf_NdisWan4
362 * - there is no check that the operating system supports the returned
365 INT WINAPI
WSAEnumProtocolsW( LPINT protocols
, LPWSAPROTOCOL_INFOW buffer
, LPDWORD len
)
369 INT local
[] = { WS_IPPROTO_TCP
, WS_IPPROTO_UDP
, NSPROTO_IPX
, NSPROTO_SPX
, NSPROTO_SPXII
, 0 };
374 if (!protocols
) protocols
= local
;
376 while (protocols
[i
]) i
++;
378 size
= i
* sizeof(WSAPROTOCOL_INFOW
);
386 for (i
= 0; protocols
[i
]; i
++)
388 if (WINSOCK_EnterSingleProtocolW( protocols
[i
], &buffer
[i
] ) == SOCKET_ERROR
)
394 /*****************************************************************************
395 * WSCEnumProtocols [WS2_32.@]
398 * protocols [I] Null-terminated array of iProtocol values.
399 * buffer [O] Buffer of WSAPROTOCOL_INFOW structures.
400 * len [I/O] Size of buffer on input/output.
401 * errno [O] Error code.
404 * Success: number of protocols to be reported on.
405 * Failure: SOCKET_ERROR. error is in errno.
408 * Doesn't supply info on layered protocols.
411 INT WINAPI
WSCEnumProtocols( LPINT protocols
, LPWSAPROTOCOL_INFOW buffer
, LPDWORD len
, LPINT errno
)
413 INT ret
= WSAEnumProtocolsW( protocols
, buffer
, len
);
415 if (ret
== SOCKET_ERROR
) *errno
= WSAENOBUFS
;