Annotation of cf/dynamips.c, revision 1.1.1.13

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.