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

📄 cisco_card.c

📁 思科路由器仿真器,用来仿7200系列得,可以在电脑上模拟路由器
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Cisco router simulation platform. * Copyright (c) 2007 Christophe Fillot (cf@utc.fr) * * Generic Cisco card routines and definitions. */#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 "cisco_card.h"/* Get cisco card type description */char *cisco_card_get_type_desc(int dev_type){   switch(dev_type) {      case CISCO_CARD_TYPE_PA:         return("Port Adapter (PA)");      case CISCO_CARD_TYPE_NM:         return("Network Module (NM)");      case CISCO_CARD_TYPE_WIC:         return("WAN Interface Card (WIC)");      default:         return("Unknown");   }}/* Set EEPROM definition for the specified Cisco card */int cisco_card_set_eeprom(vm_instance_t *vm,struct cisco_card *card,                          const struct cisco_eeprom *eeprom){   if (!eeprom)      return(0);   if (cisco_eeprom_copy(&card->eeprom,eeprom) == -1) {      vm_error(vm,"cisco_card_set_eeprom: no memory (eeprom=%p).\n",eeprom);      return(-1);   }      return(0);}/* Unset EEPROM definition */int cisco_card_unset_eeprom(struct cisco_card *card){   cisco_eeprom_free(&card->eeprom);   return(0);}/* Check if a card has a valid EEPROM defined */int cisco_card_check_eeprom(struct cisco_card *card){   return(cisco_eeprom_valid(&card->eeprom));}/* Create a card structure */static inline struct cisco_card *cisco_card_create(u_int card_type){   struct cisco_card *card;   if ((card = malloc(sizeof(*card))) != NULL) {      memset(card,0,sizeof(*card));      card->card_type = card_type;   }      return card;}/* Find a NIO binding */static struct cisco_nio_binding *cisco_card_find_nio_binding(struct cisco_card *card,u_int port_id){      struct cisco_nio_binding *nb;   if (!card)      return NULL;   for(nb=card->nio_list;nb;nb=nb->next)      if (nb->port_id == port_id)         return nb;   return NULL;}/* Remove all NIO bindings */static void cisco_card_remove_all_nio_bindings(vm_instance_t *vm,struct cisco_card *card){   struct cisco_nio_binding *nb,*next;   for(nb=card->nio_list;nb;nb=next) {      next = nb->next;      /* tell the slot driver to stop using this NIO */      if (card->driver)         card->driver->card_unset_nio(vm,card,nb->port_id);      /* unreference NIO object */      netio_release(nb->nio->name);      free(nb);   }   card->nio_list = NULL;}/* Enable all NIO for the specified card */static inlinevoid cisco_card_enable_all_nio(vm_instance_t *vm,struct cisco_card *card){   struct cisco_nio_binding *nb;   if (card && card->driver && card->drv_info)            for(nb=card->nio_list;nb;nb=nb->next)         card->driver->card_set_nio(vm,card,nb->port_id,nb->nio);}/* Disable all NIO for the specified card */static inlinevoid cisco_card_disable_all_nio(vm_instance_t *vm,struct cisco_card *card){   struct cisco_nio_binding *nb;   if (card && card->driver && card->drv_info)      for(nb=card->nio_list;nb;nb=nb->next)         card->driver->card_unset_nio(vm,card,nb->port_id);}/* Initialize a card */static inlineint cisco_card_init(vm_instance_t *vm,struct cisco_card *card,u_int id){     size_t len;   /* Check that a device type is defined for this card */   if (!card || !card->dev_type || !card->driver)      return(-1);   /* Allocate device name */   len = strlen(card->dev_type) + 10;   if (!(card->dev_name = malloc(len))) {      vm_error(vm,"unable to allocate device name.\n");      return(-1);   }   snprintf(card->dev_name,len,"%s(%u)",card->dev_type,id);   /* Initialize card driver */   if (card->driver->card_init(vm,card) == -1) {      vm_error(vm,"unable to initialize card type '%s' (id %u)\n",               card->dev_type,id);      return(-1);   }   return(0);}/* Shutdown card */static int cisco_card_shutdown(vm_instance_t *vm,struct cisco_card *card){   /* Check that a device type is defined for this card */   if (!card || !card->dev_type || !card->driver)      return(-1);   /* Shutdown the NM driver */   if (card->drv_info && (card->driver->card_shutdown(vm,card) == -1)) {      vm_error(vm,"unable to shutdown card type '%s' (slot %u/%u)\n",               card->dev_type,card->slot_id,card->subslot_id);      return(-1);   }   free(card->dev_name);   card->dev_name = NULL;   card->drv_info = NULL;   return(0);}/* Show info for the specified card */static int cisco_card_show_info(vm_instance_t *vm,struct cisco_card *card){   /* Check that a device type is defined for this card */   if (!card || !card->driver || !card->driver->card_show_info)      return(-1);   card->driver->card_show_info(vm,card);   return(0);}/* Save config for the specified card */static int cisco_card_save_config(vm_instance_t *vm,struct cisco_card *card,                                  FILE *fd){   struct cisco_nio_binding *nb;   fprintf(fd,"vm add_slot_binding %s %u %u %s\n",           vm->name,card->slot_id,card->subslot_id,card->dev_type);   for(nb=card->nio_list;nb;nb=nb->next) {      fprintf(fd,"vm add_nio_binding %s %u %u %s\n",              vm->name,card->slot_id,nb->orig_port_id,nb->nio->name);   }   return(0);}/* Find a driver in a driver array */static struct cisco_card_driver *cisco_card_find_driver(struct cisco_card_driver **array,char *dev_type){   int i;   for(i=0;array[i]!=NULL;i++)      if (!strcmp(array[i]->dev_type,dev_type))         return array[i];   return NULL;}/* ======================================================================== *//* High level routines for managing VM slots.                               *//* ======================================================================== *//* Get slot info */struct cisco_card *vm_slot_get_card_ptr(vm_instance_t *vm,u_int slot_id){   if (slot_id >= vm->nr_slots)      return NULL;   return(vm->slots[slot_id]);}/* Get info for a slot/port (with sub-cards) */static int vm_slot_get_info(vm_instance_t *vm,u_int slot_id,u_int port_id,                            struct cisco_card ***rc,u_int *real_port_id){   struct cisco_card *card;   u_int wic_id,card_type;   if (slot_id >= VM_MAX_SLOTS) {      *rc = NULL;      return(-1);   }   *rc = &vm->slots[slot_id];   card = vm->slots[slot_id];   card_type = (card != NULL) ? card->card_type : CISCO_CARD_TYPE_UNDEF;   switch(card_type) {      /*        * Handle WICs which are sub-slots for Network Modules (NM).       * Numbering: wic #0 => port_id = 0x10       *            wic #1 => port_id = 0x20       */      case CISCO_CARD_TYPE_NM:         wic_id = port_id >> 4;         if (wic_id >= (CISCO_CARD_MAX_WIC+1)) {            vm_error(vm,"Invalid wic_id %u (slot %u)\n",wic_id,slot_id);            return(-1);         }         if (wic_id >= 0x01) {            /* wic card */            *rc = &card->sub_slots[wic_id - 1];            *real_port_id = port_id & 0x0F;         } else {            /* main card */            *real_port_id = port_id;         }         return(0);      /* No translation for Cisco 7200 Port Adapters and WICs */      case CISCO_CARD_TYPE_PA:      case CISCO_CARD_TYPE_WIC:         *real_port_id = port_id;         return(0);      /* Not initialized yet */      default:         *real_port_id = port_id;         return(0);   }}/* Translate a port ID (for sub-cards) */static u_int vm_slot_translate_port_id(vm_instance_t *vm,u_int slot_id,u_int port_id,                          struct cisco_card **rc){   struct cisco_card **tmp;   u_int real_port_id = 0;   vm_slot_get_info(vm,slot_id,port_id,&tmp,&real_port_id);   *rc = *tmp;   return(real_port_id);}/* Check if a slot has an active card */int vm_slot_active(vm_instance_t *vm,u_int slot_id,u_int port_id){   struct cisco_card **rc;   u_int real_port_id;   if (vm_slot_get_info(vm,slot_id,port_id,&rc,&real_port_id) == -1)      return(FALSE);   if ((*rc == NULL) || ((*rc)->dev_type == NULL))      return(FALSE);   return(TRUE);}/* Set a flag for a card */int vm_slot_set_flag(vm_instance_t *vm,u_int slot_id,u_int port_id,u_int flag){   struct cisco_card **rc;   u_int real_port_id;   if (vm_slot_get_info(vm,slot_id,port_id,&rc,&real_port_id) == -1)      return(FALSE);   if (*rc == NULL)      return(FALSE);   (*rc)->card_flags |= flag;   return(TRUE);}/* Add a slot binding */int vm_slot_add_binding(vm_instance_t *vm,char *dev_type,                        u_int slot_id,u_int port_id){        struct cisco_card_driver *driver,**drv_array;   struct cisco_card **rc,*card,*nc,*parent;   u_int real_port_id,card_type,card_id;   if (vm_slot_get_info(vm,slot_id,port_id,&rc,&real_port_id) == -1)      return(-1);   /* check that this bay is empty */   if (*rc != NULL) {      if ((*rc)->card_flags & CISCO_CARD_FLAG_OVERRIDE) {         vm_slot_remove_binding(vm,slot_id,port_id);      } else {         vm_error(vm,"a card already exists in slot %u/%u (%s)\n",                  slot_id,port_id,(*rc)->dev_type);         return(-1);      }   }   card = vm->slots[slot_id];   if (!card || (card == *rc)) {      /* Main slot */      drv_array = vm->slots_drivers;      card_type = vm->slots_type;      card_id   = slot_id;      parent    = NULL;   } else {      /* Subslot */      if (!card->driver->card_get_sub_info) {         vm_error(vm,"no sub-slot possible for slot %u/%u.\n",slot_id,port_id);         return(-1);      }      if (card->driver->card_get_sub_info(vm,card,port_id,                                          &drv_array,&card_type) == -1)      {         vm_error(vm,"no sub-slot info for slot %u/%u.\n",slot_id,port_id);         return(-1);      }      card_id = port_id;      parent  = card;   }   assert(drv_array != NULL);   /* Find the card driver */   if (!(driver = cisco_card_find_driver(drv_array,dev_type))) {      vm_error(vm,"unknown card type '%s' for slot %u/%u.\n",               dev_type,slot_id,port_id);      return(-1);   }   /* Allocate new card info */   if (!(nc = cisco_card_create(card_type)))      return(-1);   nc->slot_id    = slot_id;   nc->subslot_id = port_id;   nc->card_id    = card_id;   nc->dev_type   = driver->dev_type;   nc->driver     = driver;   nc->parent     = parent;   *rc = nc;   return(0);  }/* Remove a slot binding */int vm_slot_remove_binding(vm_instance_t *vm,u_int slot_id,u_int port_id){   struct cisco_card **rc,*sc;   u_int i,real_port_id;   if (vm_slot_get_info(vm,slot_id,port_id,&rc,&real_port_id) == -1)      return(-1);   if (*rc == NULL)      return(-1);   if ((*rc)->drv_info != NULL) {      vm_error(vm,"slot %u/%u is still active\n",slot_id,port_id);      return(-1);   }   for(i=0;i<CISCO_CARD_MAX_SUBSLOTS;i++) {      if ((sc = (*rc)->sub_slots[i]) != NULL) {         vm_error(vm,"sub-slot %u/%u is still active\n",                  slot_id,sc->subslot_id);         return(-1);      }   }   /* Remove all NIOs bindings */    vm_slot_remove_all_nio_bindings(vm,slot_id);   /* Free the card info structure */   free(*rc);   *rc = NULL;   return(0);}/* Add a network IO binding */int vm_slot_add_nio_binding(vm_instance_t *vm,u_int slot_id,u_int port_id,                            char *nio_name){   struct cisco_nio_binding *nb;   struct cisco_card *card,*rc;   u_int real_port_id;   netio_desc_t *nio;   if (!(card = vm_slot_get_card_ptr(vm,slot_id)))      return(-1);   /* Get the real card (in case this is a sub-slot) */   real_port_id = vm_slot_translate_port_id(vm,slot_id,port_id,&rc);   if (rc == NULL)      return(-1);   /* check that a NIO is not already bound to this port */   if (cisco_card_find_nio_binding(rc,real_port_id) != NULL) {      vm_error(vm,"a NIO already exists for interface %u/%u.\n",               slot_id,port_id);      return(-1);   }   /* acquire a reference on the NIO object */   if (!(nio = netio_acquire(nio_name))) {      vm_error(vm,"unable to find NIO '%s'.\n",nio_name);      return(-1);   }   /* create a new binding */   if (!(nb = malloc(sizeof(*nb)))) {      vm_error(vm,"unable to create NIO binding for interface %u/%u.\n",               slot_id,port_id);      netio_release(nio_name);      return(-1);   }   memset(nb,0,sizeof(*nb));   nb->nio          = nio;   nb->port_id      = real_port_id;   nb->orig_port_id = port_id;   nb->next = rc->nio_list;   if (nb->next) nb->next->prev = nb;   rc->nio_list = nb;   return(0);}/* Remove a NIO binding */int vm_slot_remove_nio_binding(vm_instance_t *vm,u_int slot_id,u_int port_id){   struct cisco_nio_binding *nb;   struct cisco_card *card,*rc;   u_int real_port_id;   if (!(card = vm_slot_get_card_ptr(vm,slot_id)))      return(-1);   /* Get the real card (in case this is a sub-slot) */

⌨️ 快捷键说明

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