⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vm.c

📁 思科路由器仿真器,用来仿7200系列得,可以在电脑上模拟路由器-Cisco router simulator, used to fake a 7200 series can be simulated
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Cisco 7200 (Predator) simulation platform. * Copyright (c) 2005,2006 Christophe Fillot (cf@utc.fr) * * Virtual machine abstraction. * * TODO: IRQ Routing. */#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <errno.h>#include <fcntl.h>#include <sys/types.h>#include <assert.h>#include "registry.h"#include "device.h"#include "pci_dev.h"#include "pci_io.h"#include "vm.h"#include "dev_vtty.h"#include ARCH_INC_FILE#define DEBUG_VM  1/* Type of VM file naming (0=use VM name, 1=use instance ID) */int vm_file_naming_type = 0;/* Initialize a VM object */void vm_object_init(vm_obj_t *obj){   memset(obj,0,sizeof(*obj));}/* Add a VM object to an instance */void vm_object_add(vm_instance_t *vm,vm_obj_t *obj){   obj->next = vm->vm_object_list;   obj->pprev = &vm->vm_object_list;   if (vm->vm_object_list)      vm->vm_object_list->pprev = &obj->next;      vm->vm_object_list = obj;}/* Remove a VM object from an instance */void vm_object_remove(vm_instance_t *vm,vm_obj_t *obj){   if (obj->next)      obj->next->pprev = obj->pprev;   *(obj->pprev) = obj->next;   obj->shutdown(vm,obj->data);}/* Find an object given its name */vm_obj_t *vm_object_find(vm_instance_t *vm,char *name){   vm_obj_t *obj;   for(obj=vm->vm_object_list;obj;obj=obj->next)      if (!strcmp(obj->name,name))         return obj;   return NULL;}/* Check that a mandatory object is present */int vm_object_check(vm_instance_t *vm,char *name){   return(vm_object_find(vm,name) ? 0 : -1);}/* Shut down all objects of an instance */void vm_object_free_list(vm_instance_t *vm){   vm_obj_t *obj,*next;   for(obj=vm->vm_object_list;obj;obj=next) {      next = obj->next;      if (obj->shutdown != NULL) {#if DEBUG_VM         vm_log(vm,"VM_OBJECT","Shutdown of object \"%s\"\n",obj->name);#endif         obj->shutdown(vm,obj->data);      }   }   vm->vm_object_list = NULL;}/* Dump the object list of an instance */void vm_object_dump(vm_instance_t *vm){   vm_obj_t *obj;   printf("VM \"%s\" (%u) object list:\n",vm->name,vm->instance_id);      for(obj=vm->vm_object_list;obj;obj=obj->next) {      printf("  - %-15s [data=%p]\n",obj->name,obj->data);   }   printf("\n");}/* Get VM type */char *vm_get_type(vm_instance_t *vm){   char *machine;   switch(vm->type) {      case VM_TYPE_C3600:         machine = "c3600";         break;      case VM_TYPE_C7200:         machine = "c7200";         break;      case VM_TYPE_C2691:         machine = "c2691";         break;      case VM_TYPE_C3725:         machine = "c3725";         break;     case VM_TYPE_C3745:         machine = "c3745";         break;      default:         machine = "unknown";         break;   }   return machine;}/* Get platform type */char *vm_get_platform_type(vm_instance_t *vm){   char *machine;   switch(vm->type) {      case VM_TYPE_C3600:         machine = "C3600";         break;      case VM_TYPE_C7200:         machine = "C7200";         break;           case VM_TYPE_C2691:         machine = "C2691";         break;      case VM_TYPE_C3725:         machine = "C3725";         break;      case VM_TYPE_C3745:         machine = "C3745";         break;      default:         machine = "VM";         break;   }   return machine;}/* Get MAC address MSB */u_int vm_get_mac_addr_msb(vm_instance_t *vm){   switch(vm->type) {      case VM_TYPE_C3600:         return(0xCC);      case VM_TYPE_C7200:         return(0xCA);      case VM_TYPE_C2691:         return(0xC0);      case VM_TYPE_C3725:         return(0xC2);      case VM_TYPE_C3745:         return(0xC4);      default:         return(0xC6);   }}/* Generate a filename for use by the instance */char *vm_build_filename(vm_instance_t *vm,char *name){   char *filename,*machine;   machine = vm_get_type(vm);   switch(vm_file_naming_type) {      case 1:         filename = dyn_sprintf("%s_i%u_%s",machine,vm->instance_id,name);         break;      case 0:      default:         filename = dyn_sprintf("%s_%s_%s",machine,vm->name,name);         break;   }   assert(filename != NULL);   return filename;}/* Erase lock file */void vm_release_lock(vm_instance_t *vm,int erase){   if (vm->lock_fd != NULL) {      fclose(vm->lock_fd);      vm->lock_fd = NULL;   }      if (vm->lock_file != NULL) {      if (erase)         unlink(vm->lock_file);      free(vm->lock_file);      vm->lock_file = NULL;   }}/* Check that an instance lock file doesn't already exist */int vm_get_lock(vm_instance_t *vm){   char pid_str[32];   struct flock lock;   vm->lock_file = vm_build_filename(vm,"lock");   if (!(vm->lock_fd = fopen(vm->lock_file,"w"))) {      fprintf(stderr,"Unable to create lock file \"%s\".\n",vm->lock_file);      return(-1);   }      memset(&lock,0,sizeof(lock));   lock.l_type   = F_WRLCK;   lock.l_whence = SEEK_SET;   lock.l_start  = 0;   lock.l_len    = 0;      if (fcntl(fileno(vm->lock_fd),F_SETLK,&lock) == -1) {      if (fcntl(fileno(vm->lock_fd),F_GETLK,&lock) == 0) {         snprintf(pid_str,sizeof(pid_str),"%ld",(long)lock.l_pid);      } else {         strcpy(pid_str,"unknown");      }      fprintf(stderr,              "\nAn emulator instance (PID %s) is already running with "              "identifier %u.\n"              "If this is not the case, please erase file \"%s\".\n\n",              pid_str,vm->instance_id,vm->lock_file);      vm_release_lock(vm,FALSE);      return(-1);   }   /* write the emulator PID */   fprintf(vm->lock_fd,"%ld\n",(u_long)getpid());   return(0);}/* Log a message */void vm_flog(vm_instance_t *vm,char *module,char *format,va_list ap){   if (vm->log_fd)      m_flog(vm->log_fd,module,format,ap);}/* Log a message */void vm_log(vm_instance_t *vm,char *module,char *format,...){    va_list ap;   va_start(ap,format);   vm_flog(vm,module,format,ap);   va_end(ap);}/* Close the log file */int vm_close_log(vm_instance_t *vm){   if (vm->log_fd)      fclose(vm->log_fd);   free(vm->log_file);   vm->log_file = NULL;   vm->log_fd = NULL;   return(0);}/* Create the log file */int vm_create_log(vm_instance_t *vm){   vm_close_log(vm);   if (!(vm->log_file = vm_build_filename(vm,"log.txt")))      return(-1);   if (!(vm->log_fd = fopen(vm->log_file,"w"))) {      fprintf(stderr,"VM %s: unable to create log file '%s'\n",              vm->name,vm->log_file);      free(vm->log_file);      vm->log_file = NULL;      return(-1);   }   return(0);}/* Error message */void vm_error(vm_instance_t *vm,char *format,...){    char buffer[2048];   va_list ap;   va_start(ap,format);   vsnprintf(buffer,sizeof(buffer),format,ap);   va_end(ap);   fprintf(stderr,"%s '%s': %s",vm_get_platform_type(vm),vm->name,buffer);}/* Create a new VM instance */vm_instance_t *vm_create(char *name,int instance_id,int machine_type){   vm_instance_t *vm;   if (!(vm = malloc(sizeof(*vm)))) {      fprintf(stderr,"VM %s: unable to create new instance!\n",name);      return NULL;   }      memset(vm,0,sizeof(*vm));   vm->instance_id    = instance_id;   vm->type           = machine_type;   vm->status         = VM_STATUS_HALTED;   vm->jit_use        = JIT_SUPPORT;   vm->vtty_con_type  = VTTY_TYPE_TERM;   vm->vtty_aux_type  = VTTY_TYPE_NONE;   vm->timer_irq_check_itv = VM_TIMER_IRQ_CHECK_ITV;   if (!(vm->name = strdup(name))) {      fprintf(stderr,"VM %s: unable to store instance name!\n",name);      goto err_name;   }   /* create lock file */   if (vm_get_lock(vm) == -1)      goto err_lock;      /* create log file */   if (vm_create_log(vm) == -1)      goto err_log;   if (registry_add(vm->name,OBJ_TYPE_VM,vm) == -1) {      fprintf(stderr,"VM: Unable to store instance '%s' in registry!\n",              vm->name);      goto err_reg_add;   }   return vm; err_reg_add:   vm_close_log(vm); err_log:   free(vm->lock_file); err_lock:   free(vm->name); err_name:   free(vm);   return NULL;}/*  * Shutdown hardware resources used by a VM. * The CPU must have been stopped. */int vm_hardware_shutdown(vm_instance_t *vm){     int i;   if ((vm->status == VM_STATUS_HALTED) || !vm->cpu_group) {      vm_log(vm,"VM","trying to shutdown an inactive VM.\n");      return(-1);   }   vm_log(vm,"VM","shutdown procedure engaged.\n");   /* Mark the VM as halted */   vm->status = VM_STATUS_HALTED;   /* Disable NVRAM operations */   vm->nvram_extract_config = NULL;   vm->nvram_push_config = NULL;   /* Free the object list */   vm_object_free_list(vm);   /* Free resources used by PCI busses */   vm_log(vm,"VM","removing PCI busses.\n");   pci_io_data_remove(vm,vm->pci_io_space);   pci_bus_remove(vm->pci_bus[0]);   pci_bus_remove(vm->pci_bus[1]);   vm->pci_bus[0] = vm->pci_bus[1] = NULL;   /* Free the PCI bus pool */   for(i=0;i<VM_PCI_POOL_SIZE;i++) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -