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