|
|
1.1 root 1: /* 1.1.1.8 root 2: * Cisco router simulation platform. 1.1 root 3: * Copyright (c) 2005,2006 Christophe Fillot ([email protected]) 4: * 5: * Many thanks to Nicolas Szalay for his patch 6: * for the command line parsing and virtual machine 7: * settings (RAM, ROM, NVRAM, ...) 8: */ 9: 10: #include <stdio.h> 11: #include <stdlib.h> 12: #include <unistd.h> 13: #include <string.h> 1.1.1.4 root 14: #include <errno.h> 1.1 root 15: #include <sys/types.h> 16: #include <sys/stat.h> 17: #include <sys/mman.h> 18: #include <signal.h> 19: #include <fcntl.h> 20: #include <assert.h> 1.1.1.4 root 21: #include <getopt.h> 1.1 root 22: 1.1.1.4 root 23: #include "dynamips.h" 1.1.1.8 root 24: #include "cpu.h" 1.1 root 25: #include "mips64_exec.h" 1.1.1.8 root 26: #include "mips64_jit.h" 27: #include "ppc32_exec.h" 28: #include "ppc32_jit.h" 1.1 root 29: #include "dev_c7200.h" 1.1.1.4 root 30: #include "dev_c3600.h" 1.1.1.6 root 31: #include "dev_c2691.h" 32: #include "dev_c3725.h" 33: #include "dev_c3745.h" 1.1.1.8 root 34: #include "dev_c2600.h" 1.1.1.11 root 35: #include "dev_c1700.h" 36: #include "dev_c6msfc1.h" 37: #include "dev_c6sup1.h" 1.1.1.8 root 38: #include "ppc32_vmtest.h" 1.1 root 39: #include "dev_vtty.h" 40: #include "ptask.h" 1.1.1.5 root 41: #include "timer.h" 1.1.1.11 root 42: #include "plugin.h" 1.1.1.4 root 43: #include "registry.h" 44: #include "hypervisor.h" 1.1.1.2 root 45: #include "net_io.h" 1.1 root 46: #include "net_io_bridge.h" 1.1.1.4 root 47: #include "net_io_filter.h" 48: #include "crc.h" 49: #include "atm.h" 50: #include "frame_relay.h" 51: #include "eth_switch.h" 1.1.1.2 root 52: #ifdef GEN_ETH 53: #include "gen_eth.h" 54: #endif 1.1 root 55: #ifdef PROFILE 56: #include "profiler.h" 57: #endif 58: 59: /* Default name for logfile */ 1.1.1.4 root 60: #define LOGFILE_DEFAULT_NAME "dynamips_log.txt" 1.1 root 61: 62: /* Software version */ 1.1.1.4 root 63: const char *sw_version = DYNAMIPS_VERSION"-"JIT_ARCH; 64: 1.1.1.9 root 65: /* Software version tag */ 1.1.1.12! root 66: const char *sw_version_tag = "2007101400"; 1.1.1.9 root 67: 1.1.1.4 root 68: /* Hypervisor */ 69: int hypervisor_mode = 0; 70: int hypervisor_tcp_port = 0; 1.1.1.11 root 71: char *hypervisor_ip_address = NULL; 1.1 root 72: 73: /* Log file */ 1.1.1.4 root 74: char *log_file_name = NULL; 1.1 root 75: FILE *log_file = NULL; 76: 77: /* VM flags */ 78: volatile int vm_save_state = 0; 79: 1.1.1.11 root 80: /* Default platform */ 81: static char *default_platform = "7200"; 82: 1.1 root 83: /* Generic signal handler */ 84: void signal_gen_handler(int sig) 85: { 86: switch(sig) { 87: case SIGHUP: 1.1.1.4 root 88: /* For future use */ 1.1 root 89: break; 90: 91: case SIGQUIT: 92: /* save VM context */ 93: vm_save_state = TRUE; 1.1.1.4 root 94: break; 95: 96: case SIGINT: 97: /* CTRL+C has been pressed */ 98: if (hypervisor_mode) 99: hypervisor_stopsig(); 100: else { 101: /* In theory, this shouldn't happen thanks to VTTY settings */ 102: vm_instance_t *vm; 103: 104: if ((vm = vm_acquire("default")) != NULL) { 105: /* Only forward ctrl-c if user has requested local terminal */ 106: if (vm->vtty_con_type == VTTY_TYPE_TERM) { 107: vtty_store_ctrlc(vm->vtty_con); 108: } else { 109: vm_stop(vm); 110: } 111: vm_release(vm); 112: } else { 113: fprintf(stderr,"Error: Cannot acquire instance handle.\n"); 114: } 115: } 1.1 root 116: break; 117: 118: default: 119: fprintf(stderr,"Unhandled signal %d\n",sig); 120: } 121: } 122: 123: /* Setups signals */ 124: static void setup_signals(void) 125: { 126: struct sigaction act; 127: 128: memset(&act,0,sizeof(act)); 129: act.sa_handler = signal_gen_handler; 130: act.sa_flags = SA_RESTART; 131: sigaction(SIGHUP,&act,NULL); 132: sigaction(SIGQUIT,&act,NULL); 1.1.1.4 root 133: sigaction(SIGINT,&act,NULL); 1.1 root 134: } 135: 1.1.1.4 root 136: /* Create general log file */ 137: static void create_log_file(void) 138: { 139: /* Set the default value of the log file name */ 140: if (!log_file_name) { 141: if (!(log_file_name = strdup(LOGFILE_DEFAULT_NAME))) { 142: fprintf(stderr,"Unable to set log file name.\n"); 143: exit(EXIT_FAILURE); 144: } 1.1 root 145: } 146: 1.1.1.4 root 147: if (!(log_file = fopen(log_file_name,"w"))) { 148: fprintf(stderr,"Unable to create log file (%s).\n",strerror(errno)); 149: exit(EXIT_FAILURE); 1.1 root 150: } 1.1.1.4 root 151: } 1.1 root 152: 1.1.1.4 root 153: /* Close general log file */ 154: static void close_log_file(void) 155: { 156: if (log_file) fclose(log_file); 157: free(log_file_name); 1.1 root 158: 1.1.1.4 root 159: log_file = NULL; 160: log_file_name = NULL; 161: } 1.1 root 162: 1.1.1.4 root 163: /* Display the command line use */ 1.1.1.11 root 164: static void show_usage(vm_instance_t *vm,int argc,char *argv[]) 1.1.1.4 root 165: { 166: printf("Usage: %s [options] <ios_image>\n\n",argv[0]); 1.1 root 167: 1.1.1.4 root 168: printf("Available options:\n" 1.1.1.11 root 169: " -H [<ip_address>:]<tcp_port> : Run in hypervisor mode\n\n" 1.1.1.6 root 170: " -P <platform> : Platform to emulate (7200, 3600, " 1.1.1.11 root 171: "2691, 3725, 3745, 2600 or 1700) " 1.1.1.4 root 172: "(default: 7200)\n\n" 173: " -l <log_file> : Set logging file (default is %s)\n" 174: " -j : Disable the JIT compiler, very slow\n" 175: " --exec-area <size> : Set the exec area size (default: %d Mb)\n" 176: " --idle-pc <pc> : Set the idle PC (default: disabled)\n" 177: " --timer-itv <val> : Timer IRQ interval check (default: %u)\n" 178: "\n" 179: " -i <instance> : Set instance ID\n" 180: " -r <ram_size> : Set the virtual RAM size (default: %u Mb)\n" 181: " -o <rom_size> : Set the virtual ROM size (default: %u Mb)\n" 182: " -n <nvram_size> : Set the NVRAM size (default: %d Kb)\n" 183: " -c <conf_reg> : Set the configuration register " 184: "(default: 0x%04x)\n" 185: " -m <mac_addr> : Set the MAC address of the chassis\n" 186: " (default: automatically generated)\n" 187: " -C <cfg_file> : Import an IOS configuration file " 188: "into NVRAM\n" 189: " -X : Do not use a file to simulate RAM (faster)\n" 1.1.1.6 root 190: " -G <ghost_file> : Use a ghost file to simulate RAM\n" 191: " -g <ghost_file> : Generate a ghost RAM file\n" 1.1.1.8 root 192: " --sparse-mem : Use sparse memory\n" 1.1.1.4 root 193: " -R <rom_file> : Load an alternate ROM (default: embedded)\n" 194: " -k <clock_div> : Set the clock divisor (default: %d)\n" 195: "\n" 196: " -T <port> : Console is on TCP <port>\n" 197: " -U <si_desc> : Console in on serial interface <si_desc>\n" 198: " (default is on the terminal)\n" 199: "\n" 200: " -A <port> : AUX is on TCP <port>\n" 201: " -B <si_desc> : AUX is on serial interface <si_desc>\n" 202: " (default is no AUX port)\n" 203: "\n" 204: " --disk0 <size> : Set PCMCIA ATA disk0: size " 205: "(default: %u Mb)\n" 206: " --disk1 <size> : Set PCMCIA ATA disk1: size " 207: "(default: %u Mb)\n" 208: "\n", 209: LOGFILE_DEFAULT_NAME,MIPS_EXEC_AREA_SIZE,VM_TIMER_IRQ_CHECK_ITV, 1.1.1.11 root 210: vm->ram_size,vm->rom_size,vm->nvram_size,vm->conf_reg_setup, 211: vm->clock_divisor,vm->pcmcia_disk_size[0],vm->pcmcia_disk_size[1]); 1.1.1.4 root 212: 1.1.1.11 root 213: if (vm->platform->cli_show_options != NULL) 214: vm->platform->cli_show_options(vm); 1.1 root 215: 1.1.1.4 root 216: printf("\n" 217: #if DEBUG_SYM_TREE 218: " -S <sym_file> : Load a symbol file\n" 219: #endif 220: " -a <cfg_file> : Virtual ATM switch configuration file\n" 221: " -f <cfg_file> : Virtual Frame-Relay switch configuration " 222: "file\n" 223: " -E <cfg_file> : Virtual Ethernet switch configuration file\n" 224: " -b <cfg_file> : Virtual bridge configuration file\n" 225: " -e : Show network device list of the " 226: "host machine\n" 227: "\n"); 228: 229: printf("<si_desc> format:\n" 230: " \"device{:baudrate{:databits{:parity{:stopbits{:hwflow}}}}}}\"\n" 231: "\n"); 1.1 root 232: 1.1.1.11 root 233: switch(vm->slots_type) { 234: case CISCO_CARD_TYPE_PA: 1.1.1.4 root 235: printf("<pa_desc> format:\n" 1.1.1.11 root 236: " \"slot:sub_slot:pa_driver\"\n" 1.1.1.4 root 237: "\n"); 238: 239: printf("<pa_nio> format:\n" 240: " \"slot:port:netio_type{:netio_parameters}\"\n" 241: "\n"); 1.1 root 242: break; 1.1.1.6 root 243: 1.1.1.11 root 244: case CISCO_CARD_TYPE_NM: 1.1.1.6 root 245: printf("<nm_desc> format:\n" 1.1.1.11 root 246: " \"slot:sub_slot:nm_driver\"\n" 1.1.1.6 root 247: "\n"); 248: 249: printf("<nm_nio> format:\n" 250: " \"slot:port:netio_type{:netio_parameters}\"\n" 251: "\n"); 252: break; 253: 1.1.1.11 root 254: case CISCO_CARD_TYPE_WIC: 255: printf("<wic_desc> format:\n" 256: " \"slot:wic_driver\"\n" 1.1.1.6 root 257: "\n"); 258: 1.1.1.11 root 259: printf("<wic_nio> format:\n" 1.1.1.6 root 260: " \"slot:port:netio_type{:netio_parameters}\"\n" 261: "\n"); 262: break; 1.1.1.11 root 263: } 1.1.1.6 root 264: 1.1.1.11 root 265: if (vm->platform->show_spec_drivers != NULL) 266: vm->platform->show_spec_drivers(); 1.1.1.8 root 267: 1.1.1.11 root 268: /* Show possible slot drivers */ 269: vm_slot_show_drivers(vm); 1.1 root 270: 1.1.1.4 root 271: /* Show the possible NETIO types */ 272: netio_show_types(); 1.1 root 273: } 274: 1.1.1.4 root 275: /* Find an option in the command line */ 276: static char *cli_find_option(int argc,char *argv[],char *opt) 1.1 root 277: { 1.1.1.4 root 278: int i; 1.1 root 279: 1.1.1.4 root 280: for(i=1;i<argc;i++) { 281: if (!strncmp(argv[i],opt,2)) { 282: if (argv[i][2] != 0) 283: return(&argv[i][2]); 284: else { 285: if (argv[i+1] != NULL) 286: return(argv[i+1]); 287: else { 288: fprintf(stderr,"Error: option '%s': no argument specified.\n", 289: opt); 290: exit(EXIT_FAILURE); 291: } 292: } 293: } 1.1 root 294: } 295: 1.1.1.4 root 296: return NULL; 297: } 1.1 root 298: 1.1.1.11 root 299: /* Load plugins */ 300: static void cli_load_plugins(int argc,char *argv[]) 301: { 302: char *str; 303: int i; 304: 305: for(i=1;i<argc;i++) { 306: if (!strncmp(argv[i],"-L",2)) { 307: if (argv[i][2] != 0) 308: str = &argv[i][2]; 309: else { 310: if (argv[i+1] != NULL) 311: str = argv[i+1]; 312: else { 313: fprintf(stderr,"Plugin error: no argument specified.\n"); 314: exit(EXIT_FAILURE); 315: } 316: } 317: 318: if (!plugin_load(str)) 319: fprintf(stderr,"Unable to load plugin '%s'!\n",str); 320: } 321: } 322: } 323: 1.1.1.4 root 324: /* Determine the platform (Cisco 3600, 7200). Default is Cisco 7200 */ 1.1.1.11 root 325: static vm_platform_t *cli_get_platform_type(int argc,char *argv[]) 1.1.1.4 root 326: { 1.1.1.11 root 327: vm_platform_t *platform; 1.1.1.4 root 328: char *str; 1.1 root 329: 1.1.1.11 root 330: if (!(str = cli_find_option(argc,argv,"-P"))) 331: str = default_platform; 332: 333: if (!(platform = vm_platform_find_cli_name(str))) 1.1.1.4 root 334: fprintf(stderr,"Invalid platform type '%s'\n",str); 1.1 root 335: 1.1.1.11 root 336: return platform; 1.1.1.4 root 337: } 1.1 root 338: 1.1.1.4 root 339: static struct option cmd_line_lopts[] = { 340: { "disk0" , 1, NULL, OPT_DISK0_SIZE }, 341: { "disk1" , 1, NULL, OPT_DISK1_SIZE }, 342: { "exec-area" , 1, NULL, OPT_EXEC_AREA }, 343: { "idle-pc" , 1, NULL, OPT_IDLE_PC }, 344: { "timer-itv" , 1, NULL, OPT_TIMER_ITV }, 345: { "vm-debug" , 1, NULL, OPT_VM_DEBUG }, 346: { "iomem-size" , 1, NULL, OPT_IOMEM_SIZE }, 1.1.1.8 root 347: { "sparse-mem" , 0, NULL, OPT_SPARSE_MEM }, 1.1.1.4 root 348: { NULL , 0, NULL, 0 }, 349: }; 1.1 root 350: 1.1.1.4 root 351: /* Create a router instance */ 1.1.1.11 root 352: static vm_instance_t *cli_create_instance(char *name,char *platform_name, 1.1.1.4 root 353: int instance_id) 1.1 root 354: { 1.1.1.8 root 355: vm_instance_t *vm; 1.1 root 356: 1.1.1.11 root 357: vm = vm_create_instance(name,instance_id,platform_name); 358: 359: if (vm == NULL) { 360: fprintf(stderr,"C7200: unable to create instance!\n"); 361: return NULL; 1.1.1.4 root 362: } 1.1.1.11 root 363: 364: return vm; 1.1 root 365: } 366: 1.1.1.4 root 367: /* Parse the command line */ 1.1.1.11 root 368: static int parse_std_cmd_line(int argc,char *argv[]) 1.1 root 369: { 1.1.1.4 root 370: char *options_list = 1.1.1.11 root 371: "r:o:n:c:m:l:C:i:jt:p:s:k:T:U:A:B:a:f:E:b:S:R:M:eXP:N:G:g:L:"; 372: vm_platform_t *platform; 1.1.1.4 root 373: vm_instance_t *vm; 374: int instance_id; 1.1.1.11 root 375: int option; 1.1.1.4 root 376: char *str; 1.1 root 377: 1.1.1.4 root 378: /* Get the instance ID */ 379: instance_id = 0; 1.1 root 380: 1.1.1.4 root 381: /* Use the old VM file naming type */ 382: vm_file_naming_type = 1; 1.1 root 383: 1.1.1.11 root 384: cli_load_plugins(argc,argv); 385: 1.1.1.4 root 386: if ((str = cli_find_option(argc,argv,"-i"))) { 387: instance_id = atoi(str); 388: printf("Instance ID set to %d.\n",instance_id); 389: } 1.1 root 390: 1.1.1.4 root 391: if ((str = cli_find_option(argc,argv,"-N"))) 392: vm_file_naming_type = atoi(str); 1.1.1.2 root 393: 1.1.1.4 root 394: /* Get the platform type */ 1.1.1.11 root 395: if (!(platform = cli_get_platform_type(argc,argv))) 396: exit(EXIT_FAILURE); 1.1.1.4 root 397: 398: /* Create the default instance */ 1.1.1.11 root 399: if (!(vm = cli_create_instance("default",platform->name,instance_id))) 1.1.1.4 root 400: exit(EXIT_FAILURE); 1.1 root 401: 402: opterr = 0; 403: 1.1.1.4 root 404: while((option = getopt_long(argc,argv,options_list, 405: cmd_line_lopts,NULL)) != -1) 406: { 1.1 root 407: switch(option) 408: { 1.1.1.4 root 409: /* Instance ID (already managed) */ 410: case 'i': 411: break; 412: 413: /* Platform (already managed) */ 414: case 'P': 415: break; 416: 1.1 root 417: /* RAM size */ 418: case 'r': 1.1.1.4 root 419: vm->ram_size = strtol(optarg, NULL, 10); 420: printf("Virtual RAM size set to %d MB.\n",vm->ram_size); 1.1 root 421: break; 422: 423: /* ROM size */ 424: case 'o': 1.1.1.4 root 425: vm->rom_size = strtol(optarg, NULL, 10); 426: printf("Virtual ROM size set to %d MB.\n",vm->rom_size); 1.1 root 427: break; 428: 429: /* NVRAM size */ 430: case 'n': 1.1.1.4 root 431: vm->nvram_size = strtol(optarg, NULL, 10); 432: printf("NVRAM size set to %d KB.\n",vm->nvram_size); 1.1 root 433: break; 434: 1.1.1.4 root 435: /* Execution area size */ 436: case OPT_EXEC_AREA: 437: vm->exec_area_size = atoi(optarg); 1.1 root 438: break; 439: 1.1.1.4 root 440: /* PCMCIA disk0 size */ 441: case OPT_DISK0_SIZE: 442: vm->pcmcia_disk_size[0] = atoi(optarg); 443: printf("PCMCIA ATA disk0 size set to %u MB.\n", 444: vm->pcmcia_disk_size[0]); 1.1 root 445: break; 446: 1.1.1.4 root 447: /* PCMCIA disk1 size */ 448: case OPT_DISK1_SIZE: 449: vm->pcmcia_disk_size[1] = atoi(optarg); 450: printf("PCMCIA ATA disk1 size set to %u MB.\n", 451: vm->pcmcia_disk_size[1]); 452: break; 453: 454: /* Config Register */ 455: case 'c': 456: vm->conf_reg_setup = strtol(optarg, NULL, 0); 457: printf("Config. Register set to 0x%x.\n",vm->conf_reg_setup); 1.1 root 458: break; 459: 460: /* IOS configuration file */ 461: case 'C': 1.1.1.4 root 462: vm_ios_set_config(vm,optarg); 1.1 root 463: break; 464: 1.1.1.3 root 465: /* Use physical memory to emulate RAM (no-mapped file) */ 466: case 'X': 1.1.1.4 root 467: vm->ram_mmap = 0; 1.1.1.3 root 468: break; 469: 1.1.1.6 root 470: /* Use a ghost file to simulate RAM */ 471: case 'G': 472: vm->ghost_ram_filename = strdup(optarg); 473: vm->ghost_status = VM_GHOST_RAM_USE; 474: break; 475: 476: /* Generate a ghost RAM image */ 477: case 'g': 478: vm->ghost_ram_filename = strdup(optarg); 479: vm->ghost_status = VM_GHOST_RAM_GENERATE; 480: break; 481: 1.1.1.8 root 482: /* Use sparse memory */ 483: case OPT_SPARSE_MEM: 484: vm->sparse_mem = TRUE; 485: break; 486: 1.1 root 487: /* Alternate ROM */ 488: case 'R': 1.1.1.4 root 489: vm->rom_filename = optarg; 1.1 root 490: break; 491: 1.1.1.4 root 492: /* Idle PC */ 493: case OPT_IDLE_PC: 494: vm->idle_pc = strtoull(optarg,NULL,0); 495: printf("Idle PC set to 0x%llx.\n",vm->idle_pc); 1.1 root 496: break; 497: 1.1.1.4 root 498: /* Timer IRQ check interval */ 499: case OPT_TIMER_ITV: 500: vm->timer_irq_check_itv = atoi(optarg); 1.1 root 501: break; 502: 1.1.1.4 root 503: /* Clock divisor */ 504: case 'k': 505: vm->clock_divisor = atoi(optarg); 506: 507: if (!vm->clock_divisor) { 508: fprintf(stderr,"Invalid Clock Divisor specified!\n"); 509: exit(EXIT_FAILURE); 510: } 511: 512: printf("Using a clock divisor of %d.\n",vm->clock_divisor); 1.1.1.3 root 513: break; 514: 1.1.1.4 root 515: /* Disable JIT */ 516: case 'j': 517: vm->jit_use = FALSE; 1.1 root 518: break; 519: 1.1.1.4 root 520: /* VM debug level */ 521: case OPT_VM_DEBUG: 522: vm->debug_level = atoi(optarg); 523: break; 1.1 root 524: 1.1.1.4 root 525: /* Log file */ 526: case 'l': 527: if (!(log_file_name = strdup(optarg))) { 528: fprintf(stderr,"Unable to set log file name.\n"); 1.1 root 529: exit(EXIT_FAILURE); 530: } 1.1.1.4 root 531: printf("Log file: writing to %s\n",log_file_name); 532: break; 1.1 root 533: 1.1.1.4 root 534: #if DEBUG_SYM_TREE 535: /* Symbol file */ 536: case 'S': 537: vm->sym_filename = strdup(optarg); 1.1 root 538: break; 1.1.1.4 root 539: #endif 1.1 root 540: 541: /* TCP server for Console Port */ 542: case 'T': 1.1.1.4 root 543: vm->vtty_con_type = VTTY_TYPE_TCP; 544: vm->vtty_con_tcp_port = atoi(optarg); 545: break; 546: 547: /* Serial interface for Console port */ 548: case 'U': 549: vm->vtty_con_type = VTTY_TYPE_SERIAL; 550: if (vtty_parse_serial_option(&vm->vtty_con_serial_option,optarg)) { 551: fprintf(stderr, 552: "Invalid Console serial interface descriptor!\n"); 553: exit(EXIT_FAILURE); 554: } 1.1 root 555: break; 556: 557: /* TCP server for AUX Port */ 558: case 'A': 1.1.1.4 root 559: vm->vtty_aux_type = VTTY_TYPE_TCP; 560: vm->vtty_aux_tcp_port = atoi(optarg); 561: break; 562: 563: /* Serial interface for AUX port */ 564: case 'B': 565: vm->vtty_aux_type = VTTY_TYPE_SERIAL; 566: if (vtty_parse_serial_option(&vm->vtty_aux_serial_option,optarg)) { 567: fprintf(stderr,"Invalid AUX serial interface descriptor!\n"); 568: exit(EXIT_FAILURE); 569: } 1.1 root 570: break; 571: 1.1.1.11 root 572: /* Port settings */ 573: case 'p': 574: vm_slot_cmd_create(vm,optarg); 575: break; 576: 577: /* NIO settings */ 578: case 's': 579: vm_slot_cmd_add_nio(vm,optarg); 580: break; 581: 1.1 root 582: /* Virtual ATM switch */ 583: case 'a': 584: if (atmsw_start(optarg) == -1) 585: exit(EXIT_FAILURE); 586: break; 587: 1.1.1.3 root 588: /* Virtual Frame-Relay switch */ 589: case 'f': 590: if (frsw_start(optarg) == -1) 591: exit(EXIT_FAILURE); 592: break; 593: 1.1.1.4 root 594: /* Virtual Ethernet switch */ 595: case 'E': 596: if (ethsw_start(optarg) == -1) 597: exit(EXIT_FAILURE); 598: break; 599: 1.1 root 600: /* Virtual bridge */ 601: case 'b': 602: if (netio_bridge_start(optarg) == -1) 603: exit(EXIT_FAILURE); 604: break; 605: 1.1.1.2 root 606: #ifdef GEN_ETH 607: /* Ethernet device list */ 608: case 'e': 609: gen_eth_show_dev_list(); 610: exit(EXIT_SUCCESS); 611: #endif 612: 1.1.1.11 root 613: /* Load plugin (already handled) */ 614: case 'L': 615: break; 616: 1.1 root 617: /* Oops ! */ 618: case '?': 1.1.1.11 root 619: show_usage(vm,argc,argv); 1.1 root 620: exit(EXIT_FAILURE); 1.1.1.4 root 621: 622: /* Parse options specific to the platform */ 623: default: 1.1.1.11 root 624: if (vm->platform->cli_parse_options != NULL) 625: if (vm->platform->cli_parse_options(vm,option) == -1) 626: exit(EXIT_FAILURE); 1.1 root 627: } 628: } 629: 630: /* Last argument, this is the IOS filename */ 631: if (optind == (argc - 1)) { 632: /* setting IOS image file */ 1.1.1.4 root 633: vm_ios_set_image(vm,argv[optind]); 634: printf("IOS image file: %s\n\n",vm->ios_image); 1.1 root 635: } else { 636: /* IOS missing */ 637: fprintf(stderr,"Please specify an IOS image filename\n"); 1.1.1.11 root 638: show_usage(vm,argc,argv); 1.1 root 639: exit(EXIT_FAILURE); 640: } 641: 1.1.1.4 root 642: vm_release(vm); 643: return(0); 644: } 645: 646: /* 647: * Run in hypervisor mode with a config file if the "-H" option 648: * is present in command line. 649: */ 650: static int run_hypervisor(int argc,char *argv[]) 651: { 1.1.1.11 root 652: char *options_list = "H:l:hN:L:"; 1.1.1.4 root 653: int i,option; 1.1.1.11 root 654: char *index; 655: size_t len; 1.1.1.4 root 656: 657: for(i=1;i<argc;i++) 658: if (!strcmp(argv[i],"-H")) { 659: hypervisor_mode = 1; 660: break; 1.1 root 661: } 662: 1.1.1.4 root 663: /* standard mode with one instance */ 664: if (!hypervisor_mode) 665: return(FALSE); 666: 1.1.1.11 root 667: cli_load_plugins(argc,argv); 668: 1.1.1.4 root 669: opterr = 0; 670: while((option = getopt(argc,argv,options_list)) != -1) { 671: switch(option) 672: { 673: /* Hypervisor TCP port */ 674: case 'H': 1.1.1.11 root 675: index = strrchr(optarg,':'); 676: 677: if (!index) { 678: hypervisor_tcp_port = atoi(optarg); 679: } else { 680: len = index - optarg; 681: hypervisor_ip_address = malloc(len + 1); 682: 683: if (!hypervisor_ip_address) { 684: fprintf(stderr,"Unable to set hypervisor IP address!\n"); 685: exit(EXIT_FAILURE); 686: } 687: 688: memcpy(hypervisor_ip_address,optarg,len); 689: hypervisor_ip_address[len] = '\0'; 690: } 1.1.1.4 root 691: break; 692: 693: /* Log file */ 694: case 'l': 695: if (!(log_file_name = malloc(strlen(optarg)+1))) { 1.1.1.11 root 696: fprintf(stderr,"Unable to set log file name!\n"); 1.1.1.4 root 697: exit(EXIT_FAILURE); 698: } 699: strcpy(log_file_name, optarg); 700: printf("Log file: writing to %s\n",log_file_name); 701: break; 702: 703: /* VM file naming type */ 704: case 'N': 705: vm_file_naming_type = atoi(optarg); 706: break; 1.1.1.11 root 707: 708: /* Load plugin (already handled) */ 709: case 'L': 710: break; 711: 1.1.1.4 root 712: /* Oops ! */ 713: case '?': 1.1.1.11 root 714: //show_usage(argc,argv,VM_TYPE_C7200); 1.1.1.4 root 715: exit(EXIT_FAILURE); 716: } 1.1 root 717: } 718: 1.1.1.4 root 719: return(TRUE); 720: } 1.1 root 721: 1.1.1.4 root 722: /* Delete all objects */ 723: void dynamips_reset(void) 724: { 725: printf("Shutdown in progress...\n"); 1.1 root 726: 1.1.1.6 root 727: /* Delete all virtual router instances */ 1.1.1.11 root 728: vm_delete_all_instances(); 1.1.1.4 root 729: 730: /* Delete ATM and Frame-Relay switches + bridges */ 731: netio_bridge_delete_all(); 732: atmsw_delete_all(); 733: frsw_delete_all(); 734: ethsw_delete_all(); 1.1 root 735: 1.1.1.4 root 736: /* Delete all NIO descriptors */ 737: netio_delete_all(); 1.1 root 738: 1.1.1.4 root 739: printf("Shutdown completed.\n"); 740: } 1.1 root 741: 1.1.1.11 root 742: /* Default platforms */ 743: static int (*platform_register[])(void) = { 744: c7200_platform_register, 745: c3600_platform_register, 746: c3725_platform_register, 747: c3745_platform_register, 748: c2691_platform_register, 749: c2600_platform_register, 750: c1700_platform_register, 751: c6sup1_platform_register, 752: c6msfc1_platform_register, 753: NULL, 754: }; 755: 756: /* Register default platforms */ 757: static void register_default_platforms(void) 758: { 759: int i; 760: 761: for(i=0;platform_register[i];i++) 762: platform_register[i](); 763: } 764: 1.1.1.4 root 765: int main(int argc,char *argv[]) 766: { 767: vm_instance_t *vm; 1.1 root 768: 1.1.1.4 root 769: #ifdef PROFILE 770: atexit(profiler_savestat); 771: #endif 772: 1.1.1.8 root 773: printf("Cisco Router Simulation Platform (version %s)\n",sw_version); 774: printf("Copyright (c) 2005-2007 Christophe Fillot.\n"); 1.1.1.6 root 775: printf("Build date: %s %s\n\n",__DATE__,__TIME__); 1.1.1.4 root 776: 1.1.1.11 root 777: /* Register platforms */ 778: register_default_platforms(); 779: 1.1.1.5 root 780: /* Initialize timers */ 781: timer_init(); 782: 1.1.1.4 root 783: /* Initialize object registry */ 784: registry_init(); 785: 786: /* Initialize ATM module (for HEC checksums) */ 787: atm_init(); 788: 789: /* Initialize CRC functions */ 790: crc_init(); 791: 792: /* Initialize NetIO code */ 793: netio_rxl_init(); 794: 795: /* Initialize NetIO packet filters */ 796: netio_filter_load_all(); 797: 798: /* Initialize VTTY code */ 799: vtty_init(); 800: 801: /* Parse standard command line */ 802: if (!run_hypervisor(argc,argv)) 1.1.1.11 root 803: parse_std_cmd_line(argc,argv); 1.1.1.4 root 804: 805: /* Create general log file */ 806: create_log_file(); 807: 808: /* Periodic tasks initialization */ 809: if (ptask_init(0) == -1) 1.1 root 810: exit(EXIT_FAILURE); 811: 1.1.1.4 root 812: /* Create instruction lookup tables */ 813: mips64_jit_create_ilt(); 814: mips64_exec_create_ilt(); 1.1.1.8 root 815: ppc32_jit_create_ilt(); 816: ppc32_exec_create_ilt(); 1.1.1.11 root 817: 1.1 root 818: setup_signals(); 819: 1.1.1.4 root 820: if (!hypervisor_mode) { 821: /* Initialize the default instance */ 822: vm = vm_acquire("default"); 823: assert(vm != NULL); 824: 1.1.1.11 root 825: if (vm->platform->init_instance(vm) == -1) { 1.1.1.4 root 826: fprintf(stderr,"Unable to initialize router instance.\n"); 827: exit(EXIT_FAILURE); 828: } 1.1 root 829: 1.1.1.7 root 830: #if (DEBUG_INSN_PERF_CNT > 0) || (DEBUG_BLOCK_PERF_CNT > 0) 1.1.1.4 root 831: { 1.1.1.11 root 832: m_uint32_t counter,prev = 0,delta; 1.1.1.4 root 833: while(vm->status == VM_STATUS_RUNNING) { 1.1.1.8 root 834: counter = cpu_get_perf_counter(vm->boot_cpu); 835: delta = counter - prev; 836: prev = counter; 1.1.1.11 root 837: printf("delta = %u\n",delta); 1.1.1.4 root 838: sleep(1); 839: } 840: } 841: #else 842: /* Start instance monitoring */ 843: vm_monitor(vm); 844: #endif 1.1 root 845: 1.1.1.4 root 846: /* Free resources used by instance */ 847: vm_release(vm); 848: } else { 1.1.1.11 root 849: hypervisor_tcp_server(hypervisor_ip_address,hypervisor_tcp_port); 1.1.1.4 root 850: } 1.1 root 851: 1.1.1.4 root 852: dynamips_reset(); 853: close_log_file(); 1.1 root 854: return(0); 855: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.