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

📄 dev_c2600.c

📁 思科路由器仿真器,用来仿7200系列得,可以在电脑上模拟路由器
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Cisco router simulation platform. * Copyright (c) 2006 Christophe Fillot (cf@utc.fr) * * Generic Cisco 2600 routines and definitions (EEPROM,...). */#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <sys/types.h>#include <assert.h>#include "cpu.h"#include "vm.h"#include "dynamips.h"#include "memory.h"#include "device.h"#include "ppc32_mem.h"#include "pci_io.h"#include "cisco_eeprom.h"#include "dev_mpc860.h"#include "dev_rom.h"#include "dev_c2600.h"#include "dev_c2600_iofpga.h"#include "dev_vtty.h"#include "registry.h"/* ======================================================================== *//* EEPROM definitions                                                       *//* ======================================================================== *//* Cisco 2600 mainboard EEPROM */static m_uint16_t eeprom_c2600_mb_data[] = {   0x0101, 0x0404, 0x0000, 0x0000, 0x4320, 0x00FF, 0x0091, 0x0020,   0x0000, 0x0000, 0x0000, 0x0000, 0x3030, 0x3000, 0x0030, 0x3030,   0x3002, 0x0200, 0x0000, 0x0000, 0x00FF, 0xFFFF, 0x5006, 0x490B,   0x1709, 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 c2600_mb_id {   char *name;   char *mb_driver;   m_uint16_t id;   int xm_model;   int supported;};struct c2600_mb_id c2600_mainboard_id[] = {   { "2610"   , "CISCO2600-MB-1E"  , 0x0091, FALSE, TRUE  },   { "2611"   , "CISCO2600-MB-2E"  , 0x0092, FALSE, TRUE  },   { "2620"   , "CISCO2600-MB-1FE" , 0x0094, FALSE, TRUE  },   { "2621"   , "CISCO2600-MB-2FE" , 0x00a2, FALSE, TRUE  },   { "2610XM" , "CISCO2600-MB-1FE" , 0x036a, TRUE,  TRUE  },   { "2611XM" , "CISCO2600-MB-2FE" , 0x036b, TRUE,  FALSE },   { "2620XM" , "CISCO2600-MB-1FE" , 0x036c, TRUE,  TRUE  },   { "2621XM" , "CISCO2600-MB-2FE" , 0x036d, TRUE,  FALSE },   { "2650XM" , "CISCO2600-MB-1FE" , 0x036e, TRUE,  TRUE  },   { "2651XM" , "CISCO2600-MB-2FE" , 0x036f, TRUE,  FALSE },   { NULL     , NULL               , 0x0000, FALSE, FALSE },};/* ======================================================================== *//* Network Module Drivers                                                   *//* ======================================================================== */static struct cisco_card_driver *nm_drivers[] = {   &dev_c2600_mb1e_eth_driver,   &dev_c2600_mb2e_eth_driver,   &dev_c2600_mb1fe_eth_driver,   &dev_c2600_mb2fe_eth_driver,   &dev_c2600_nm_1e_driver,   &dev_c2600_nm_4e_driver,   &dev_c2600_nm_1fe_tx_driver,   &dev_c2600_nm_16esw_driver,   &dev_c2600_nm_nam_driver,   &dev_c2600_nm_cids_driver,   NULL,};/* ======================================================================== *//* Cisco 2600 router instances                                              *//* ======================================================================== *//* Initialize default parameters for a C2600 */static void c2600_init_defaults(c2600_t *router);/* Read a byte from the NVRAM */static inline m_uint8_t nvram_read_byte(u_char *base,u_int offset){   m_uint8_t *ptr;   ptr = (m_uint8_t *)base + (offset << 2);   return(*ptr);}/* Write a byte to the NVRAM */static inline void nvram_write_byte(u_char *base,u_int offset,m_uint8_t val){   m_uint8_t *ptr;   ptr = (m_uint8_t *)base + (offset << 2);   *ptr = val;}/* Read a 16-bit value from NVRAM */static m_uint16_t nvram_read16(u_char *base,u_int offset){   m_uint16_t val;   val =  nvram_read_byte(base,offset) << 8;   val |= nvram_read_byte(base,offset+1);   return(val);}/* Write a 16-bit value to NVRAM */static void nvram_write16(u_char *base,u_int offset,m_uint16_t val){   nvram_write_byte(base,offset,val >> 8);   nvram_write_byte(base,offset+1,val & 0xFF);}/* Read a 32-bit value from NVRAM */static m_uint32_t nvram_read32(u_char *base,u_int offset){   m_uint32_t val;   val =  nvram_read_byte(base,offset)   << 24;   val |= nvram_read_byte(base,offset+1) << 16;   val |= nvram_read_byte(base,offset+2) << 8;   val |= nvram_read_byte(base,offset+3);   return(val);}/* Write a 32-bit value to NVRAM */static void nvram_write32(u_char *base,u_int offset,m_uint32_t val){   nvram_write_byte(base,offset,val >> 24);   nvram_write_byte(base,offset+1,val >> 16);   nvram_write_byte(base,offset+2,val >> 8);   nvram_write_byte(base,offset+3,val & 0xFF);}/* Read a buffer from NVRAM */static void nvram_memcpy_from(u_char *base,u_int offset,u_char *data,u_int len){   u_int i;   for(i=0;i<len;i++) {      *data = nvram_read_byte(base,offset+i);      data++;   }}/* Write a buffer from NVRAM */static void nvram_memcpy_to(u_char *base,u_int offset,u_char *data,u_int len){   u_int i;   for(i=0;i<len;i++) {      nvram_write_byte(base,offset+i,*data);      data++;   }}/* Directly extract the configuration from the NVRAM device */ssize_t c2600_nvram_extract_config(vm_instance_t *vm,u_char **buffer){   u_char *base_ptr;   u_int 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 = vm->nvram_rom_space;   end_ptr = nvram_size;   if ((ios_ptr + 0x30) >= end_ptr) {      vm_error(vm,"NVRAM file too small\n");      return(-1);   }   magic1 = nvram_read16(base_ptr,ios_ptr+0x06);   magic2 = nvram_read16(base_ptr,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 = nvram_read32(base_ptr,ios_ptr+0x10) + 1;   nvlen = nvram_read32(base_ptr,ios_ptr+0x18);   printf("START = 0x%8.8x, LEN = 0x%8.8x\n",start,nvlen);   printf("END   = 0x%8.8x\n",nvram_read32(base_ptr,ios_ptr+0x14));   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);   }   nvram_memcpy_from(base_ptr,cfg_ptr,*buffer,nvlen-1);   (*buffer)[nvlen-1] = 0;   return(nvlen-1);}/* Compute NVRAM checksum */static m_uint16_t c2600_nvram_cksum(u_char *base_ptr,u_int offset,size_t count){   m_uint32_t sum = 0;   while(count > 1) {      sum = sum + nvram_read16(base_ptr,offset);      offset += 2;      count -= sizeof(m_uint16_t);   }   if (count > 0)       sum = sum + ((nvram_read16(base_ptr,offset) & 0xFF) << 8);   while(sum>>16)      sum = (sum & 0xffff) + (sum >> 16);   return(~sum);}/* Directly push the IOS configuration to the NVRAM device */int c2600_nvram_push_config(vm_instance_t *vm,u_char *buffer,size_t len){   m_uint32_t cfg_offset,cklen,tmp,ios_ptr,cfg_ptr;   m_uint16_t cksum;   u_char *base_ptr;   int fd;   fd = vm_mmap_create_file(vm,"nvram",vm->nvram_size*4096,&base_ptr);   if (fd == -1)      return(-1);   cfg_offset = 0x2c;   ios_ptr = vm->nvram_rom_space;   cfg_ptr = ios_ptr + cfg_offset;   /* Write IOS tag, uncompressed config... */   nvram_write16(base_ptr,ios_ptr+0x06,0xF0A5);   nvram_write16(base_ptr,ios_ptr+0x08,0xABCD);   nvram_write16(base_ptr,ios_ptr+0x0a,0x0001);   nvram_write16(base_ptr,ios_ptr+0x0c,0x0000);   nvram_write16(base_ptr,ios_ptr+0x0e,0x0c04);   /* Store file contents to NVRAM */   nvram_memcpy_to(base_ptr,cfg_ptr,buffer,len);   /* Write config addresses + size */   tmp = cfg_offset - 0x08;   nvram_write32(base_ptr,ios_ptr+0x10,tmp);   nvram_write32(base_ptr,ios_ptr+0x14,tmp + len);   nvram_write32(base_ptr,ios_ptr+0x18,len);   /* Compute the checksum */   cklen = (vm->nvram_size*1024) - (vm->nvram_rom_space + 0x08);   cksum = c2600_nvram_cksum(base_ptr,ios_ptr+0x08,cklen);   nvram_write16(base_ptr,ios_ptr+0x0c,cksum);   vm_mmap_close_file(fd,base_ptr,vm->nvram_size*4096);   return(0);}/* Check for empty config */int c2600_nvram_check_empty_config(vm_instance_t *vm){   struct vdevice *dev;   m_uint64_t addr;   m_uint32_t len;   if (!(dev = dev_get_by_name(vm,"nvram")))      return(-1);   addr = dev->phys_addr + (vm->nvram_rom_space << 2);   len  = dev->phys_len - (vm->nvram_rom_space << 2);   while(len > 0) {      if (physmem_copy_u32_from_vm(vm,addr) != 0)         return(0);      addr += sizeof(m_uint32_t);      len  -= sizeof(m_uint32_t);   }   /* Empty NVRAM */   vm->conf_reg |= 0x0040;   printf("NVRAM is empty, setting config register to 0x%x\n",vm->conf_reg);   return(0);}/* Create a new router instance */static int c2600_create_instance(vm_instance_t *vm){   c2600_t *router;   if (!(router = malloc(sizeof(*router)))) {      fprintf(stderr,"C2600 '%s': Unable to create new instance!\n",vm->name);      return(-1);   }   memset(router,0,sizeof(*router));   router->vm = vm;   vm->hw_data = router;   c2600_init_defaults(router);   return(0);}/* Free resources used by a router instance */static int c2600_delete_instance(vm_instance_t *vm){   c2600_t *router = VM_C2600(vm);   int i;   /* 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<vm->nr_slots;i++)      vm_slot_remove_all_nio_bindings(vm,i);   /* Shutdown all Network Modules */   vm_slot_shutdown_all(vm);      /* 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);}/* Save configuration of a C2600 instance */void c2600_save_config(vm_instance_t *vm,FILE *fd){   c2600_t *router = VM_C2600(vm);   fprintf(fd,"c2600 set_chassis %s %s\n\n",vm->name,router->mainboard_type);}/* Get WIC device address for the specified onboard port */int c2600_get_onboard_wic_addr(u_int slot,m_uint64_t *phys_addr){   if (slot >= C2600_MAX_WIC_BAYS)      return(-1);   *phys_addr = C2600_WIC_ADDR + (slot * C2600_WIC_SIZE);   return(0);}/* Set EEPROM for the specified slot */int c2600_set_slot_eeprom(c2600_t *router,u_int slot,                          struct cisco_eeprom *eeprom){   switch(slot) {      case 1:         router->nm_eeprom_group.eeprom[0] = eeprom;         return(0);      default:         return(-1);   }}/* Get slot/port corresponding to specified network IRQ */static inline void c2600_net_irq_get_slot_port(u_int irq,u_int *slot,u_int *port){   irq -= C2600_NETIO_IRQ_BASE;   *port = irq & C2600_NETIO_IRQ_PORT_MASK;   *slot = irq >> C2600_NETIO_IRQ_PORT_BITS;}/* Get network IRQ for specified slot/port */u_int c2600_net_irq_for_slot_port(u_int slot,u_int port){   u_int irq;   irq = (slot << C2600_NETIO_IRQ_PORT_BITS) + port;   irq += C2600_NETIO_IRQ_BASE;   return(irq);}/* Find Cisco 2600 Mainboard info */static struct c2600_mb_id *c2600_get_mb_info(char *mainboard_type){      int i;   for(i=0;c2600_mainboard_id[i].name;i++)      if (!strcmp(c2600_mainboard_id[i].name,mainboard_type))         return(&c2600_mainboard_id[i]);   return NULL;}/* Show all available mainboards */void c2600_mainboard_show_drivers(void){   int i;   printf("Available C2600 chassis drivers:\n");   for(i=0;c2600_mainboard_id[i].name;i++)      printf("  * %s %s\n",             c2600_mainboard_id[i].name,             !c2600_mainboard_id[i].supported ? "(NOT WORKING)" : "");   printf("\n");}/* Show the list of available NM drivers */void c2600_nm_show_drivers(void){   int i;   printf("Available C2600 Network Module drivers:\n");   for(i=0;nm_drivers[i];i++) {      printf("  * %s %s\n",             nm_drivers[i]->dev_type,             !nm_drivers[i]->supported ? "(NOT WORKING)" : "");   }      printf("\n");}/* Set the base MAC address of the chassis */static int c2600_burn_mac_addr(c2600_t *router,n_eth_addr_t *addr){   int i;   for(i=0;i<3;i++) {      router->vm->chassis_cookie[i+1] = addr->eth_addr_byte[i*2] << 8;      router->vm->chassis_cookie[i+1] |= addr->eth_addr_byte[(i*2)+1];   }   return(0);}/* Set mainboard type */int c2600_mainboard_set_type(c2600_t *router,char *mainboard_type){   struct c2600_mb_id *mb_info;   if (router->vm->status == VM_STATUS_RUNNING) {      vm_error(router->vm,"unable to change mainboard type when online.\n");      return(-1);   }   if (!(mb_info = c2600_get_mb_info(mainboard_type))) {      vm_error(router->vm,"unknown mainboard '%s'\n",mainboard_type);      return(-1);   }   router->mainboard_type = mainboard_type;   router->xm_model = mb_info->xm_model;

⌨️ 快捷键说明

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