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

📄 dev_c3600.c

📁 思科路由器仿真器,用来仿7200系列得,可以在电脑上模拟路由器-Cisco router simulator, used to fake a 7200 series can be simulated
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * Cisco 3600 simulation platform. * Copyright (c) 2006 Christophe Fillot (cf@utc.fr) * * Generic Cisco 3600 routines and definitions (EEPROM,...). */#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <sys/types.h>#include <assert.h>#include "mips64.h"#include "dynamips.h"#include "memory.h"#include "device.h"#include "pci_io.h"#include "dev_gt.h"#include "cisco_eeprom.h"#include "dev_c3600.h"#include "dev_c3600_bay.h"#include "dev_vtty.h"#include "registry.h"/* ======================================================================== *//* EEPROM definitions                                                       *//* ======================================================================== *//* Cisco 3620 mainboard EEPROM */static m_uint16_t eeprom_c3620_mainboard_data[64] = {   0x0001, 0x0000, 0x0000, 0x0000, 0x0AFF, 0x7318, 0x5011, 0x0020,   0x0000, 0x0000, 0xA0FF, 0x9904, 0x19FF, 0xFFFF, 0xFFFF, 0x0002,   0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,   0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,   0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,   0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,   0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,   0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,};struct cisco_eeprom eeprom_c3620_mainboard = {   "C3620 Mainboard",    eeprom_c3620_mainboard_data,   sizeof(eeprom_c3620_mainboard_data)/2,};/* Cisco 3640 mainboard EEPROM */static m_uint16_t eeprom_c3640_mainboard_data[64] = {   0x0001, 0x0000, 0x0000, 0x0000, 0x0AFF, 0x7316, 0x8514, 0x0040,   0x0000, 0x0000, 0xA1FF, 0x0102, 0x22FF, 0xFFFF, 0xFFFF, 0x0002,   0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,   0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,   0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,   0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,   0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,   0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,};struct cisco_eeprom eeprom_c3640_mainboard = {   "C3640 Mainboard",    eeprom_c3640_mainboard_data,   sizeof(eeprom_c3640_mainboard_data)/2,};/* Cisco 3660 backplane EEPROM */static m_uint16_t eeprom_c3660_backplane_data[64] = {   0x04FF, 0x4000, 0xC841, 0x0100, 0xC046, 0x0320, 0x0012, 0x8402,   0x4243, 0x3080, 0x0000, 0x0000, 0x0202, 0xC18B, 0x4841, 0x4430,   0x3434, 0x3431, 0x3135, 0x4A03, 0x0081, 0x0000, 0x0000, 0x0400,   0xC28B, 0x4A41, 0x4230, 0x3434, 0x3643, 0x304C, 0x32C3, 0x0600,   0x044D, 0x0EC2, 0xD043, 0x0070, 0xC408, 0x0000, 0x0000, 0x0000,   0x0000, 0x851C, 0x0A5B, 0x0201, 0x06FF, 0xFFFF, 0xFFFF, 0xFFFF,   0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,   0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,};struct cisco_eeprom eeprom_c3660_backplane = {   "C3660 Backplane",    eeprom_c3660_backplane_data,   sizeof(eeprom_c3660_backplane_data)/2,};/* ======================================================================== *//* Chassis Drivers                                                          *//* ======================================================================== */static int c3620_init(c3600_t *router);static int c3640_init(c3600_t *router);static int c3660_init(c3600_t *router);static struct c3600_chassis_driver chassis_drivers[] = {   { "3620"  , 3620, 1, c3620_init, &eeprom_c3620_mainboard },   { "3640"  , 3640, 1, c3640_init, &eeprom_c3640_mainboard },   { "3660"  , 3660, 1, c3660_init, &eeprom_c3660_backplane },   { NULL    , -1,   0, NULL,       NULL },};/* ======================================================================== *//* Network Module Drivers                                                   *//* ======================================================================== */static struct c3600_nm_driver *nm_drivers[] = {   &dev_c3600_nm_1e_driver,   &dev_c3600_nm_4e_driver,   &dev_c3600_nm_1fe_tx_driver,   &dev_c3600_nm_4t_driver,   &dev_c3600_leopard_2fe_driver,   &dev_c3600_nm_16esw_driver,   NULL,};/* ======================================================================== *//* Cisco 3600 router instances                                              *//* ======================================================================== *//* Directly extract the configuration from the NVRAM device */ssize_t c3600_nvram_extract_config(vm_instance_t *vm,char **buffer){   u_char *base_ptr,*ios_ptr,*cfg_ptr,*end_ptr;   m_uint32_t start,nvlen;   m_uint16_t magic1,magic2;    struct vdevice *nvram_dev;   off_t nvram_size;   int fd;   if ((nvram_dev = dev_get_by_name(vm,"nvram")))      dev_sync(nvram_dev);   fd = vm_mmap_open_file(vm,"nvram",&base_ptr,&nvram_size);   if (fd == -1)      return(-1);   ios_ptr = base_ptr + vm->nvram_rom_space;   end_ptr = base_ptr + nvram_size;   if ((ios_ptr + 0x30) >= end_ptr) {      vm_error(vm,"NVRAM file too small\n");      return(-1);   }   magic1  = ntohs(*PTR_ADJUST(m_uint16_t *,ios_ptr,0x06));   magic2  = ntohs(*PTR_ADJUST(m_uint16_t *,ios_ptr,0x08));   if ((magic1 != 0xF0A5) || (magic2 != 0xABCD)) {      vm_error(vm,"unable to find IOS magic numbers (0x%x,0x%x)!\n",               magic1,magic2);      return(-1);   }   start = ntohl(*PTR_ADJUST(m_uint32_t *,ios_ptr,0x10)) + 1;   nvlen = ntohl(*PTR_ADJUST(m_uint32_t *,ios_ptr,0x18));   if (!(*buffer = malloc(nvlen+1))) {      vm_error(vm,"unable to allocate config buffer (%u bytes)\n",nvlen);      return(-1);   }   cfg_ptr = ios_ptr + start + 0x08;   if ((cfg_ptr + nvlen) > end_ptr) {      vm_error(vm,"NVRAM file too small\n");      return(-1);   }   memcpy(*buffer,cfg_ptr,nvlen-1);   (*buffer)[nvlen-1] = 0;   return(nvlen-1);}/* Directly push the IOS configuration to the NVRAM device */int c3600_nvram_push_config(vm_instance_t *vm,char *buffer,size_t len){   u_char *base_ptr,*ios_ptr,*cfg_ptr;   m_uint32_t cfg_offset,cklen,tmp;   m_uint16_t cksum;   int fd;   fd = vm_mmap_create_file(vm,"nvram",vm->nvram_size*1024,&base_ptr);   if (fd == -1)      return(-1);   cfg_offset = 0x2c;   ios_ptr = base_ptr + vm->nvram_rom_space;   cfg_ptr = ios_ptr  + cfg_offset;   /* Write IOS tag, uncompressed config... */   *PTR_ADJUST(m_uint16_t *,ios_ptr,0x06) = htons(0xF0A5);   *PTR_ADJUST(m_uint16_t *,ios_ptr,0x08) = htons(0xABCD);   *PTR_ADJUST(m_uint16_t *,ios_ptr,0x0a) = htons(0x0001);   *PTR_ADJUST(m_uint16_t *,ios_ptr,0x0c) = htons(0x0000);   *PTR_ADJUST(m_uint16_t *,ios_ptr,0x0e) = htons(0x0c04);   /* Store file contents to NVRAM */   memcpy(cfg_ptr,buffer,len);   /* Write config addresses + size */   tmp = cfg_offset - 0x08;   *PTR_ADJUST(m_uint32_t *,ios_ptr,0x10) = htonl(tmp);   *PTR_ADJUST(m_uint32_t *,ios_ptr,0x14) = htonl(tmp + len);   *PTR_ADJUST(m_uint32_t *,ios_ptr,0x18) = htonl(len);   /* Compute the checksum */   cklen = (vm->nvram_size*1024) - (vm->nvram_rom_space + 0x08);   cksum = nvram_cksum((m_uint16_t *)(ios_ptr+0x08),cklen);   *PTR_ADJUST(m_uint16_t *,ios_ptr,0x0c) = htons(cksum);   vm_mmap_close_file(fd,base_ptr,vm->nvram_size*1024);   return(0);}/* Create a new router instance */c3600_t *c3600_create_instance(char *name,int instance_id){   c3600_t *router;   if (!(router = malloc(sizeof(*router)))) {      fprintf(stderr,"C3600 '%s': Unable to create new instance!\n",name);      return NULL;   }   memset(router,0,sizeof(*router));   if (!(router->vm = vm_create(name,instance_id,VM_TYPE_C3600))) {      fprintf(stderr,"C3600 '%s': unable to create VM instance!\n",name);      goto err_vm;   }   c3600_init_defaults(router);   router->vm->hw_data = router;   return router; err_vm:   free(router);   return NULL;}/* Free resources used by a router instance */static int c3600_free_instance(void *data,void *arg){   vm_instance_t *vm = data;   c3600_t *router;   int i;   if (vm->type == VM_TYPE_C3600) {      router = VM_C3600(vm);      /* Stop all CPUs */      if (vm->cpu_group != NULL) {         vm_stop(vm);               if (cpu_group_sync_state(vm->cpu_group) == -1) {            vm_error(vm,"unable to sync with system CPUs.\n");            return(FALSE);         }      }      /* Remove NIO bindings */      for(i=0;i<C3600_MAX_NM_BAYS;i++)         c3600_nm_remove_all_nio_bindings(router,i);      /* Shutdown all Network Modules */      c3600_nm_shutdown_all(router);      /* Free mainboard EEPROM */      cisco_eeprom_free(&router->mb_eeprom);      /* Free all resources used by VM */      vm_free(vm);      /* Free the router structure */      free(router);      return(TRUE);   }   return(FALSE);}/* Delete a router instance */int c3600_delete_instance(char *name){   return(registry_delete_if_unused(name,OBJ_TYPE_VM,                                    c3600_free_instance,NULL));}/* Delete all router instances */int c3600_delete_all_instances(void){   return(registry_delete_type(OBJ_TYPE_VM,c3600_free_instance,NULL));}/* Save configuration of a C3600 instance */void c3600_save_config(c3600_t *router,FILE *fd){   vm_instance_t *vm = router->vm;   struct c3600_nio_binding *nb;   struct c3600_nm_bay *bay;   int i;   /* General settings */   fprintf(fd,"c3600 create %s %u\n",vm->name,vm->instance_id);   fprintf(fd,"c3600 set_chassis %s %s\n",           vm->name,router->chassis_driver->chassis_type);   /* VM configuration */   vm_save_config(vm,fd);   /* Network Module settings */   for(i=0;i<C3600_MAX_NM_BAYS;i++) {      if (!(bay = c3600_nm_get_info(router,i)))         continue;      if (bay->dev_type) {         fprintf(fd,"c3600 add_nm_binding %s %u %s\n",                 vm->name,i,bay->dev_type);      }      for(nb=bay->nio_list;nb;nb=nb->next) {         fprintf(fd,"c3600 add_nio_binding %s %u %u %s\n",                 vm->name,i,nb->port_id,nb->nio->name);      }   }   fprintf(fd,"\n");}/* Save configurations of all C3600 instances */static void c3600_reg_save_config(registry_entry_t *entry,void *opt,int *err){   vm_instance_t *vm = entry->data;   c3600_t *router = VM_C3600(vm);   if (vm->type == VM_TYPE_C3600)      c3600_save_config(router,(FILE *)opt);}void c3600_save_config_all(FILE *fd){   registry_foreach_type(OBJ_TYPE_VM,c3600_reg_save_config,fd,NULL);}/* Set NM EEPROM definition */int c3600_nm_set_eeprom(c3600_t *router,u_int nm_bay,                        const struct cisco_eeprom *eeprom){   if (nm_bay >= C3600_MAX_NM_BAYS) {      vm_error(router->vm,"c3600_nm_set_eeprom: invalid NM Bay %u.\n",nm_bay);      return(-1);   }      if (cisco_eeprom_copy(&router->nm_bay[nm_bay].eeprom,eeprom) == -1) {      vm_error(router->vm,"c3600_nm_set_eeprom: no memory.\n");      return(-1);   }      return(0);}/* Unset NM EEPROM definition (empty bay) */int c3600_nm_unset_eeprom(c3600_t *router,u_int nm_bay){   if (nm_bay >= C3600_MAX_NM_BAYS) {      vm_error(router->vm,"c3600_nm_set_eeprom: invalid NM Bay %u.\n",nm_bay);      return(-1);   }      cisco_eeprom_free(&router->nm_bay[nm_bay].eeprom);   return(0);}/* Check if a bay has a port adapter */int c3600_nm_check_eeprom(c3600_t *router,u_int nm_bay){   if (nm_bay >= C3600_MAX_NM_BAYS)      return(FALSE);   return(cisco_eeprom_valid(&router->nm_bay[nm_bay].eeprom));}/* Get bay info */struct c3600_nm_bay *c3600_nm_get_info(c3600_t *router,u_int nm_bay){   if (nm_bay >= C3600_MAX_NM_BAYS)      return NULL;   return(&router->nm_bay[nm_bay]);}/* Get NM type */char *c3600_nm_get_type(c3600_t *router,u_int nm_bay){   struct c3600_nm_bay *bay;   bay = c3600_nm_get_info(router,nm_bay);   return((bay != NULL) ? bay->dev_type : NULL);}/* Get driver info about the specified slot */void *c3600_nm_get_drvinfo(c3600_t *router,u_int nm_bay){   struct c3600_nm_bay *bay;   bay = c3600_nm_get_info(router,nm_bay);   return((bay != NULL) ? bay->drv_info : NULL);}/* Set driver info for the specified slot */int c3600_nm_set_drvinfo(c3600_t *router,u_int nm_bay,void *drv_info){   struct c3600_nm_bay *bay;   if (!(bay = c3600_nm_get_info(router,nm_bay)))      return(-1);   bay->drv_info = drv_info;   return(0);}/* Get a NM driver */static struct c3600_nm_driver *c3600_nm_get_driver(char *dev_type){   int i;   for(i=0;nm_drivers[i];i++)      if (!strcmp(nm_drivers[i]->dev_type,dev_type))         return nm_drivers[i];   return NULL;}/* Add a NM binding */int c3600_nm_add_binding(c3600_t *router,char *dev_type,u_int nm_bay){      struct c3600_nm_driver *nm_driver;   struct c3600_nm_bay *bay;   if (!(bay = c3600_nm_get_info(router,nm_bay)))      return(-1);   /* check that this bay is empty */   if (bay->dev_type != NULL) {      vm_error(router->vm,"a NM already exists in slot %u.\n",nm_bay);      return(-1);   }   /* find the NM driver */   if (!(nm_driver = c3600_nm_get_driver(dev_type))) {      vm_error(router->vm,"unknown NM type '%s'.\n",dev_type);      return(-1);   }   bay->dev_type = nm_driver->dev_type;   bay->nm_driver = nm_driver;   return(0);  }/* Remove a NM binding */int c3600_nm_remove_binding(c3600_t *router,u_int nm_bay){      struct c3600_nm_bay *bay;   if (!(bay = c3600_nm_get_info(router,nm_bay)))      return(-1);   /* stop if this bay is still active */   if (bay->drv_info != NULL) {      vm_error(router->vm,"slot %u still active.\n",nm_bay);      return(-1);   }   /* check that this bay is not empty */   if (bay->dev_type == NULL) {      vm_error(router->vm,"slot %u is empty.\n",nm_bay);      return(-1);   }      /* remove all NIOs bindings */    c3600_nm_remove_all_nio_bindings(router,nm_bay);   bay->dev_type  = NULL;   bay->nm_driver = NULL;   return(0);}/* Find a NIO binding */struct c3600_nio_binding *c3600_nm_find_nio_binding(c3600_t *router,u_int nm_bay,u_int port_id){      struct c3600_nio_binding *nb;   struct c3600_nm_bay *bay;   if (!(bay = c3600_nm_get_info(router,nm_bay)))      return NULL;

⌨️ 快捷键说明

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