1 /*
2  * PROJECT:         ReactOS API tests
3  * LICENSE:         LGPLv2.1+ - See COPYING.LIB in the top level directory
4  * PURPOSE:         Test for getservbyport
5  * PROGRAMMER:      Thomas Faber <thomas.faber@reactos.org>
6  */
7 
8 #include "ws2_32.h"
9 
START_TEST(getservbyport)10 START_TEST(getservbyport)
11 {
12     WSADATA WsaData;
13     struct servent *Serv;
14     const struct
15     {
16         int Port;
17         struct
18         {
19             PCSTR Proto;
20             PCSTR Name;
21             PCSTR Aliases[5+1];
22         } Protos[3+1];
23     } Tests[] =
24     {
25         { 0,                                                       },
26         { -1,                                                      },
27         { 80,         { { "tcp", "http", { "www", "www-http" } },
28                         { "udp", NULL                          },
29                         { "xyz", NULL                          } } },
30         { 65536 + 80, { { "tcp", "http", { "www", "www-http" } } } },
31         { 0xffff0050, { { "tcp", "http", { "www", "www-http" } } } },
32         { 25,         { { "tcp", "smtp", { "mail" }            } } },
33         { 445,        { { "tcp", "microsoft-ds"                },
34                         { "udp", "microsoft-ds"                } } },
35         { 514,        { { "tcp", "cmd", { "shell" }            },
36                         { "udp", "syslog"                      } } },
37         { 47624,      { { "tcp", "directplaysrvr"              },
38                         { "udp", "directplaysrvr"              } } },
39     };
40     ULONG i, Proto, Alias;
41     int Error;
42     ULONG ExpectProto;
43 
44     /* not yet initialized */
45     Serv = getservbyport(0, NULL);
46     Error = WSAGetLastError();
47     ok(Serv == NULL, "Serv = %p\n", Serv);
48     ok(Error == WSANOTINITIALISED, "Error = %d\n", Error);
49 
50     Error = WSAStartup(MAKEWORD(2, 2), &WsaData);
51     ok_dec(Error, 0);
52 
53     for (i = 0; i < RTL_NUMBER_OF(Tests); i++)
54     {
55         Proto = 0;
56         do
57         {
58             Serv = getservbyport(htons(Tests[i].Port), Tests[i].Protos[Proto].Proto);
59             Error = WSAGetLastError();
60 
61             /* For a NULL proto we expect the same as the first array entry */
62             ExpectProto = Proto;
63             if (Tests[i].Protos[Proto].Proto == NULL)
64             {
65                 ExpectProto = 0;
66             }
67 
68             if (Tests[i].Protos[ExpectProto].Name == NULL)
69             {
70                 ok(Serv == NULL, "[%d, %s] getservbyport succeeded unexpectedly\n",
71                    Tests[i].Port, Tests[i].Protos[Proto].Proto);
72                 ok(Error == WSANO_DATA, "[%d, %s] getservbyport returned error %d\n",
73                    Tests[i].Port, Tests[i].Protos[Proto].Proto, Error);
74                 continue;
75             }
76             else
77             {
78                 ok(Serv != NULL, "[%d, %s] getservbyport failed with %d\n",
79                    Tests[i].Port, Tests[i].Protos[Proto].Proto, Error);
80             }
81 
82             if (Serv == NULL)
83             {
84                 continue;
85             }
86 
87             /* Check name */
88             ok(!strcmp(Serv->s_name, Tests[i].Protos[ExpectProto].Name),
89                "[%d, %s] s_name = '%s', expected '%s'\n",
90                Tests[i].Port, Tests[i].Protos[Proto].Proto, Serv->s_name, Tests[i].Protos[ExpectProto].Name);
91 
92             /* Check aliases */
93             ok(Serv->s_aliases != NULL, "[%d, %s] s_aliases = NULL\n",
94                Tests[i].Port, Tests[i].Protos[Proto].Proto);
95             for (Alias = 0; Serv->s_aliases; Alias++)
96             {
97                 if (Alias >= RTL_NUMBER_OF(Tests[i].Protos[ExpectProto].Aliases))
98                 {
99                     ok(0, "[%d, %s] Too many aliases\n",
100                        Tests[i].Port, Tests[i].Protos[Proto].Proto);
101                     break;
102                 }
103                 if (Serv->s_aliases[Alias] == NULL)
104                 {
105                     ok(Tests[i].Protos[ExpectProto].Aliases[Alias] == NULL,
106                        "[%d, %s] getservbyport did not return expected alias '%s'\n",
107                        Tests[i].Port, Tests[i].Protos[Proto].Proto, Tests[i].Protos[ExpectProto].Aliases[Alias]);
108                     break;
109                 }
110                 if (Tests[i].Protos[ExpectProto].Aliases[Alias] == NULL)
111                 {
112                     ok(Serv->s_aliases[Alias] == NULL,
113                        "[%d, %s] getservbyport returned additional alias '%s'\n",
114                        Tests[i].Port, Tests[i].Protos[Proto].Proto, Serv->s_aliases[Alias]);
115                     break;
116                 }
117 
118                  ok(!strcmp(Serv->s_aliases[Alias], Tests[i].Protos[ExpectProto].Aliases[Alias]),
119                     "[%d, %s] Got alias '%s', expected '%s'\n",
120                     Tests[i].Port, Tests[i].Protos[Proto].Proto, Serv->s_aliases[Alias],Tests[i].Protos[ExpectProto].Aliases[Alias]);
121             }
122 
123             /* Port should be equal (upper bits are ignored) */
124             ok(ntohs(Serv->s_port) == (Tests[i].Port & 0xffff), "[%d, %s] s_port = %d\n",
125                Tests[i].Port, Tests[i].Protos[Proto].Proto, ntohs(Serv->s_port));
126 
127             /* Check proto */
128             ok(!strcmp(Serv->s_proto, Tests[i].Protos[ExpectProto].Proto), "[%d, %s] s_proto = '%s', expected '%s'\n",
129                Tests[i].Port, Tests[i].Protos[Proto].Proto, Serv->s_proto, Tests[i].Protos[ExpectProto].Proto);
130         /* We want to include one NULL past the last proto in the array */
131         } while (Tests[i].Protos[Proto++].Proto != NULL);
132     }
133 
134     Error = WSACleanup();
135     ok_dec(Error, 0);
136 }
137