1 /*
2 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
3 * Use is subject to license terms.
4 */
5
6 /*
7 * BSD 3 Clause License
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions are met:
11 * - Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 *
14 * - Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 *
18 * - Neither the name of Sun Microsystems, Inc. nor the
19 * names of its contributors may be used to endorse or promote products
20 * derived from this software without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY SUN MICROSYSTEMS, INC. ''AS IS'' AND ANY
23 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
24 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
25 * DISCLAIMED. IN NO EVENT SHALL SUN MICROSYSTEMS, INC. BE LIABLE FOR ANY
26 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
27 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
29 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34 /*
35 * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
36 */
37
38 #include <ndmp.h>
39 #include <ndmp_connect.h>
40 #include <log.h>
41 #include <stdlib.h>
42
43 handletable * getmessage_handle(handletable *, ndmp_message, FILE *);
44 int initialize_handletable(handletable *);
45 conn_table * get_connection(conn_table *, conn_handle *, FILE *);
46 int create_conntable(conn_table *, xdr_info *, conn_handle *, FILE *);
47 int getrandom_num();
48 int insert_connection(conn_table *, xdr_info *, conn_handle *, FILE *);
49 void print_conntable(conn_table *);
50 conn_table * delete_connection(conn_table *, conn_handle *, FILE *);
51
52 /*
53 * getmessage_handle() method gets the handletable entry for the messagecode
54 * Args are :
55 * tbl : Handle table
56 * messagecode : NDMP messagecode to be searched
57 * loghandle : Log handle
58 * Return Value : returns the pointer to the handletable structure
59 */
60
61 handletable * getmessage_handle(handletable *tbl, ndmp_message messagecode,
62 FILE *log)
63 {
64
65 while (tbl) {
66
67 if (tbl->messagecode == messagecode) {
68 ndmp_dprintf(log,
69 "Message code %x found & returning struct\n",
70 tbl->messagecode);
71 return (tbl);
72 }
73 tbl++;
74 }
75 return (NULL);
76 }
77
78 /*
79 * initialize_handletable() method initializes the handletable entries with the
80 * messagecode, reply structure size and xdr encode/decode function pointers.
81 * This table is populated here and will remain constant.
82 * Args are :
83 * tbl : Handle table
84 * Return Value : returns SUCCESS(0): Success ERROR(1):Failure
85 */
86
87 int
88 initialize_handletable(handletable *tbl)
89 {
90 /* Initialize the handletable with all the ndmp interface xdr methods */
91
92 tbl[0].messagecode = NDMP_CONNECT_OPEN;
93 tbl[0].replysize = sizeof (ndmp_connect_open_reply);
94
95 tbl[1].messagecode = NDMP_CONFIG_GET_SERVER_INFO;
96 tbl[1].replysize = sizeof (ndmp_config_get_server_info_reply);
97
98 tbl[2].messagecode = NDMP_NOTIFY_CONNECTION_STATUS;
99 tbl[2].replysize = sizeof (ndmp_notify_connection_status_post);
100
101 tbl[3].messagecode = NDMP_CONFIG_GET_SERVER_INFO;
102 tbl[3].replysize = sizeof (ndmp_config_get_server_info_reply);
103
104 tbl[4].messagecode = NDMP_CONNECT_CLIENT_AUTH;
105 tbl[4].replysize = sizeof (ndmp_connect_client_auth_reply);
106
107 tbl[5].messagecode = NDMP_CONNECT_CLOSE;
108 tbl[5].replysize = 0;
109
110 tbl[6].messagecode = NDMP_CONFIG_GET_HOST_INFO;
111 tbl[6].replysize = sizeof (ndmp_config_get_host_info_reply);
112
113 tbl[7].messagecode = NDMP_CONFIG_GET_CONNECTION_TYPE;
114 tbl[7].replysize = sizeof (ndmp_config_get_connection_type_reply);
115
116 tbl[8].messagecode = NDMP_CONFIG_GET_AUTH_ATTR;
117 tbl[8].replysize = sizeof (ndmp_config_get_auth_attr_reply);
118
119 tbl[9].messagecode = NDMP_CONFIG_GET_BUTYPE_INFO;
120 tbl[9].replysize = sizeof (ndmp_config_get_butype_attr_reply);
121
122 tbl[10].messagecode = NDMP_CONFIG_GET_FS_INFO;
123 tbl[10].replysize = sizeof (ndmp_config_get_fs_info_reply);
124
125 tbl[11].messagecode = NDMP_CONFIG_GET_TAPE_INFO;
126 tbl[11].replysize = sizeof (ndmp_config_get_tape_info_reply);
127
128 tbl[12].messagecode = NDMP_CONFIG_GET_SCSI_INFO;
129 tbl[12].replysize = sizeof (ndmp_config_get_scsi_info_reply);
130
131 tbl[13].messagecode = NDMP_CONFIG_GET_EXT_LIST;
132 tbl[13].replysize = sizeof (ndmp_config_get_ext_list_reply);
133
134 tbl[14].messagecode = NDMP_SCSI_OPEN;
135 tbl[14].replysize = sizeof (ndmp_scsi_open_reply);
136
137 tbl[15].messagecode = NDMP_SCSI_CLOSE;
138 tbl[15].replysize = sizeof (ndmp_scsi_close_reply);
139
140 tbl[16].messagecode = NDMP_SCSI_GET_STATE;
141 tbl[16].replysize = sizeof (ndmp_scsi_get_state_reply);
142
143 tbl[17].messagecode = NDMP_SCSI_RESET_DEVICE;
144 tbl[17].replysize = sizeof (ndmp_scsi_reset_device_reply);
145
146 tbl[18].messagecode = NDMP_SCSI_EXECUTE_CDB;
147 tbl[18].replysize = sizeof (ndmp_execute_cdb_reply);
148
149 tbl[19].messagecode = NDMP_TAPE_OPEN;
150 tbl[19].replysize = sizeof (ndmp_tape_open_reply);
151
152 tbl[20].messagecode = NDMP_TAPE_CLOSE;
153 tbl[20].replysize = sizeof (ndmp_tape_close_reply);
154
155 tbl[21].messagecode = NDMP_TAPE_GET_STATE;
156 tbl[21].replysize = sizeof (ndmp_tape_get_state_reply);
157
158 tbl[22].messagecode = NDMP_TAPE_MTIO;
159 tbl[22].replysize = sizeof (ndmp_tape_mtio_reply);
160
161 tbl[23].messagecode = NDMP_TAPE_WRITE;
162 tbl[23].replysize = sizeof (ndmp_tape_write_reply);
163
164 tbl[24].messagecode = NDMP_TAPE_READ;
165 tbl[24].replysize = sizeof (ndmp_tape_read_reply);
166
167 tbl[25].messagecode = NDMP_TAPE_EXECUTE_CDB;
168 tbl[25].replysize = sizeof (ndmp_tape_execute_cdb_reply);
169
170 tbl[26].messagecode = NDMP_DATA_GET_STATE;
171 tbl[26].replysize = sizeof (ndmp_data_get_state_reply);
172
173 tbl[27].messagecode = NDMP_DATA_START_BACKUP;
174 tbl[27].replysize = sizeof (ndmp_data_start_backup_reply);
175
176 tbl[28].messagecode = NDMP_DATA_START_RECOVER;
177 tbl[28].replysize = sizeof (ndmp_data_start_recover_reply);
178
179 tbl[29].messagecode = NDMP_DATA_GET_ENV;
180 tbl[29].replysize = sizeof (ndmp_data_get_env_reply);
181
182 tbl[30].messagecode = NDMP_DATA_STOP;
183 tbl[30].replysize = sizeof (ndmp_data_stop_reply);
184
185 tbl[31].messagecode = NDMP_DATA_LISTEN;
186 tbl[31].replysize = sizeof (ndmp_data_listen_reply);
187
188 tbl[32].messagecode = NDMP_DATA_CONNECT;
189 tbl[32].replysize = sizeof (ndmp_data_connect_reply);
190
191 tbl[33].messagecode = NDMP_DATA_START_RECOVER_FILEHIST;
192 tbl[33].replysize = sizeof (ndmp_data_start_recover_reply);
193
194 tbl[34].messagecode = NDMP_NOTIFY_DATA_HALTED;
195 tbl[34].replysize = sizeof (ndmp_notify_data_halted_post);
196
197 tbl[35].messagecode = NDMP_NOTIFY_MOVER_HALTED;
198 tbl[35].replysize = sizeof (ndmp_notify_mover_halted_post);
199
200 tbl[36].messagecode = NDMP_NOTIFY_MOVER_PAUSED;
201 tbl[36].replysize = sizeof (ndmp_notify_mover_paused_post);
202
203 tbl[37].messagecode = NDMP_NOTIFY_DATA_READ;
204 tbl[37].replysize = sizeof (ndmp_notify_data_read_post);
205
206 tbl[38].messagecode = NDMP_LOG_FILE;
207 tbl[38].replysize = sizeof (ndmp_log_file_post);
208
209 tbl[39].messagecode = NDMP_LOG_MESSAGE;
210 tbl[39].replysize = sizeof (ndmp_log_message_post);
211
212 tbl[40].messagecode = NDMP_FH_ADD_FILE;
213 tbl[40].replysize = sizeof (ndmp_fh_add_file_post);
214
215 tbl[41].messagecode = NDMP_FH_ADD_DIR;
216 tbl[41].replysize = sizeof (ndmp_fh_add_dir_post);
217
218 tbl[42].messagecode = NDMP_FH_ADD_NODE;
219 tbl[42].replysize = sizeof (ndmp_fh_add_node_post);
220
221 tbl[43].messagecode = NDMP_MOVER_GET_STATE;
222 tbl[43].replysize = sizeof (ndmp_mover_get_state_reply);
223
224 tbl[44].messagecode = NDMP_MOVER_LISTEN;
225 tbl[44].replysize = sizeof (ndmp_mover_listen_reply);
226
227 tbl[45].messagecode = NDMP_MOVER_CONTINUE;
228 tbl[45].replysize = sizeof (ndmp_mover_continue_reply);
229
230 tbl[46].messagecode = NDMP_MOVER_ABORT;
231 tbl[46].replysize = sizeof (ndmp_mover_abort_reply);
232
233 tbl[47].messagecode = NDMP_MOVER_STOP;
234 tbl[47].replysize = sizeof (ndmp_mover_stop_reply);
235
236 tbl[48].messagecode = NDMP_MOVER_SET_WINDOW;
237 tbl[48].replysize = sizeof (ndmp_mover_set_window_reply);
238
239 tbl[49].messagecode = NDMP_MOVER_READ;
240 tbl[49].replysize = sizeof (ndmp_mover_read_reply);
241
242 tbl[50].messagecode = NDMP_MOVER_CLOSE;
243 tbl[50].replysize = sizeof (ndmp_mover_close_reply);
244
245 tbl[51].messagecode = NDMP_MOVER_SET_RECORD_SIZE;
246 tbl[51].replysize = sizeof (ndmp_mover_set_record_size_reply);
247
248 tbl[52].messagecode = NDMP_MOVER_CONNECT;
249 tbl[52].replysize = sizeof (ndmp_mover_connect_reply);
250
251 tbl[53].messagecode = NDMP_DATA_ABORT;
252 tbl[53].replysize = sizeof (ndmp_data_abort_reply);
253
254 tbl[54].messagecode = NDMP_CONFIG_SET_EXT_LIST;
255 tbl[54].replysize = sizeof (ndmp_config_set_ext_list_reply);
256
257 tbl[55].messagecode = NDMP_CONNECT_SERVER_AUTH;
258 tbl[55].replysize = sizeof (ndmp_connect_server_auth_reply);
259
260 return (SUCCESS);
261 }
262
263 /*
264 * get_connection() method gets a pointer to the connection object from the
265 * connection table
266 * Args are :
267 * tbl : Connection table
268 * conn : Connection handle to be searched
269 * log : Log file handle
270 * Return Value : returns pointer to the connection table entry found
271 */
272
273 conn_table *
274 get_connection(conn_table *tbl, conn_handle *conn, FILE *log)
275 {
276
277 ndmp_dprintf(log, "In getconnection method \n");
278
279 if (tbl == NULL) {
280 ndmp_dprintf(log, "getconnection(): connection tbl is null \n");
281 return (NULL);
282 }
283
284 while (tbl) {
285 if (tbl->conn->connhandle == conn->connhandle) {
286 ndmp_dprintf(log, "getconnection(): "
287 "connection found \n");
288 return (tbl);
289 }
290 tbl = tbl->next;
291 }
292 ndmp_dprintf(log, "getconnection (): connection not found in table \n");
293 return (NULL);
294 }
295
296 /*
297 * create_conntable() method creates the connection table to hold the connection
298 * objects and inserts the first element in the connection table
299 * Args are :
300 * conntbl2 : Connection table
301 * xinfo : Pointer to the xdr_info containing sd and xdr pointer
302 * conn : Connection object to be inserted in connection table
303 * log : Log file handle
304 * Return Value : returns SUCCESS(0): Success ERROR(1):Failure
305 */
306
307
308 int create_conntable(conn_table *conntbl2, xdr_info *xinfo, conn_handle *conn,
309 FILE *log)
310 {
311 /* Get the random number for the connection handle */
312
313 conn->connhandle = getrandom_num();
314
315 ndmp_dprintf(log, "Inside create_conntable connection handle is %d\n",
316 conn->connhandle);
317
318
319 ndmp_dprintf(log, "conntable is null and creating conn_table \n");
320
321
322 conntbl2->conn->connhandle = conn->connhandle;
323 ndmp_dprintf(log, "connection handle is %d and conn id %d \n",
324 conntbl2->conn->connhandle, conn->connhandle);
325
326 conntbl2->xdrinfo->xdrs = xinfo->xdrs;
327
328 conntbl2->xdrinfo->sd = xinfo->sd;
329
330 ndmp_dprintf(log, "socket desc is %d and xdr sock id %d \n",
331 conntbl2->xdrinfo->sd, xinfo->sd);
332
333 conntbl2->next = NULL;
334
335 return (SUCCESS);
336
337 }
338
339 /*
340 * getrandom_num() method generates random number each time when its called
341 * This method is used to generate unique connection handle.
342 * Return Value : returns random number generated
343 */
344
345 int
346 getrandom_num()
347 {
348 const int HIGH = 100;
349 srand(time(NULL));
350 return (random() % HIGH);
351 }
352
353 /*
354 * insert_connection() method inserts connetion object into an exisiting
355 * connection table
356 * Args are :
357 * conntbl2 : Connection table
358 * xinfo : Pointer to the xdr_info containing sd and xdr pointer
359 * conn : Connection object to be inserted in connection table
360 * log : Log file handle
361 * Return Value : returns SUCCESS(0): Success ERROR(1):Failure
362 */
363
364 int
365 insert_connection(conn_table *conntbl, xdr_info *xinfo, conn_handle *conn,
366 FILE *log)
367 {
368 conn_table *temp = conntbl;
369
370 conn->connhandle = getrandom_num();
371
372 ndmp_dprintf(log, "Inside insert_connection : conn handle %d \n",
373 conn->connhandle);
374
375 while (temp) {
376 if (temp->next == NULL) {
377 conn_table *new = (conn_table *)
378 malloc(sizeof (conn_table));
379
380 new->conn = (conn_handle *)
381 malloc(sizeof (conn_handle));
382
383 new->xdrinfo = (xdr_info *) malloc(sizeof (xdr_info));
384
385 new->xdrinfo->xdrs = (XDR *) malloc(sizeof (XDR));
386
387 new->conn->connhandle = conn->connhandle;
388
389 new->xdrinfo->xdrs = xinfo->xdrs;
390
391 new->xdrinfo->sd = xinfo->sd;
392
393 new->next = NULL;
394
395 temp->next = new;
396 return (SUCCESS);
397
398 }
399 temp = temp->next;
400 }
401
402 return (ERROR);
403 }
404
405 /*
406 * print_conntable() method prints the connection table entries
407 * This method is used for debugging pursposes
408 * Args are :
409 * conntbl : Connection table
410 * Return Value : returns void
411 */
412
413 void
414 print_conntable(conn_table *conntbl)
415 {
416 printf("Table contents are \n");
417
418 while (conntbl) {
419
420 printf("Connection handle is %d \n", conntbl->conn->connhandle);
421 printf("Socket id is %d \n", conntbl->xdrinfo->sd);
422 conntbl = conntbl->next;
423 }
424 }
425
426 /*
427 * delete_connection() method frees up memory allocated for conn_table entries
428 * and deletes the connection object from connection table
429 * Args are :
430 * tbl : Connection table
431 * conn : Connection object to be deleted
432 * log : Log file handle
433 * Return Value : returns pointer to the connection table after deletion
434 */
435
436 conn_table *
437 delete_connection(conn_table *tbl, conn_handle *conn, FILE *log)
438 {
439 conn_table *temp = tbl;
440 conn_table *temp1 = temp;
441
442 if (temp->next == NULL) {
443 tbl = temp->next;
444
445 /* close the socket */
446 shutdown(temp->xdrinfo->sd, 2);
447 free(temp->xdrinfo->xdrs);
448 free(temp->xdrinfo);
449 free(temp);
450 ndmp_dprintf(log, "delete_connection():Deletion successful \n");
451 return (tbl);
452 }
453
454 while (temp) {
455 if ((temp->conn->connhandle == conn->connhandle)) {
456 temp1->next = temp->next;
457 /* Close the socket */
458 shutdown(temp->xdrinfo->sd, 2);
459 free(temp->xdrinfo->xdrs);
460 free(temp->xdrinfo);
461 free(temp);
462
463 return (tbl);
464 }
465 temp1 = temp;
466 temp = temp->next;
467 }
468
469 return (tbl);
470 }