[PATCH] ws2_32: Drop dependencies on system getprotoby(name|number) functions

Zebediah Figura z.figura12 at gmail.com
Sun Jul 12 23:12:04 CDT 2020


On 7/12/20 10:42 PM, Alex Henrie wrote:
> Signed-off-by: Alex Henrie <alexhenrie24 at gmail.com>
> ---
> Implementing these functions entirely in Wine allows us to make sure
> that protocol 0 is "ip" (not "hotopt" like on Linux) and that protocols
> supported by neither Windows nor Wine do not appear in the list. Plus,
> it will facilitate the conversion of ws2_32 to PE.
> ---
>  configure.ac                 |   2 -
>  dlls/ws2_32/socket.c         | 165 +++++++++++++++++------------------
>  dlls/ws2_32/tests/protocol.c | 147 +++++++++++++++++++++++++++++++
>  3 files changed, 229 insertions(+), 85 deletions(-)
> 
> diff --git a/configure.ac b/configure.ac
> index 4829648c3a..9002ce8d60 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -2245,8 +2245,6 @@ AC_CHECK_FUNCS(\
>  	getaddrinfo \
>  	getnameinfo \
>  	getnetbyname \
> -	getprotobyname \
> -	getprotobynumber \
>  	getservbyport \
>  )
>  
> diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c
> index 69fbb37af2..36a92f2354 100644
> --- a/dlls/ws2_32/socket.c
> +++ b/dlls/ws2_32/socket.c
> @@ -6505,60 +6505,82 @@ struct WS_hostent* WINAPI WS_gethostbyname(const char* name)
>  }
>  
>  
> -static const struct { int prot; const char *names[3]; } protocols[] =
> -{
> -    {   0, { "ip", "IP" }},
> -    {   1, { "icmp", "ICMP" }},
> -    {   2, { "igmp", "IGMP" }},
> -    {   3, { "ggp", "GGP" }},
> -    {   6, { "tcp", "TCP" }},
> -    {   8, { "egp", "EGP" }},
> -    {   9, { "igp", "IGP" }},
> -    {  12, { "pup", "PUP" }},
> -    {  17, { "udp", "UDP" }},
> -    {  20, { "hmp", "HMP" }},
> -    {  22, { "xns-idp", "XNS-IDP" }},
> -    {  27, { "rdp", "RDP" }},
> -    {  29, { "iso-tp4", "ISO-TP4" }},
> -    {  33, { "dccp", "DCCP" }},
> -    {  36, { "xtp", "XTP" }},
> -    {  37, { "ddp", "DDP" }},
> -    {  38, { "idpr-cmtp", "IDPR-CMTP" }},
> -    {  41, { "ipv6", "IPv6" }},
> -    {  43, { "ipv6-route", "IPv6-Route" }},
> -    {  44, { "ipv6-frag", "IPv6-Frag" }},
> -    {  45, { "idrp", "IDRP" }},
> -    {  46, { "rsvp", "RSVP" }},
> -    {  47, { "gre", "GRE" }},
> -    {  50, { "esp", "ESP" }},
> -    {  51, { "ah", "AH" }},
> -    {  57, { "skip", "SKIP" }},
> -    {  58, { "ipv6-icmp", "IPv6-ICMP" }},
> -    {  59, { "ipv6-nonxt", "IPv6-NoNxt" }},
> -    {  60, { "ipv6-opts", "IPv6-Opts" }},
> -    {  66, { "rvd", "RVD" }},
> -    {  73, { "rspf", "RSPF" }},
> -    {  81, { "vmtp", "VMTP" }},
> -    {  88, { "eigrp", "EIGRP" }},
> -    {  89, { "ospf", "OSPFIGP" }},
> -    {  93, { "ax.25", "AX.25" }},
> -    {  94, { "ipip", "IPIP" }},
> -    {  97, { "etherip", "ETHERIP" }},
> -    {  98, { "encap", "ENCAP" }},
> -    { 103, { "pim", "PIM" }},
> -    { 108, { "ipcomp", "IPCOMP" }},
> -    { 112, { "vrrp", "VRRP" }},
> -    { 115, { "l2tp", "L2TP" }},
> -    { 124, { "isis", "ISIS" }},
> -    { 132, { "sctp", "SCTP" }},
> -    { 133, { "fc", "FC" }},
> -    { 135, { "mobility-header", "Mobility-Header" }},
> -    { 136, { "udplite", "UDPLite" }},
> -    { 137, { "mpls-in-ip", "MPLS-in-IP" }},
> -    { 139, { "hip", "HIP" }},
> -    { 140, { "shim6", "Shim6" }},
> -    { 141, { "wesp", "WESP" }},
> -    { 142, { "rohc", "ROHC" }},
> +static const char * const protocols[][3] =
> +{
> +    /* 0 */
> +    { "ip", "IP" },
> +    { "icmp", "ICMP" },
> +    { },
> +    { "ggp", "GGP" },
> +    { },
> +    { },
> +    { "tcp", "TCP" },
> +    { },
> +    { "egp", "EGP" },
> +    { },
> +    /* 10 */
> +    { },
> +    { },
> +    { "pup", "PUP" },
> +    { },
> +    { },
> +    { },
> +    { },
> +    { "udp", "UDP" },
> +    { },
> +    { },
> +    /* 20 */
> +    { "hmp", "HMP" },
> +    { },
> +    { "xns-idp", "XNS-IDP" },
> +    { },
> +    { },
> +    { },
> +    { },
> +    { "rdp", "RDP" },
> +    { },
> +    { },
> +    /* 30 */
> +    { },
> +    { },
> +    { },
> +    { },
> +    { },
> +    { },
> +    { },
> +    { },
> +    { },
> +    { },
> +    /* 40 */
> +    { },
> +    { "ipv6", "IPv6" },
> +    { },
> +    { "ipv6-route", "IPv6-Route" },
> +    { "ipv6-frag", "IPv6-Frag" },
> +    { },
> +    { },
> +    { },
> +    { },
> +    { },
> +    /* 50 */
> +    { "esp", "ESP" },
> +    { "ah", "AH" },
> +    { },
> +    { },
> +    { },
> +    { },
> +    { },
> +    { },
> +    { "ipv6-icmp", "IPv6-ICMP" },
> +    { "ipv6-nonxt", "IPv6-NoNxt" },
> +    /* 60 */
> +    { "ipv6-opts", "IPv6-Opts" },
> +    { },
> +    { },
> +    { },
> +    { },
> +    { },
> +    { "rvd", "RVD" },
>  };

I guess this is a matter of opinion, but I don't think the table is more
readable in this form.

>  
>  /***********************************************************************
> @@ -6567,21 +6589,12 @@ static const struct { int prot; const char *names[3]; } protocols[] =
>  struct WS_protoent* WINAPI WS_getprotobyname(const char* name)
>  {
>      struct WS_protoent* retval = NULL;
> -#ifdef HAVE_GETPROTOBYNAME
> -    struct protoent*     proto;
> -    EnterCriticalSection( &csWSgetXXXbyYYY );
> -    if( (proto = getprotobyname(name)) != NULL )
> -        retval = WS_create_pe( proto->p_name, proto->p_aliases, proto->p_proto );
> -    LeaveCriticalSection( &csWSgetXXXbyYYY );
> -#endif
> -    if (!retval)
> +    unsigned int i;
> +    for (i = 0; i < ARRAY_SIZE(protocols); i++)
>      {
> -        unsigned int i;
> -        for (i = 0; i < ARRAY_SIZE(protocols); i++)
> +        if (protocols[i][0] && _strnicmp( protocols[i][0], name, -1 ) == 0)
>          {
> -            if (_strnicmp( protocols[i].names[0], name, -1 )) continue;
> -            retval = WS_create_pe( protocols[i].names[0], (char **)protocols[i].names + 1,
> -                                   protocols[i].prot );
> +            retval = WS_create_pe( protocols[i][0], (char **)&protocols[i][1], i );
>              break;
>          }
>      }
> @@ -6601,23 +6614,9 @@ struct WS_protoent* WINAPI WS_getprotobyname(const char* name)
>  struct WS_protoent* WINAPI WS_getprotobynumber(int number)
>  {
>      struct WS_protoent* retval = NULL;
> -#ifdef HAVE_GETPROTOBYNUMBER
> -    struct protoent*     proto;
> -    EnterCriticalSection( &csWSgetXXXbyYYY );
> -    if( (proto = getprotobynumber(number)) != NULL )
> -        retval = WS_create_pe( proto->p_name, proto->p_aliases, proto->p_proto );
> -    LeaveCriticalSection( &csWSgetXXXbyYYY );
> -#endif
> -    if (!retval)
> +    if (number < ARRAY_SIZE(protocols) && protocols[number][0])
>      {
> -        unsigned int i;
> -        for (i = 0; i < ARRAY_SIZE(protocols); i++)
> -        {
> -            if (protocols[i].prot != number) continue;
> -            retval = WS_create_pe( protocols[i].names[0], (char **)protocols[i].names + 1,
> -                                   protocols[i].prot );
> -            break;
> -        }
> +        retval = WS_create_pe( protocols[number][0], (char **)&protocols[number][1], number );
>      }
>      if (!retval)
>      {
> diff --git a/dlls/ws2_32/tests/protocol.c b/dlls/ws2_32/tests/protocol.c
> index 99bd1373a9..323119da1c 100644
> --- a/dlls/ws2_32/tests/protocol.c
> +++ b/dlls/ws2_32/tests/protocol.c
> @@ -192,6 +192,151 @@ static void test_WSAEnumProtocolsW(void)
>      }
>  }
>  
> +static const struct
> +{
> +    const char *names[3];
> +    BOOL missing_from_xp;
> +}
> +protocols[] =
> +{
> +    /* 0 */
> +    { { "ip", "IP" } },
> +    { { "icmp", "ICMP" } },
> +    { },
> +    { { "ggp", "GGP" } },
> +    { },
> +    { },
> +    { { "tcp", "TCP" } },
> +    { },
> +    { { "egp", "EGP" } },
> +    { },
> +    /* 10 */
> +    { },
> +    { },
> +    { { "pup", "PUP" } },
> +    { },
> +    { },
> +    { },
> +    { },
> +    { { "udp", "UDP" } },
> +    { },
> +    { },
> +    /* 20 */
> +    { { "hmp", "HMP" } },
> +    { },
> +    { { "xns-idp", "XNS-IDP" } },
> +    { },
> +    { },
> +    { },
> +    { },
> +    { { "rdp", "RDP" } },
> +    { },
> +    { },
> +    /* 30 */
> +    { },
> +    { },
> +    { },
> +    { },
> +    { },
> +    { },
> +    { },
> +    { },
> +    { },
> +    { },
> +    /* 40 */
> +    { },
> +    { { "ipv6", "IPv6" }, TRUE },
> +    { },
> +    { { "ipv6-route", "IPv6-Route" }, TRUE },
> +    { { "ipv6-frag", "IPv6-Frag" }, TRUE },
> +    { },
> +    { },
> +    { },
> +    { },
> +    { },
> +    /* 50 */
> +    { { "esp", "ESP" }, TRUE },
> +    { { "ah", "AH" }, TRUE },
> +    { },
> +    { },
> +    { },
> +    { },
> +    { },
> +    { },
> +    { { "ipv6-icmp", "IPv6-ICMP" }, TRUE },
> +    { { "ipv6-nonxt", "IPv6-NoNxt" }, TRUE },
> +    /* 60 */
> +    { { "ipv6-opts", "IPv6-Opts" }, TRUE },
> +    { },
> +    { },
> +    { },
> +    { },
> +    { },
> +    { { "rvd", "RVD" } },
> +};
> +
> +void test_getprotobyname(void)
> +{
> +    struct protoent *ent;
> +    char all_caps_name[16];
> +    int i, j;
> +
> +    for (i = 0; i < ARRAY_SIZE(protocols); i++)
> +    {
> +        for (j = 0; protocols[i].names[j]; j++)
> +        {
> +            ent = getprotobyname(protocols[i].names[j]);
> +            ok((ent && ent->p_proto == i) || broken(!ent && protocols[i].missing_from_xp),
> +               "Expected %s to be protocol number %d, got %d\n",
> +               wine_dbgstr_a(protocols[i].names[j]), i, ent ? ent->p_proto : -1);
> +        }
> +
> +        if (protocols[i].names[0])
> +        {
> +            for (j = 0; protocols[i].names[0][j]; j++)
> +                all_caps_name[j] = toupper(protocols[i].names[0][j]);
> +            all_caps_name[j] = 0;
> +            ent = getprotobyname(all_caps_name);
> +            ok((ent && ent->p_proto == i) || broken(!ent && protocols[i].missing_from_xp),
> +               "Expected %s to be protocol number %d, got %d\n",
> +               wine_dbgstr_a(all_caps_name), i, ent ? ent->p_proto : -1);
> +        }
> +    }
> +}
> +
> +void test_getprotobynumber(void)
> +{
> +    struct protoent *ent;
> +    int i, j;
> +
> +    for (i = -1; i <= 256; i++)
> +    {
> +        ent = getprotobynumber(i);
> +
> +        if (i < 0 || i >= ARRAY_SIZE(protocols) || !protocols[i].names[0])
> +        {
> +            ok(!ent,
> +               "Expected protocol number %d to be undefined, got %s\n",
> +               i, wine_dbgstr_a(ent ? ent->p_name : NULL));
> +            continue;
> +        }
> +
> +        ok((ent && ent->p_name && strcmp(ent->p_name, protocols[i].names[0]) == 0) ||
> +           broken(!ent && protocols[i].missing_from_xp),
> +           "Expected protocol number %d to be %s, got %s\n",
> +           i, protocols[i].names[0], wine_dbgstr_a(ent ? ent->p_name : NULL));
> +
> +        for (j = 0; protocols[i].names[1+j]; j++)
> +        {
> +            ok((ent && ent->p_aliases && ent->p_aliases[j] &&
> +                strcmp(ent->p_aliases[j], protocols[i].names[1+j]) == 0) ||
> +               broken(!ent && protocols[i].missing_from_xp),
> +               "Expected protocol number %d alias %d to be %s, got %s\n",
> +               i, j, protocols[i].names[0], wine_dbgstr_a(ent && ent->p_aliases ? ent->p_aliases[j] : NULL));
> +        }
> +    }
> +}
> +
>  START_TEST( protocol )
>  {
>      WSADATA data;
> @@ -201,4 +346,6 @@ START_TEST( protocol )
>  
>      test_WSAEnumProtocolsA();
>      test_WSAEnumProtocolsW();
> +    test_getprotobyname();
> +    test_getprotobynumber();
>  }
> 

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: OpenPGP digital signature
URL: <http://www.winehq.org/pipermail/wine-devel/attachments/20200712/93360866/attachment-0001.sig>


More information about the wine-devel mailing list