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

📄 dev_c3745.c

📁 思科路由器仿真器,用来仿7200系列得,可以在电脑上模拟路由器
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Cisco 3745 simulation platform. * Copyright (c) 2006 Christophe Fillot (cf@utc.fr) * * Generic Cisco 3745 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 "pci_io.h"#include "dev_gt.h"#include "cisco_eeprom.h"#include "dev_rom.h"#include "dev_c3745.h"#include "dev_c3745_iofpga.h"#include "dev_vtty.h"#include "registry.h"/* ======================================================================== *//* EEPROM definitions                                                       *//* ======================================================================== *//* Cisco 3745 motherboard EEPROM */static m_uint16_t eeprom_c3745_motherboard_data[] = {   0x04FF, 0xC18B, 0x5858, 0x5858, 0x5858, 0x5858, 0x5858, 0x5809,   0x6940, 0x02F7, 0xC046, 0x0320, 0x003E, 0x3E03, 0x4241, 0x3085,   0x1C12, 0x4004, 0x80FF, 0xFFFF, 0xFFC4, 0x08FF, 0xFFFF, 0xFFFF,   0xFFFF, 0xFF81, 0x0000, 0x0000, 0x0400, 0x0300, 0xC508, 0xFFFF,   0xFFFF, 0xFFFF, 0xFFFF, 0x4102, 0x0002, 0x04C2, 0x8B58, 0x5858,   0x5858, 0x5858, 0x5858, 0x5858, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,   0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,   0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,};struct cisco_eeprom eeprom_c3745_motherboard = {   "C3745 Motherboard",    eeprom_c3745_motherboard_data,   sizeof(eeprom_c3745_motherboard_data)/2,};/* Cisco 3745 I/O board EEPROM */static m_uint16_t eeprom_c3745_ioboard_data[] = {   0x04FF, 0x4002, 0xF841, 0x0200, 0xC046, 0x0320, 0x0038, 0x7E01,   0x4242, 0x3080, 0x0000, 0x0000, 0x0203, 0xC18B, 0x5858, 0x5858,   0x5858, 0x5858, 0x5858, 0x5803, 0x0081, 0x0000, 0x0000, 0x0400,   0xC809, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFC2, 0x8B58, 0x5858,   0x5858, 0x5858, 0x5858, 0x5858, 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_c3745_ioboard = {   "C3745 I/O board",    eeprom_c3745_ioboard_data,   sizeof(eeprom_c3745_ioboard_data)/2,};/* Cisco 3745 midplane EEPROM */static m_uint16_t eeprom_c3745_midplane_data[] = {   0x04FF, 0x4003, 0x3E41, 0x0200, 0xC046, 0x0320, 0x0030, 0x0101,   0x4241, 0x3080, 0x0000, 0x0000, 0x0205, 0xC18B, 0x5858, 0x5858,   0x5858, 0x5858, 0x5858, 0x5803, 0x0081, 0x0000, 0x0000, 0x0400,   0xC809, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFC3, 0x0600, 0x0DED,   0xCD7D, 0x8043, 0x0050, 0xC28B, 0x5858, 0x5858, 0x5858, 0x5858,   0x5858, 0x58FF, 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_c3745_midplane = {   "C3745 Midplane",    eeprom_c3745_midplane_data,   sizeof(eeprom_c3745_midplane_data)/2,};/* ======================================================================== *//* Network Module Drivers                                                   *//* ======================================================================== */static struct cisco_card_driver *nm_drivers[] = {   &dev_c3745_nm_1fe_tx_driver,   &dev_c3745_nm_16esw_driver,   &dev_c3745_gt96100_fe_driver,   &dev_c3745_nm_4t_driver,   &dev_c3745_nm_nam_driver,   &dev_c3745_nm_cids_driver,   NULL,};/* ======================================================================== *//* Cisco 3745 router instances                                              *//* ======================================================================== *//* Initialize default parameters for a C3745 */static void c3745_init_defaults(c3745_t *router);/* Directly extract the configuration from the NVRAM device */static ssize_t c3745_nvram_extract_config(vm_instance_t *vm,u_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,"rom")))      dev_sync(nvram_dev);   fd = vm_mmap_open_file(vm,"rom",&base_ptr,&nvram_size);   if (fd == -1)      return(-1);   ios_ptr = base_ptr + C3745_NVRAM_OFFSET;   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);}static int c3745_nvram_push_config_part(vm_instance_t *vm,                                        u_char *buffer,size_t len,                                        u_char *ios_ptr){   m_uint32_t cfg_offset,cklen,tmp;   m_uint16_t cksum;   u_char *cfg_ptr;   cfg_offset = 0x2c;   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 = C3745_NVRAM_SIZE - 0x08;   cksum = nvram_cksum((m_uint16_t *)(ios_ptr+0x08),cklen);   *PTR_ADJUST(m_uint16_t *,ios_ptr,0x0c) = htons(cksum);   return(0);}/* Directly push the IOS configuration to the NVRAM device */static int c3745_nvram_push_config(vm_instance_t *vm,u_char *buffer,size_t len){   u_char *base_ptr,*ios_ptr;   int fd;      fd = vm_mmap_create_file(vm,"rom",vm->rom_size*1048576,&base_ptr);   if (fd == -1)      return(-1);   ios_ptr = base_ptr + C3745_NVRAM_OFFSET;   /* Normal config */   c3745_nvram_push_config_part(vm,buffer,len,ios_ptr);      /* Backup config */   c3745_nvram_push_config_part(vm,buffer,len,ios_ptr + C3745_NVRAM_SIZE);   vm_mmap_close_file(fd,base_ptr,vm->rom_size*1048576);   return(0);}/* Check for empty config */static int c3745_nvram_check_empty_config(vm_instance_t *vm){   struct vdevice *rom_dev;   m_uint64_t addr;   size_t len;   if (!(rom_dev = dev_get_by_name(vm,"rom")))      return(-1);   addr = rom_dev->phys_addr + C3745_NVRAM_OFFSET;   len  = C3745_NVRAM_SIZE;   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 c3745_create_instance(vm_instance_t *vm){   c3745_t *router;   if (!(router = malloc(sizeof(*router)))) {      fprintf(stderr,"C3745 '%s': Unable to create new instance!\n",vm->name);      return(-1);   }   memset(router,0,sizeof(*router));   router->vm = vm;   vm->hw_data = router;   c3745_init_defaults(router);   return(0);}/* Free resources used by a router instance */static int c3745_delete_instance(vm_instance_t *vm){   c3745_t *router = VM_C3745(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 */   for(i=0;i<3;i++)      cisco_eeprom_free(&router->sys_eeprom[i]);      /* Free all resources used by VM */   vm_free(vm);   /* Free the router structure */   free(router);   return(TRUE);}/* Get WIC device address for the specified onboard port */int c3745_get_onboard_wic_addr(u_int slot,m_uint64_t *phys_addr){   if (slot >= C3745_MAX_WIC_BAYS)      return(-1);   *phys_addr = C3745_WIC_ADDR + (slot * C3745_WIC_SIZE);   return(0);}/* Set EEPROM for the specified slot */int c3745_set_slot_eeprom(c3745_t *router,u_int slot,                          struct cisco_eeprom *eeprom){   if ((slot < 1) || (slot >= C3745_MAX_NM_BAYS))      return(-1);   router->nm_eeprom_group[slot-1].eeprom[0] = eeprom;   return(0);}/* Get slot/port corresponding to specified network IRQ */static inline void c3745_net_irq_get_slot_port(u_int irq,u_int *slot,u_int *port){   irq -= C3745_NETIO_IRQ_BASE;   *port = irq & C3745_NETIO_IRQ_PORT_MASK;   *slot = irq >> C3745_NETIO_IRQ_PORT_BITS;}/* Get network IRQ for specified slot/port */u_int c3745_net_irq_for_slot_port(u_int slot,u_int port){   u_int irq;   irq = (slot << C3745_NETIO_IRQ_PORT_BITS) + port;   irq += C3745_NETIO_IRQ_BASE;   return(irq);}/* Set the base MAC address of the chassis */static int c3745_burn_mac_addr(c3745_t *router,n_eth_addr_t *addr){   m_uint8_t eeprom_ver;   size_t offset;   /* Read EEPROM format version */   cisco_eeprom_get_byte(&router->sys_eeprom[2],0,&eeprom_ver);   switch(eeprom_ver) {      case 0:         cisco_eeprom_set_region(&router->sys_eeprom[2],2,                                 addr->eth_addr_byte,6);         break;      case 4:         if (!cisco_eeprom_v4_find_field(&router->sys_eeprom[2],                                         0xC3,&offset)) {            cisco_eeprom_set_region(&router->sys_eeprom[2],offset,                                    addr->eth_addr_byte,6);         }         break;      default:         vm_error(router->vm,"c3745_burn_mac_addr: unable to handle "                  "EEPROM version %u\n",eeprom_ver);         return(-1);   }   return(0);}/* Set chassis MAC address */int c3745_chassis_set_mac_addr(c3745_t *router,char *mac_addr){   if (parse_mac_addr(&router->mac_addr,mac_addr) == -1) {      vm_error(router->vm,"unable to parse MAC address '%s'.\n",mac_addr);      return(-1);   }   /* Set the chassis base MAC address */   c3745_burn_mac_addr(router,&router->mac_addr);   return(0);}/* Create the two main PCI busses for a GT64120 based system */static int c3745_init_gt96100(c3745_t *router){   vm_instance_t *vm = router->vm;   vm_obj_t *obj;   vm->pci_bus[0] = pci_bus_create("PCI bus #0",0);   vm->pci_bus[1] = pci_bus_create("PCI bus #1",0);   if (!vm->pci_bus[0] || !vm->pci_bus[1]) {      vm_error(router->vm,"unable to create PCI data.\n");      return(-1);   }      if (dev_gt96100_init(vm,"gt96100",C3745_GT96K_ADDR,0x200000,                        C3745_GT96K_IRQ,                        C3745_EXT_IRQ,                        c3745_net_irq_for_slot_port(0,0),                        255) == -1)      return(-1);   if (!(obj = vm_object_find(router->vm,"gt96100")))      return(-1);   router->gt_data = obj->data;   return(0);}/* Initialize a Cisco 3745 */static int c3745_init(c3745_t *router){      vm_instance_t *vm = router->vm;

⌨️ 快捷键说明

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