1 | /****************** 2 | Copyright (c) 1999,2000,2001,2002 RIPE NCC 3 | 4 | All Rights Reserved 5 | 6 | Permission to use, copy, modify, and distribute this software and its 7 | documentation for any purpose and without fee is hereby granted, 8 | provided that the above copyright notice appear in all copies and that 9 | both that copyright notice and this permission notice appear in 10 | supporting documentation, and that the name of the author not be 11 | used in advertising or publicity pertaining to distribution of the 12 | software without specific, written prior permission. 13 | 14 | THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING 15 | ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL 16 | AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY 17 | DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN 18 | AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 19 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 20 | ***************************************/ 21 | 22 | #include "rip.h" 23 | 24 | /* this is for purify - to display the memory allocation records */ 25 | extern void purify_new_inuse(void); 26 | 27 | 28 | /*++++++++++++++++++++++++++++++++++++++ 29 | 30 | All functions in this file share the same interface: they take the 31 | arguments to the command given by the user, pointer to a dynamic 32 | GString to which the command output should be appended and the 33 | connection data, so that some things can be displayed directly to it, 34 | bypassing the GString. 35 | 36 | int <command_something> return code. 0 indicates success. 37 | PC_RET_QUIT is a reserved code 38 | that indicates that the connection 39 | should be closed. 40 | 41 | char *input command arguments 42 | 43 | GString *output (dynamic) output string 44 | 45 | sk_conn_st *condat connection data 46 | 47 | ++++++++++++++++++++++++++++++++++++++*/ 48 | 49 | /*++++++++++++++++++++++++++++++++++++++ 50 | 51 | Relay functions for composed commands (eg. "set counter"). 52 | 53 | They run the second word as a command from a specific array 54 | (show/set/stop/whatever). The hardcoded text is used only for help 55 | messages, printed in case the command is wrong as 56 | 57 | "<hardcoded> commands are: <list of possible commands>". 58 | 59 | ++++++++++++++++++++++++++++++++++++++*/ 60 | int command_show(char *input, GString *output, sk_conn_st *condat) { 61 | return command_execute(show, "show ", input, output, condat); 62 | } 63 | 64 | int command_set( char *input, GString *output, sk_conn_st *condat) { 65 | return command_execute(set, "set ", input, output, condat); 66 | } 67 | 68 | int command_stop(char *input, GString *output, sk_conn_st *condat) { 69 | return command_execute(stop, "stop ", input, output, condat); 70 | } 71 | 72 | 73 | /*++++++++++++++++++++++++++++++++++++++ 74 | 75 | Display available commands. 76 | 77 | ++++++++++++++++++++++++++++++++++++++*/ 78 | int command_help(char *input, GString *output, sk_conn_st *condat) 79 | { 80 | /* by the time it came here, the "help" bit is already taken away. */ 81 | return show_commands(command, "", output); 82 | 83 | } 84 | 85 | 86 | /*++++++++++++++++++++++++++++++++++++++ 87 | 88 | Quit the config session. 89 | 90 | ++++++++++++++++++++++++++++++++++++++*/ 91 | int command_quit(char *input, GString *output, sk_conn_st *condat) { 92 | /* Administrator wishes to quit. */ 93 | return PC_RET_QUIT; 94 | } /* command_quit() */ 95 | 96 | /*++++++++++++++++++++++++++++++++++++++ 97 | 98 | Display the memory allocation records of purify(tm). 99 | The #define must be changed to activate this. 100 | The program will link only with purify. 101 | 102 | ++++++++++++++++++++++++++++++++++++++*/ 103 | int command_purify(char *input, GString *output, sk_conn_st *condat) 104 | { 105 | #if 0 106 | purify_new_inuse(); 107 | #else 108 | g_string_append(output, "NOP"); 109 | #endif 110 | 111 | return 0; 112 | } 113 | 114 | 115 | /*++++++++++++++++++++++++++++++++++++++ 116 | 117 | Display a specific constant of the CO module. 118 | 119 | Argument: name of the constant. 120 | 121 | ++++++++++++++++++++++++++++++++++++++*/ 122 | int show_const(char *input, GString *output, sk_conn_st *condat) { 123 | /* Administrator wishes to show constants. */ 124 | char *result, *name, *cursor; 125 | int res = 0; 126 | 127 | if( strlen(input) > 0 ) { 128 | cursor = input; 129 | name = (char *)strsep(&cursor, " "); 130 | 131 | if( (result = CO_const_to_string(name)) != NULL ) { 132 | g_string_append(output, result); 133 | UT_free(result); 134 | } 135 | else { 136 | g_string_append(output, "unknown constant"); 137 | res = PC_RET_ERR; 138 | } 139 | } 140 | else { 141 | g_string_append(output, "name required"); 142 | res = PC_RET_ERR; 143 | } 144 | 145 | return res; 146 | 147 | } /* show_const() */ 148 | 149 | 150 | /*++++++++++++++++++++++++++++++++++++++ 151 | 152 | Display all the constants of the CO module. 153 | 154 | ++++++++++++++++++++++++++++++++++++++*/ 155 | int show_consts(char *input, GString *output, sk_conn_st *condat) 156 | { 157 | /* Administrator wishes to show constants. */ 158 | char *s = CO_to_string(); 159 | g_string_append(output, s); 160 | UT_free(s); 161 | return 0; 162 | } /* show_consts() */ 163 | 164 | 165 | /*++++++++++++++++++++++++++++++++++++++ 166 | 167 | Display all the properties of the PR module. 168 | 169 | ++++++++++++++++++++++++++++++++++++++*/ 170 | int show_props(char *input, GString *output, sk_conn_st *condat) 171 | { 172 | /* Administrator wishes to show properties. */ 173 | char *s = PR_to_string(); 174 | g_string_append(output, s); 175 | UT_free(s); 176 | return 0; 177 | } /* show_props() */ 178 | 179 | 180 | /*++++++++++++++++++++++++++++++++++++++ 181 | 182 | Display all running threads registered with the TA module. 183 | 184 | ++++++++++++++++++++++++++++++++++++++*/ 185 | int show_threads(char *input, GString *output, sk_conn_st *condat) 186 | { 187 | /* Administrator wishes to show thread information. */ 188 | char *s = TA_tostring(); 189 | g_string_append(output, s); 190 | UT_free(s); 191 | return 0; 192 | } /* show_thread() */ 193 | 194 | 195 | /*++++++++++++++++++++++++++++++++++++++ 196 | 197 | Switch the session to a whois session. 198 | 199 | ++++++++++++++++++++++++++++++++++++++*/ 200 | int show_whois(char *input, GString *output, sk_conn_st *condat) 201 | { 202 | /* Go to whois mode */ 203 | PW_interact(condat->sock); 204 | return 0; 205 | } /* show_whois() */ 206 | 207 | 208 | /*++++++++++++++++++++++++++++++++++++++ 209 | 210 | Display the statistics about the server. 211 | 212 | ++++++++++++++++++++++++++++++++++++++*/ 213 | int show_uptime(char *input, GString *output, sk_conn_st *condat) 214 | { 215 | char timestring[26]; 216 | extern time_t SV_starttime; 217 | 218 | ctime_r(&SV_starttime, timestring); 219 | SK_cd_printf( condat, 220 | "System running since %sUptime in seconds: %ld \n\n", 221 | timestring, 222 | time(NULL) - SV_starttime); 223 | 224 | return 0; 225 | } 226 | 227 | /*++++++++++++++++++++++++++++++++++++++ 228 | 229 | Display the whois access statistics from the AC module. 230 | 231 | ++++++++++++++++++++++++++++++++++++++*/ 232 | int show_access(char *input, GString *output, sk_conn_st *condat) 233 | { 234 | int cnt = AC_print_access(output); 235 | 236 | g_string_sprintfa(output, "Found %d nodes\n", cnt); 237 | 238 | return 0; 239 | } /* show_access() */ 240 | 241 | 242 | /*++++++++++++++++++++++++++++++++++++++ 243 | 244 | Display the whois access control list from the AC module. 245 | 246 | ++++++++++++++++++++++++++++++++++++++*/ 247 | int show_acl(char *input, GString *output, sk_conn_st *condat) 248 | { 249 | int cnt = AC_print_acl(output); 250 | 251 | g_string_sprintfa(output, "Found %d nodes\n", cnt); 252 | 253 | return 0; 254 | } /* show_acl() */ 255 | 256 | 257 | /*++++++++++++++++++++++++++++++++++++++ 258 | 259 | Modify the whois access control list in the AC module. 260 | 261 | Arguments: IP[/prefixlength] column=value,column=value... 262 | 263 | Column names as in acl display. Unset columns are inherited. 264 | 265 | ++++++++++++++++++++++++++++++++++++++*/ 266 | int set_acl(char *input, GString *output, sk_conn_st *condat) 267 | { 268 | int res = 0; 269 | 270 | /* first 8 characters ("set acl ") are already skipped */ 271 | if( ! NOERR( AC_asc_acl_command_set( input, "Manual"))) { 272 | g_string_append(output, "Error!\n"); 273 | res = PC_RET_ERR; 274 | } 275 | return res; 276 | } 277 | 278 | /*++++++++++++++++++++++++++++++++++++++ 279 | 280 | Reset the deny counter in the access tree to 0 (after reenabling) 281 | (AC module). 282 | 283 | Argument: IP address. 284 | 285 | ++++++++++++++++++++++++++++++++++++++*/ 286 | int set_nodeny(char *input, GString *output, sk_conn_st *condat) { 287 | 288 | /* first 11 characters ("set nodeny ") are already skipped */ 289 | 290 | if( ! NOERR( AC_asc_set_nodeny(input) )) { 291 | g_string_append(output, "Error\n"); 292 | return PC_RET_ERR; 293 | } 294 | else { 295 | return 0; 296 | } 297 | 298 | } /* set_nodeny() */ 299 | 300 | 301 | /*++++++++++++++++++++++++++++++++++++++ 302 | 303 | Pause/resume update capability of the UD module. 304 | 305 | Argument: the word "pause" or "resume". 306 | 307 | ++++++++++++++++++++++++++++++++++++++*/ 308 | int set_updates(char *input, GString *output, sk_conn_st *condat) 309 | { 310 | char argstr[17]; 311 | int pause=0, resume=0; 312 | int res = 0; 313 | 314 | if( sscanf(input, "%16s", argstr) == 1) { 315 | pause = (strcmp(argstr,"pause") == 0); 316 | resume = (strcmp(argstr,"resume") == 0); 317 | } 318 | 319 | if( !pause && !resume ) { 320 | g_string_append(output, "syntax error."); 321 | res = PC_RET_ERR; 322 | } 323 | else { 324 | /* all params ok. just set the property */ 325 | char *value = pause ? "0" : "1"; 326 | 327 | if (CO_set_const("UD.do_update", value) == 0) { 328 | g_string_append(output, "Constant successfully set\n"); 329 | } 330 | else { 331 | g_string_append(output, "Could not set\n"); 332 | res = PC_RET_ERR; 333 | } 334 | } 335 | return res; 336 | } 337 | /*++++++++++++++++++++++++++++++++++++++ 338 | 339 | Pause/resume queries. 340 | 341 | Argument: the word "pause" or "resume". 342 | 343 | ++++++++++++++++++++++++++++++++++++++*/ 344 | int set_queries(char *input, GString *output, sk_conn_st *condat) 345 | { 346 | char argstr[17]; 347 | int pause=0, resume=0; 348 | int res = 0; 349 | 350 | if( sscanf(input, "%16s", argstr) == 1) { 351 | pause = (strcmp(argstr,"pause") == 0); 352 | resume = (strcmp(argstr,"resume") == 0); 353 | } 354 | 355 | if( !pause && !resume ) { 356 | g_string_append(output, "syntax error."); 357 | res = PC_RET_ERR; 358 | } 359 | else { 360 | 361 | if(pause){ 362 | PW_stopqueries(); 363 | g_string_append(output, "Queries are stopped\n"); 364 | }else { 365 | PW_startqueries(); 366 | g_string_append(output, "Queries are unblocked\n"); 367 | } 368 | } 369 | return res; 370 | } 371 | 372 | 373 | /*++++++++++++++++++++++++++++++++++++++ 374 | 375 | Reset the source. 376 | 377 | Reloads the radix tree. 378 | 379 | Argument: the source name. 380 | 381 | ++++++++++++++++++++++++++++++++++++++*/ 382 | int set_initrx(char *input, GString *output, sk_conn_st *condat) 383 | { 384 | ca_dbSource_t *source_hdl; 385 | int res = 0; 386 | 387 | source_hdl = ca_get_SourceHandleByName(input); 388 | if (source_hdl == NULL){ 389 | g_string_append(output, "Unknown source"); 390 | res = PC_RET_ERR; 391 | } 392 | else if(RP_init_trees( source_hdl ) != RP_OK ) { 393 | g_string_append(output, "Could not re-initialize radix trees"); 394 | res = PC_RET_ERR; 395 | } 396 | else if(RP_sql_load_reg( source_hdl ) != RP_OK ) { 397 | g_string_append(output, "Could not load radix trees"); 398 | res = PC_RET_ERR; 399 | } 400 | else { 401 | g_string_append(output, "radix trees reloaded successfully\n"); 402 | } 403 | return res; 404 | } 405 | /*++++++++++++++++++++++++++++++++++++++ 406 | 407 | Reset the "session time" and "# of tasks" 408 | of a specific thread registered with the TA module. 409 | 410 | ++++++++++++++++++++++++++++++++++++++*/ 411 | #if 0 412 | 413 | /* 414 | XXX: 415 | I've removed this function because it is supposed to pass a pthread_t 416 | to the TA_reset_counters() function. But pthread_t is an opaque 417 | type - on FreeBSD it is a pointer to a structure, so you can't simply 418 | use sscanf() to get one! 419 | 420 | Shane 421 | 2001-09-05 422 | 423 | int set_counter(char *input, GString *output, sk_conn_st *condat) 424 | { 425 | unsigned thr_id; 426 | 427 | if( sscanf(input, "%d", &thr_id) == 1) { 428 | TA_reset_counters(thr_id); 429 | } 430 | return 0; 431 | } 432 | */ 433 | #endif /* 0 */ 434 | 435 | 436 | 437 | /*++++++++++++++++++++++++++++++++++++++ 438 | 439 | Execute a command in the ER path processor of the ER module. 440 | (first subject to macro expansion of the first word). 441 | 442 | Argument is passed entirely to ER_macro_spec(). 443 | 444 | ++++++++++++++++++++++++++++++++++++++*/ 445 | int set_err(char *input, GString *output, sk_conn_st *condat) 446 | { 447 | char *erret = NULL; 448 | int res; 449 | 450 | res = ER_macro_spec(input, &erret); 451 | g_string_append(output, erret); 452 | UT_free(erret); 453 | 454 | return res; 455 | } 456 | 457 | 458 | /*++++++++++++++++++++++++++++++++++++++ 459 | 460 | Show the current setup of the ER path system of the ER module. 461 | 462 | ++++++++++++++++++++++++++++++++++++++*/ 463 | int show_err(char *input, GString *output, sk_conn_st *condat) 464 | { 465 | char *erret = NULL; 466 | 467 | er_print_paths(&erret); 468 | g_string_append(output, erret); 469 | UT_free(erret); 470 | 471 | return 0; 472 | } 473 | 474 | 475 | /*++++++++++++++++++++++++++++++++++++++ 476 | 477 | Show the currently defined macros for the ER path system of the ER module. 478 | 479 | ++++++++++++++++++++++++++++++++++++++*/ 480 | int show_macros(char *input, GString *output, sk_conn_st *condat) 481 | { 482 | ER_macro_list(condat); 483 | return 0; 484 | } 485 | 486 | 487 | 488 | /*++++++++++++++++++++++++++++++++++++++ 489 | 490 | (re)define a macro for the ER path processor. 491 | 492 | Arguments: The first word is treated as a macro name. 493 | The rest of the line is treated as a macro definition. 494 | 495 | ++++++++++++++++++++++++++++++++++++++*/ 496 | int set_macro(char *input, GString *output, sk_conn_st *condat) 497 | { 498 | char *name, *body; 499 | 500 | if( strlen(input) > 0 ) { 501 | body = input; 502 | name = (char *)strsep(&body, " "); 503 | 504 | ER_make_macro( name, body ); 505 | } 506 | 507 | return 0; 508 | } 509 | 510 | 511 | 512 | 513 | /*++++++++++++++++++++++++++++++++++++++ 514 | 515 | Trigger running of the socket watchdog actions for a specific thread 516 | (typically resulting in shutting down of a query thread). 517 | 518 | Arguments are "<socket_id> <thread_id>" as in the output of "show threads". 519 | 520 | Assumes the command is like "stop query 11 17". 521 | This is to limit ambiguities (a new thread on the same socket, for example). 522 | . 523 | ++++++++++++++++++++++++++++++++++++++*/ 524 | #if 0 525 | /* 526 | XXX: 527 | I've removed this function because it is supposed to pass a pthread_t 528 | to the TA_trigger() function. But pthread_t is an opaque 529 | type - on FreeBSD it is a pointer to a structure, so you can't simply 530 | use sscanf() to get one! 531 | 532 | Shane 533 | 2001-09-05 534 | 535 | int stop_query(char *input, GString *output, sk_conn_st *condat) 536 | { 537 | int fd; 538 | unsigned thr; 539 | 540 | 541 | if( sscanf(input, "%d %ud", &fd, &thr) < 2 ) { 542 | g_string_append(output,"error!!"); 543 | return PC_RET_ERR; 544 | } 545 | else { 546 | TA_trigger("whois", fd, thr); 547 | return 0; 548 | } 549 | } 550 | */ 551 | #endif /* 0 */