Annotation of cf/dynamips.c, revision 1.1.1.12

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

unix.superglobalmegacorp.com

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