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_save(char *input, GString *output, sk_conn_st *condat) { 61 | return command_execute(save, "save ", input, output, condat); 62 | } 63 | 64 | int command_show(char *input, GString *output, sk_conn_st *condat) { 65 | return command_execute(show, "show ", input, output, condat); 66 | } 67 | 68 | int command_set( char *input, GString *output, sk_conn_st *condat) { 69 | return command_execute(set, "set ", input, output, condat); 70 | } 71 | 72 | int command_stop(char *input, GString *output, sk_conn_st *condat) { 73 | return command_execute(stop, "stop ", input, output, condat); 74 | } 75 | 76 | 77 | /*++++++++++++++++++++++++++++++++++++++ 78 | 79 | Display available commands. 80 | 81 | ++++++++++++++++++++++++++++++++++++++*/ 82 | int command_help(char *input, GString *output, sk_conn_st *condat) 83 | { 84 | /* by the time it came here, the "help" bit is already taken away. */ 85 | return show_commands(command, "", output); 86 | 87 | } 88 | 89 | 90 | /*++++++++++++++++++++++++++++++++++++++ 91 | 92 | Quit the config session. 93 | 94 | ++++++++++++++++++++++++++++++++++++++*/ 95 | int command_quit(char *input, GString *output, sk_conn_st *condat) { 96 | /* Administrator wishes to quit. */ 97 | return PC_RET_QUIT; 98 | } /* command_quit() */ 99 | 100 | /*++++++++++++++++++++++++++++++++++++++ 101 | 102 | Display the memory allocation records of purify(tm). 103 | The #define must be changed to activate this. 104 | The program will link only with purify. 105 | 106 | ++++++++++++++++++++++++++++++++++++++*/ 107 | int command_purify(char *input, GString *output, sk_conn_st *condat) 108 | { 109 | #if 0 110 | purify_new_inuse(); 111 | #else 112 | g_string_append(output, "NOP"); 113 | #endif 114 | 115 | return 0; 116 | } 117 | 118 | int save_access_tree(char *input, GString *output, sk_conn_st *condat) { 119 | er_ret_t ret_err; 120 | 121 | ret_err = AC_persistence_save(); 122 | 123 | switch (ret_err) { 124 | case AC_OK: 125 | g_string_append(output, "Save successful"); 126 | break; 127 | case AC_SAVING: 128 | g_string_append(output, "Already saving"); 129 | break; 130 | default: 131 | g_string_append(output, "Unknown error"); 132 | return PC_RET_ERR; 133 | } 134 | return 0; 135 | } 136 | 137 | /*++++++++++++++++++++++++++++++++++++++ 138 | 139 | Display a specific constant of the CO module. 140 | 141 | Argument: name of the constant. 142 | 143 | ++++++++++++++++++++++++++++++++++++++*/ 144 | int show_const(char *input, GString *output, sk_conn_st *condat) { 145 | /* Administrator wishes to show constants. */ 146 | char *result, *name, *cursor; 147 | int res = 0; 148 | 149 | if( strlen(input) > 0 ) { 150 | cursor = input; 151 | name = (char *)strsep(&cursor, " "); 152 | 153 | if( (result = CO_const_to_string(name)) != NULL ) { 154 | g_string_append(output, result); 155 | UT_free(result); 156 | } 157 | else { 158 | g_string_append(output, "unknown constant"); 159 | res = PC_RET_ERR; 160 | } 161 | } 162 | else { 163 | g_string_append(output, "name required"); 164 | res = PC_RET_ERR; 165 | } 166 | 167 | return res; 168 | 169 | } /* show_const() */ 170 | 171 | 172 | /*++++++++++++++++++++++++++++++++++++++ 173 | 174 | Display all the constants of the CO module. 175 | 176 | ++++++++++++++++++++++++++++++++++++++*/ 177 | int show_consts(char *input, GString *output, sk_conn_st *condat) 178 | { 179 | /* Administrator wishes to show constants. */ 180 | char *s = CO_to_string(); 181 | g_string_append(output, s); 182 | UT_free(s); 183 | return 0; 184 | } /* show_consts() */ 185 | 186 | 187 | /*++++++++++++++++++++++++++++++++++++++ 188 | 189 | Display all the properties of the PR module. 190 | 191 | ++++++++++++++++++++++++++++++++++++++*/ 192 | int show_props(char *input, GString *output, sk_conn_st *condat) 193 | { 194 | /* Administrator wishes to show properties. */ 195 | char *s = PR_to_string(); 196 | g_string_append(output, s); 197 | UT_free(s); 198 | return 0; 199 | } /* show_props() */ 200 | 201 | 202 | /*++++++++++++++++++++++++++++++++++++++ 203 | 204 | Display all running threads registered with the TA module. 205 | 206 | ++++++++++++++++++++++++++++++++++++++*/ 207 | int show_threads(char *input, GString *output, sk_conn_st *condat) 208 | { 209 | /* Administrator wishes to show thread information. */ 210 | char *s = TA_tostring(); 211 | g_string_append(output, s); 212 | UT_free(s); 213 | return 0; 214 | } /* show_thread() */ 215 | 216 | 217 | /*++++++++++++++++++++++++++++++++++++++ 218 | 219 | Switch the session to a whois session. 220 | 221 | ++++++++++++++++++++++++++++++++++++++*/ 222 | int show_whois(char *input, GString *output, sk_conn_st *condat) 223 | { 224 | /* Go to whois mode */ 225 | PW_interact(condat->sock); 226 | return 0; 227 | } /* show_whois() */ 228 | 229 | 230 | /*++++++++++++++++++++++++++++++++++++++ 231 | 232 | Display the statistics about the server. 233 | 234 | ++++++++++++++++++++++++++++++++++++++*/ 235 | int show_uptime(char *input, GString *output, sk_conn_st *condat) 236 | { 237 | char timestring[26]; 238 | extern time_t SV_starttime; 239 | 240 | ctime_r(&SV_starttime, timestring); 241 | SK_cd_printf( condat, 242 | "System running since %sUptime in seconds: %ld \n\n", 243 | timestring, 244 | time(NULL) - SV_starttime); 245 | 246 | return 0; 247 | } 248 | 249 | /*++++++++++++++++++++++++++++++++++++++ 250 | 251 | Display the whois access statistics from the AC module. 252 | 253 | ++++++++++++++++++++++++++++++++++++++*/ 254 | int show_access(char *input, GString *output, sk_conn_st *condat) 255 | { 256 | int cnt = AC_print_access(output); 257 | 258 | g_string_sprintfa(output, "Found %d nodes\n", cnt); 259 | 260 | return 0; 261 | } /* show_access() */ 262 | 263 | 264 | /*++++++++++++++++++++++++++++++++++++++ 265 | 266 | Display the whois access control list from the AC module. 267 | 268 | ++++++++++++++++++++++++++++++++++++++*/ 269 | int show_acl(char *input, GString *output, sk_conn_st *condat) 270 | { 271 | int cnt = AC_print_acl(output); 272 | 273 | g_string_sprintfa(output, "Found %d nodes\n", cnt); 274 | 275 | return 0; 276 | } /* show_acl() */ 277 | 278 | /*++++++++++++++++++++++++++++++++++++++ 279 | 280 | Display the access tree auto save state. 281 | 282 | ++++++++++++++++++++++++++++++++++++++*/ 283 | int show_auto_save(char *input, GString *output, sk_conn_st *condat) 284 | { 285 | g_string_sprintfa(output, "Auto save is %d\n", ac_auto_save); 286 | 287 | return 0; 288 | } /* show_auto_save() */ 289 | 290 | 291 | /*++++++++++++++++++++++++++++++++++++++ 292 | 293 | Modify the whois access control list in the AC module. 294 | 295 | Arguments: IP[/prefixlength] column=value,column=value... 296 | 297 | Column names as in acl display. Unset columns are inherited. 298 | 299 | ++++++++++++++++++++++++++++++++++++++*/ 300 | int set_acl(char *input, GString *output, sk_conn_st *condat) 301 | { 302 | int res = 0; 303 | 304 | /* first 8 characters ("set acl ") are already skipped */ 305 | if( ! NOERR( AC_asc_acl_command_set( input, "Manual"))) { 306 | g_string_append(output, "Error!\n"); 307 | res = PC_RET_ERR; 308 | } 309 | return res; 310 | } 311 | 312 | /*++++++++++++++++++++++++++++++++++++++ 313 | 314 | Sets the auto save status of the access tree. 315 | 316 | Arguments: 0 = don't auto save, 1 = auto save 317 | 318 | ++++++++++++++++++++++++++++++++++++++*/ 319 | int set_auto_save(char *input, GString *output, sk_conn_st *condat) 320 | { 321 | int res = 0; 322 | 323 | /* Lame */ 324 | switch (input[0]) { 325 | case '0': 326 | ac_auto_save = 0; 327 | printf("0\n"); 328 | break; 329 | case '1': 330 | ac_auto_save = 1; 331 | printf("1\n"); 332 | break; 333 | default: 334 | printf("X\n"); 335 | res = PC_RET_ERR; 336 | } 337 | return res; 338 | } 339 | 340 | /*++++++++++++++++++++++++++++++++++++++ 341 | 342 | Reset the deny counter in the access tree to 0 (after reenabling) 343 | (AC module). 344 | 345 | Argument: IP address. 346 | 347 | ++++++++++++++++++++++++++++++++++++++*/ 348 | int set_nodeny(char *input, GString *output, sk_conn_st *condat) { 349 | 350 | /* first 11 characters ("set nodeny ") are already skipped */ 351 | 352 | if( ! NOERR( AC_asc_set_nodeny(input) )) { 353 | g_string_append(output, "Error\n"); 354 | return PC_RET_ERR; 355 | } 356 | else { 357 | return 0; 358 | } 359 | 360 | } /* set_nodeny() */ 361 | 362 | 363 | /*++++++++++++++++++++++++++++++++++++++ 364 | 365 | Pause/resume update capability of the UD module. 366 | 367 | Argument: the word "pause" or "resume". 368 | 369 | ++++++++++++++++++++++++++++++++++++++*/ 370 | int set_updates(char *input, GString *output, sk_conn_st *condat) 371 | { 372 | char argstr[17]; 373 | int pause=0, resume=0; 374 | int res = 0; 375 | 376 | if( sscanf(input, "%16s", argstr) == 1) { 377 | pause = (strcmp(argstr,"pause") == 0); 378 | resume = (strcmp(argstr,"resume") == 0); 379 | } 380 | 381 | if( !pause && !resume ) { 382 | g_string_append(output, "syntax error."); 383 | res = PC_RET_ERR; 384 | } 385 | else { 386 | /* all params ok. just set the property */ 387 | char *value = pause ? "0" : "1"; 388 | 389 | if (CO_set_const("UD.do_update", value) == 0) { 390 | g_string_append(output, "Constant successfully set\n"); 391 | } 392 | else { 393 | g_string_append(output, "Could not set\n"); 394 | res = PC_RET_ERR; 395 | } 396 | } 397 | return res; 398 | } 399 | /*++++++++++++++++++++++++++++++++++++++ 400 | 401 | Pause/resume queries. 402 | 403 | Argument: the word "pause" or "resume". 404 | 405 | ++++++++++++++++++++++++++++++++++++++*/ 406 | int set_queries(char *input, GString *output, sk_conn_st *condat) 407 | { 408 | char argstr[17]; 409 | int pause=0, resume=0; 410 | int res = 0; 411 | 412 | if( sscanf(input, "%16s", argstr) == 1) { 413 | pause = (strcmp(argstr,"pause") == 0); 414 | resume = (strcmp(argstr,"resume") == 0); 415 | } 416 | 417 | if( !pause && !resume ) { 418 | g_string_append(output, "syntax error."); 419 | res = PC_RET_ERR; 420 | } 421 | else { 422 | 423 | if(pause){ 424 | PW_stopqueries(); 425 | g_string_append(output, "Queries are stopped\n"); 426 | }else { 427 | PW_startqueries(); 428 | g_string_append(output, "Queries are unblocked\n"); 429 | } 430 | } 431 | return res; 432 | } 433 | 434 | 435 | /*++++++++++++++++++++++++++++++++++++++ 436 | 437 | Reset the source. 438 | 439 | Reloads the radix tree. 440 | 441 | Argument: the source name. 442 | 443 | ++++++++++++++++++++++++++++++++++++++*/ 444 | int set_initrx(char *input, GString *output, sk_conn_st *condat) 445 | { 446 | ca_dbSource_t *source_hdl; 447 | int res = 0; 448 | 449 | source_hdl = ca_get_SourceHandleByName(input); 450 | if (source_hdl == NULL){ 451 | g_string_append(output, "Unknown source"); 452 | res = PC_RET_ERR; 453 | } 454 | else if(RP_init_trees( source_hdl ) != RP_OK ) { 455 | g_string_append(output, "Could not re-initialize radix trees"); 456 | res = PC_RET_ERR; 457 | } 458 | else if(RP_sql_load_reg( source_hdl ) != RP_OK ) { 459 | g_string_append(output, "Could not load radix trees"); 460 | res = PC_RET_ERR; 461 | } 462 | else { 463 | g_string_append(output, "radix trees reloaded successfully\n"); 464 | } 465 | return res; 466 | } 467 | /*++++++++++++++++++++++++++++++++++++++ 468 | 469 | Reset the "session time" and "# of tasks" 470 | of a specific thread registered with the TA module. 471 | 472 | ++++++++++++++++++++++++++++++++++++++*/ 473 | #if 0 474 | 475 | /* 476 | XXX: 477 | I've removed this function because it is supposed to pass a pthread_t 478 | to the TA_reset_counters() function. But pthread_t is an opaque 479 | type - on FreeBSD it is a pointer to a structure, so you can't simply 480 | use sscanf() to get one! 481 | 482 | Shane 483 | 2001-09-05 484 | 485 | int set_counter(char *input, GString *output, sk_conn_st *condat) 486 | { 487 | unsigned thr_id; 488 | 489 | if( sscanf(input, "%d", &thr_id) == 1) { 490 | TA_reset_counters(thr_id); 491 | } 492 | return 0; 493 | } 494 | */ 495 | #endif /* 0 */ 496 | 497 | 498 | 499 | /*++++++++++++++++++++++++++++++++++++++ 500 | 501 | Execute a command in the ER path processor of the ER module. 502 | (first subject to macro expansion of the first word). 503 | 504 | Argument is passed entirely to ER_macro_spec(). 505 | 506 | ++++++++++++++++++++++++++++++++++++++*/ 507 | int set_err(char *input, GString *output, sk_conn_st *condat) 508 | { 509 | char *erret = NULL; 510 | int res; 511 | 512 | res = ER_macro_spec(input, &erret); 513 | g_string_append(output, erret); 514 | UT_free(erret); 515 | 516 | return res; 517 | } 518 | 519 | 520 | /*++++++++++++++++++++++++++++++++++++++ 521 | 522 | Show the current setup of the ER path system of the ER module. 523 | 524 | ++++++++++++++++++++++++++++++++++++++*/ 525 | int show_err(char *input, GString *output, sk_conn_st *condat) 526 | { 527 | char *erret = NULL; 528 | 529 | er_print_paths(&erret); 530 | g_string_append(output, erret); 531 | UT_free(erret); 532 | 533 | return 0; 534 | } 535 | 536 | 537 | /*++++++++++++++++++++++++++++++++++++++ 538 | 539 | Show the currently defined macros for the ER path system of the ER module. 540 | 541 | ++++++++++++++++++++++++++++++++++++++*/ 542 | int show_macros(char *input, GString *output, sk_conn_st *condat) 543 | { 544 | ER_macro_list(condat); 545 | return 0; 546 | } 547 | 548 | 549 | 550 | /*++++++++++++++++++++++++++++++++++++++ 551 | 552 | (re)define a macro for the ER path processor. 553 | 554 | Arguments: The first word is treated as a macro name. 555 | The rest of the line is treated as a macro definition. 556 | 557 | ++++++++++++++++++++++++++++++++++++++*/ 558 | int set_macro(char *input, GString *output, sk_conn_st *condat) 559 | { 560 | char *name, *body; 561 | 562 | if( strlen(input) > 0 ) { 563 | body = input; 564 | name = (char *)strsep(&body, " "); 565 | 566 | ER_make_macro( name, body ); 567 | } 568 | 569 | return 0; 570 | } 571 | 572 | 573 | 574 | 575 | /*++++++++++++++++++++++++++++++++++++++ 576 | 577 | Trigger running of the socket watchdog actions for a specific thread 578 | (typically resulting in shutting down of a query thread). 579 | 580 | Arguments are "<socket_id> <thread_id>" as in the output of "show threads". 581 | 582 | Assumes the command is like "stop query 11 17". 583 | This is to limit ambiguities (a new thread on the same socket, for example). 584 | . 585 | ++++++++++++++++++++++++++++++++++++++*/ 586 | #if 0 587 | /* 588 | XXX: 589 | I've removed this function because it is supposed to pass a pthread_t 590 | to the TA_trigger() function. But pthread_t is an opaque 591 | type - on FreeBSD it is a pointer to a structure, so you can't simply 592 | use sscanf() to get one! 593 | 594 | Shane 595 | 2001-09-05 596 | 597 | int stop_query(char *input, GString *output, sk_conn_st *condat) 598 | { 599 | int fd; 600 | unsigned thr; 601 | 602 | 603 | if( sscanf(input, "%d %ud", &fd, &thr) < 2 ) { 604 | g_string_append(output,"error!!"); 605 | return PC_RET_ERR; 606 | } 607 | else { 608 | TA_trigger("whois", fd, thr); 609 | return 0; 610 | } 611 | } 612 | */ 613 | #endif /* 0 */