mirror of
https://github.com/mirkobrombin/raven.git
synced 2026-11-05 21:56:33 +00:00
- Both calls read the host's protocols database into one PROTOENT the process reuses, as Winsock reuses its per-thread one: the name, an empty list of aliases and the protocol number. - The record keeps its pointers, so the 32-bit and 64-bit layouts are written apart; a protocol the database does not list answers NULL with WSANO_DATA, as the services calls beside them do. - The new guest fixture protocol_client.c checks that both spellings of a protocol name the same record, that a second call reuses it, and that an unlisted name and an unlisted number are refused. It is built for 64-bit and 32-bit callers. Assisted-by: Claude Code:deepseek-v4.1-flash-1017 AI-Scope: Wrote the two handlers next to the existing getservbyname ones, the PROTOENT writer for both pointer widths, and the guest fixture; checked with ctest (native_protocol_database_client, native_protocol_database_client_x32).
45 lines
1.4 KiB
C
45 lines
1.4 KiB
C
#define WIN32_LEAN_AND_MEAN
|
|
#include <winsock2.h>
|
|
|
|
/* getprotobyname and getprotobynumber answer from the protocols database into one PROTOENT that the following call reuses, as Winsock
|
|
reuses its per-thread one. Both spellings of a protocol name the same record, and a protocol the database does not list is refused. */
|
|
static int same(const char *left, const char *right)
|
|
{
|
|
if (!left || !right)
|
|
return 0;
|
|
for (unsigned at = 0;; ++at) {
|
|
char a = left[at], b = right[at];
|
|
if (a >= 'A' && a <= 'Z')
|
|
a = (char)(a - 'A' + 'a');
|
|
if (a != b)
|
|
return 0;
|
|
if (!a)
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
int raven_entry(void)
|
|
{
|
|
WSADATA data;
|
|
if (WSAStartup(MAKEWORD(2, 2), &data))
|
|
return 1;
|
|
struct protoent *tcp = getprotobyname("tcp");
|
|
if (!tcp || tcp->p_proto != 6 || !same(tcp->p_name, "tcp"))
|
|
return 2;
|
|
struct protoent *by_number = getprotobynumber(6);
|
|
if (!by_number || by_number->p_proto != 6 || !same(by_number->p_name, "tcp"))
|
|
return 3;
|
|
// The record is the one the earlier call answered with, and it has no aliases.
|
|
if (tcp != by_number || !by_number->p_aliases || by_number->p_aliases[0])
|
|
return 4;
|
|
struct protoent *udp = getprotobynumber(17);
|
|
if (!udp || udp->p_proto != 17 || !same(udp->p_name, "udp"))
|
|
return 5;
|
|
// A protocol the database does not list has no record.
|
|
SetLastError(0xdead);
|
|
if (getprotobyname("no-such-protocol") || getprotobynumber(200))
|
|
return 6;
|
|
WSACleanup();
|
|
return 0;
|
|
}
|