e9b98663a59155386de81a1cd9e17bda4cdd1cc7
[sfrench/samba-autobuild/.git] / source4 / torture / nbt / register.c
1 /* 
2    Unix SMB/CIFS implementation.
3
4    NBT name registration testing
5
6    Copyright (C) Andrew Tridgell 2005
7    
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 2 of the License, or
11    (at your option) any later version.
12    
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17    
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23 #include "includes.h"
24 #include "libcli/nbt/libnbt.h"
25 #include "librpc/gen_ndr/ndr_nbt.h"
26 #include "lib/socket/socket.h"
27
28 #define CHECK_VALUE(v, correct) do { \
29         if ((v) != (correct)) { \
30                 printf("(%s) Incorrect value %s=%d - should be %d\n", \
31                        __location__, #v, v, correct); \
32                 ret = False; \
33         }} while (0)
34
35 #define CHECK_STRING(v, correct) do { \
36         if (StrCaseCmp(v, correct) != 0) { \
37                 printf("(%s) Incorrect value %s='%s' - should be '%s'\n", \
38                        __location__, #v, v, correct); \
39                 ret = False; \
40         }} while (0)
41
42 /*
43   test that a server responds correctly to attempted registrations of its name
44 */
45 static BOOL nbt_register_own(TALLOC_CTX *mem_ctx, struct nbt_name *name, 
46                              const char *address)
47 {
48         struct nbt_name_register io;
49         NTSTATUS status;
50         struct nbt_name_socket *nbtsock = nbt_name_socket_init(mem_ctx, NULL);
51         BOOL ret = True;
52         const char *myaddress = iface_best_ip(address);
53
54         socket_listen(nbtsock->sock, myaddress, 0, 0, 0);
55
56         printf("Testing name defense to name registration\n");
57
58         io.in.name = *name;
59         io.in.dest_addr = address;
60         io.in.address = myaddress;
61         io.in.nb_flags = NBT_NODE_B | NBT_NM_ACTIVE;
62         io.in.register_demand = False;
63         io.in.broadcast = True;
64         io.in.multi_homed = False;
65         io.in.ttl = 1234;
66         io.in.timeout = 3;
67         io.in.retries = 0;
68         
69         status = nbt_name_register(nbtsock, mem_ctx, &io);
70         if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) {
71                 printf("No response from %s for name register\n", address);
72                 return False;
73         }
74         if (!NT_STATUS_IS_OK(status)) {
75                 printf("Bad response from %s for name register - %s\n",
76                        address, nt_errstr(status));
77                 return False;
78         }
79         
80         CHECK_STRING(io.out.name.name, name->name);
81         CHECK_VALUE(io.out.name.type, name->type);
82         CHECK_VALUE(io.out.rcode, NBT_RCODE_ACT);
83
84         /* check a register demand */
85         io.in.address = myaddress;
86         io.in.register_demand = True;
87
88         status = nbt_name_register(nbtsock, mem_ctx, &io);
89         if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) {
90                 printf("No response from %s for name register\n", address);
91                 return False;
92         }
93         if (!NT_STATUS_IS_OK(status)) {
94                 printf("Bad response from %s for name register - %s\n",
95                        address, nt_errstr(status));
96                 return False;
97         }
98         
99         CHECK_STRING(io.out.name.name, name->name);
100         CHECK_VALUE(io.out.name.type, name->type);
101         CHECK_VALUE(io.out.rcode, NBT_RCODE_ACT);
102
103         return ret;
104 }
105
106
107 /*
108   test that a server responds correctly to attempted name refresh requests
109 */
110 static BOOL nbt_refresh_own(TALLOC_CTX *mem_ctx, struct nbt_name *name, 
111                             const char *address)
112 {
113         struct nbt_name_refresh io;
114         NTSTATUS status;
115         struct nbt_name_socket *nbtsock = nbt_name_socket_init(mem_ctx, NULL);
116         BOOL ret = True;
117         const char *myaddress = iface_best_ip(address);
118
119         socket_listen(nbtsock->sock, myaddress, 0, 0, 0);
120
121         printf("Testing name defense to name refresh\n");
122
123         io.in.name = *name;
124         io.in.dest_addr = address;
125         io.in.address = myaddress;
126         io.in.nb_flags = NBT_NODE_B | NBT_NM_ACTIVE;
127         io.in.broadcast = False;
128         io.in.ttl = 1234;
129         io.in.timeout = 3;
130         io.in.retries = 0;
131         
132         status = nbt_name_refresh(nbtsock, mem_ctx, &io);
133         if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) {
134                 printf("No response from %s for name refresh\n", address);
135                 return False;
136         }
137         if (!NT_STATUS_IS_OK(status)) {
138                 printf("Bad response from %s for name refresh - %s\n",
139                        address, nt_errstr(status));
140                 return False;
141         }
142         
143         CHECK_STRING(io.out.name.name, name->name);
144         CHECK_VALUE(io.out.name.type, name->type);
145         CHECK_VALUE(io.out.rcode, NBT_RCODE_ACT);
146
147         return ret;
148 }
149
150
151
152 /*
153   test name registration to a server
154 */
155 BOOL torture_nbt_register(void)
156 {
157         const char *address;
158         struct nbt_name name;
159         TALLOC_CTX *mem_ctx = talloc_new(NULL);
160         NTSTATUS status;
161         BOOL ret = True;
162         
163         name.name = strupper_talloc(mem_ctx, lp_parm_string(-1, "torture", "host"));
164         name.type = NBT_NAME_SERVER;
165         name.scope = NULL;
166
167         /* do an initial name resolution to find its IP */
168         status = resolve_name(&name, mem_ctx, &address);
169         if (!NT_STATUS_IS_OK(status)) {
170                 printf("Failed to resolve %s - %s\n",
171                        name.name, nt_errstr(status));
172                 talloc_free(mem_ctx);
173                 return False;
174         }
175
176         ret &= nbt_register_own(mem_ctx, &name, address);
177         ret &= nbt_refresh_own(mem_ctx, &name, address);
178
179         talloc_free(mem_ctx);
180
181         return ret;
182 }