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

📄 dev_c7200.c

📁 思科路由器仿真器,用来仿7200系列得,可以在电脑上模拟路由器-Cisco router simulator, used to fake a 7200 series can be simulated
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * Cisco 7200 (Predator) simulation platform. * Copyright (c) 2005,2006 Christophe Fillot (cf@utc.fr) * * Generic Cisco 7200 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_c7200.h"#include "dev_vtty.h"#include "registry.h"#include "net.h"/* ======================================================================== *//* CPU EEPROM definitions                                                   *//* ======================================================================== *//* NPE-100 */static m_uint16_t eeprom_cpu_npe100_data[16] = {   0x0135, 0x0203, 0xffff, 0xffff, 0x4906, 0x0004, 0x0000, 0x0000,   0x6000, 0x0000, 0x9901, 0x0600, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,};/* NPE-150 */static m_uint16_t eeprom_cpu_npe150_data[16] = {   0x0115, 0x0203, 0xffff, 0xffff, 0x4906, 0x0004, 0x0000, 0x0000,   0x6000, 0x0000, 0x9901, 0x0600, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,};/* NPE-175 */static m_uint16_t eeprom_cpu_npe175_data[16] = {   0x01C2, 0x0203, 0xffff, 0xffff, 0x4906, 0x0004, 0x0000, 0x0000,   0x6000, 0x0000, 0x9901, 0x0600, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,};/* NPE-200 */static m_uint16_t eeprom_cpu_npe200_data[16] = {   0x0169, 0x0200, 0xffff, 0xffff, 0x4909, 0x8902, 0x0000, 0x0000,   0x6800, 0x0000, 0x9710, 0x2200, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,};/* NPE-225 (same as NPE-175) */static m_uint16_t eeprom_cpu_npe225_data[16] = {   0x01C2, 0x0203, 0xffff, 0xffff, 0x4906, 0x0004, 0x0000, 0x0000,   0x6000, 0x0000, 0x9901, 0x0600, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,};/* NPE-300 */static m_uint16_t eeprom_cpu_npe300_data[16] = {   0x01AE, 0x0402, 0xffff, 0xffff, 0x490D, 0x5108, 0x0000, 0x0000,   0x5000, 0x0000, 0x0012, 0x1000, 0x0000, 0xFFFF, 0xFFFF, 0xFF00,};/* NPE-400 */static m_uint16_t eeprom_cpu_npe400_data[64] = {   0x04FF, 0x4001, 0xF841, 0x0100, 0xC046, 0x0320, 0x001F, 0xC802,   0x8249, 0x14BC, 0x0242, 0x4230, 0xC18B, 0x3131, 0x3131, 0x3131,   0x3131, 0x0000, 0x0004, 0x0002, 0x0285, 0x1C0F, 0xF602, 0xCB87,   0x4E50, 0x452D, 0x3430, 0x3080, 0x0000, 0x0000, 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,};/* NPE-G1 */static m_uint16_t eeprom_cpu_npeg1_data[64] = {   0x04FF, 0x4003, 0x5B41, 0x0200, 0xC046, 0x0320, 0x0049, 0xD00B,   0x8249, 0x1B4C, 0x0B42, 0x4130, 0xC18B, 0x3131, 0x3131, 0x3131,   0x3131, 0x0000, 0x0004, 0x0002, 0x0985, 0x1C13, 0xDA09, 0xCB86,   0x4E50, 0x452D, 0x4731, 0x8000, 0x0000, 0x00FF, 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,};/* * CPU EEPROM array. */static struct cisco_eeprom c7200_cpu_eeprom[] = {   { "npe-100", eeprom_cpu_npe100_data, sizeof(eeprom_cpu_npe100_data)/2 },   { "npe-150", eeprom_cpu_npe150_data, sizeof(eeprom_cpu_npe150_data)/2 },   { "npe-175", eeprom_cpu_npe175_data, sizeof(eeprom_cpu_npe175_data)/2 },   { "npe-200", eeprom_cpu_npe200_data, sizeof(eeprom_cpu_npe200_data)/2 },   { "npe-225", eeprom_cpu_npe225_data, sizeof(eeprom_cpu_npe225_data)/2 },   { "npe-300", eeprom_cpu_npe300_data, sizeof(eeprom_cpu_npe300_data)/2 },   { "npe-400", eeprom_cpu_npe400_data, sizeof(eeprom_cpu_npe400_data)/2 },   { "npe-g1" , eeprom_cpu_npeg1_data , sizeof(eeprom_cpu_npeg1_data)/2 },   { NULL, NULL, 0 },};/* ======================================================================== *//* Midplane EEPROM definitions                                              *//* ======================================================================== *//* Standard Midplane EEPROM contents */static m_uint16_t eeprom_midplane_data[32] = {   0x0106, 0x0101, 0xffff, 0xffff, 0x4906, 0x0303, 0xFFFF, 0xFFFF,   0xFFFF, 0x0400, 0x0000, 0x0000, 0x4C09, 0x10B0, 0xFFFF, 0x00FF,   0x0000, 0x0000, 0x6335, 0x8B28, 0x631D, 0x0000, 0x608E, 0x6D1C,   0x62BB, 0x0000, 0x6335, 0x8B28, 0x0000, 0x0000, 0x6335, 0x8B28,};/* VXR Midplane EEPROM contents */static m_uint16_t eeprom_vxr_midplane_data[32] = {   0x0106, 0x0201, 0xffff, 0xffff, 0x4906, 0x0303, 0xFFFF, 0xFFFF,   0xFFFF, 0x0400, 0x0000, 0x0000, 0x4C09, 0x10B0, 0xFFFF, 0x00FF,   0x0000, 0x0000, 0x6335, 0x8B28, 0x631D, 0x0000, 0x608E, 0x6D1C,   0x62BB, 0x0000, 0x6335, 0x8B28, 0x0000, 0x0000, 0x6335, 0x8B28,};/* * Midplane EEPROM array. */static struct cisco_eeprom c7200_midplane_eeprom[] = {   { "std", eeprom_midplane_data, sizeof(eeprom_midplane_data)/2 },   { "vxr", eeprom_vxr_midplane_data, sizeof(eeprom_vxr_midplane_data)/2 },   { NULL, NULL, 0 },};/* ======================================================================== *//* PEM EEPROM definitions (for NPE-175 and NPE-225)                         *//* ======================================================================== *//* NPE-175 */static m_uint16_t eeprom_pem_npe175_data[16] = {   0x01C3, 0x0100, 0xFFFF, 0xFFFF, 0x490D, 0x8A04, 0x0000, 0x0000,   0x5000, 0x0000, 0x9906, 0x0400, 0x0000, 0xFFFF, 0xFFFF, 0xFFFF,};/* NPE-225 */static m_uint16_t eeprom_pem_npe225_data[16] = {   0x01D5, 0x0100, 0xFFFF, 0xFFFF, 0x490D, 0x8A04, 0x0000, 0x0000,   0x5000, 0x0000, 0x9906, 0x0400, 0x0000, 0xFFFF, 0xFFFF, 0xFFFF,};/* * PEM EEPROM array. */static struct cisco_eeprom c7200_pem_eeprom[] = {   { "npe-175", eeprom_pem_npe175_data, sizeof(eeprom_pem_npe175_data)/2 },   { "npe-225", eeprom_pem_npe225_data, sizeof(eeprom_pem_npe225_data)/2 },   { NULL, NULL, 0 },};/* ======================================================================== *//* Port Adapter Drivers                                                     *//* ======================================================================== */static struct c7200_pa_driver *pa_drivers[] = {   &dev_c7200_io_fe_driver,   &dev_c7200_pa_fe_tx_driver,   &dev_c7200_pa_4e_driver,   &dev_c7200_pa_8e_driver,   &dev_c7200_pa_4t_driver,   &dev_c7200_pa_8t_driver,   &dev_c7200_pa_a1_driver,   &dev_c7200_pa_pos_oc3_driver,   &dev_c7200_pa_4b_driver,      &dev_c7200_pa_mc8te1_driver,   NULL,};/* ======================================================================== *//* NPE Drivers                                                              *//* ======================================================================== */#define DECLARE_NPE(type) \   int (c7200_init_##type)(c7200_t *router)   DECLARE_NPE(npe100);DECLARE_NPE(npe150);DECLARE_NPE(npe175);DECLARE_NPE(npe200);DECLARE_NPE(npe225);DECLARE_NPE(npe300);DECLARE_NPE(npe400);DECLARE_NPE(npeg1);static struct c7200_npe_driver npe_drivers[] = {   { "npe-100" , c7200_init_npe100, 256, 1, C7200_NVRAM_ADDR, 0, 5,  0, 6 },   { "npe-150" , c7200_init_npe150, 256, 1, C7200_NVRAM_ADDR, 0, 5,  0, 6 },   { "npe-175" , c7200_init_npe175, 256, 1, C7200_NVRAM_ADDR, 2, 16, 1, 0 },   { "npe-200" , c7200_init_npe200, 256, 1, C7200_NVRAM_ADDR, 0, 5,  0, 6 },   { "npe-225" , c7200_init_npe225, 256, 1, C7200_NVRAM_ADDR, 2, 16, 1, 0 },   { "npe-300" , c7200_init_npe300, 256, 1, C7200_NVRAM_ADDR, 2, 16, 1, 0 },   { "npe-400" , c7200_init_npe400, 512, 1, C7200_NVRAM_ADDR, 2, 16, 1, 0 },   { "npe-g1"  , c7200_init_npeg1, 1024, 0,      C7200_NPEG1_NVRAM_ADDR, 17, 16, 16, 0 },   { NULL      , NULL },};/* ======================================================================== *//* Cisco 7200 router instances                                              *//* ======================================================================== *//* Directly extract the configuration from the NVRAM device */ssize_t c7200_nvram_extract_config(vm_instance_t *vm,char **buffer){      u_char *base_ptr,*ios_ptr,*cfg_ptr,*end_ptr;   m_uint32_t start,end,nvlen,clen;   m_uint16_t magic1,magic2;    struct vdevice *nvram_dev;   m_uint64_t nvram_addr;   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);   nvram_addr = VM_C7200(vm)->npe_driver->nvram_addr;   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;   end   = ntohl(*PTR_ADJUST(m_uint32_t *,ios_ptr,0x14));   nvlen = ntohl(*PTR_ADJUST(m_uint32_t *,ios_ptr,0x18));   clen  = end - start;   if ((clen + 1) != nvlen) {      vm_error(vm,"invalid configuration size (0x%x)\n",nvlen);      return(-1);   }   if (!(*buffer = malloc(clen+1))) {      vm_error(vm,"unable to allocate config buffer (%u bytes)\n",clen);      return(-1);   }   cfg_ptr = base_ptr + (start - nvram_addr);   if ((start < nvram_addr) || ((cfg_ptr + clen) > end_ptr)) {      vm_error(vm,"NVRAM file too small\n");      return(-1);   }   memcpy(*buffer,cfg_ptr,clen);   (*buffer)[clen] = 0;   return(clen);}/* Directly push the IOS configuration to the NVRAM device */int c7200_nvram_push_config(vm_instance_t *vm,char *buffer,size_t len){     u_char *base_ptr,*ios_ptr,*cfg_ptr;   m_uint32_t cfg_addr,cfg_offset;   m_uint32_t nvram_addr,cklen;   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;   nvram_addr = VM_C7200(vm)->npe_driver->nvram_addr;   cfg_addr = nvram_addr + vm->nvram_rom_space + 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(0x0000);   /* Store file contents to NVRAM */   memcpy(cfg_ptr,buffer,len);   /* Write config addresses + size */   *PTR_ADJUST(m_uint32_t *,ios_ptr,0x10) = htonl(cfg_addr);   *PTR_ADJUST(m_uint32_t *,ios_ptr,0x14) = htonl(cfg_addr + 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);}/* Get an EEPROM for a given NPE model */static const struct cisco_eeprom *c7200_get_cpu_eeprom(char *npe_name){   return(cisco_eeprom_find(c7200_cpu_eeprom,npe_name));}/* Get an EEPROM for a given midplane model */static const struct cisco_eeprom *c7200_get_midplane_eeprom(char *midplane_name){   return(cisco_eeprom_find(c7200_midplane_eeprom,midplane_name));}/* Get a PEM EEPROM for a given NPE model */static const struct cisco_eeprom *c7200_get_pem_eeprom(char *npe_name){   return(cisco_eeprom_find(c7200_pem_eeprom,npe_name));}/* Set the base MAC address of the chassis */static int c7200_burn_mac_addr(c7200_t *router,n_eth_addr_t *addr){   m_uint8_t eeprom_ver;   /* Read EEPROM format version */   cisco_eeprom_get_byte(&router->mp_eeprom,0,&eeprom_ver);   if (eeprom_ver != 1) {      vm_error(router->vm,"c7200_burn_mac_addr: unable to handle "              "EEPROM version %u\n",eeprom_ver);      return(-1);   }   cisco_eeprom_set_region(&router->mp_eeprom,12,addr->eth_addr_byte,6);   return(0);}/* Free specific hardware resources used by C7200 */static void c7200_free_hw_ressources(c7200_t *router){   /* Shutdown all Port Adapters */   c7200_pa_shutdown_all(router);   /* Inactivate the PCMCIA bus */   router->pcmcia_bus = NULL;   /* Remove the hidden I/O bridge */   if (router->io_pci_bridge != NULL) {      pci_bridge_remove(router->io_pci_bridge);      router->io_pci_bridge = NULL;   }}/* Create a new router instance */c7200_t *c7200_create_instance(char *name,int instance_id){   c7200_t *router;   if (!(router = malloc(sizeof(*router)))) {      fprintf(stderr,"C7200 '%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_C7200))) {      fprintf(stderr,"C7200 '%s': unable to create VM instance!\n",name);      goto err_vm;   }   c7200_init_defaults(router);   router->vm->hw_data = router;   router->vm->elf_machine_id = C7200_ELF_MACHINE_ID;   return router; err_vm:   free(router);   return NULL;}/* Free resources used by a router instance */static int c7200_free_instance(void *data,void *arg){   vm_instance_t *vm = data;   c7200_t *router;   int i;   if (vm->type == VM_TYPE_C7200) {      router = VM_C7200(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<C7200_MAX_PA_BAYS;i++)         c7200_pa_remove_all_nio_bindings(router,i);      /* Free specific HW resources */      c7200_free_hw_ressources(router);      /* Free EEPROMs */      cisco_eeprom_free(&router->cpu_eeprom);      cisco_eeprom_free(&router->mp_eeprom);      cisco_eeprom_free(&router->pem_eeprom);      /* Free all resources used by VM */      vm_free(vm);      /* Free the router structure */      free(router);      return(TRUE);   }   return(FALSE);}/* Delete a router instance */

⌨️ 快捷键说明

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