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

📄 atm.c

📁 思科路由器仿真器,用来仿7200系列得,可以在电脑上模拟路由器-Cisco router simulator, used to fake a 7200 series can be simulated
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Cisco 7200 (Predator) simulation platform. * Copyright (c) 2005,2006 Christophe Fillot (cf@utc.fr) * * ATM utility functions and Virtual ATM switch. * * HEC and AAL5 CRC computation functions are from Charles Michael Heard * and can be found at (no licence specified, this is to check!): * *    http://cell-relay.indiana.edu/cell-relay/publications/software/CRC/ */#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <pthread.h>#include <errno.h>#include <sys/select.h>#include <sys/time.h>#include <sys/types.h>#include "utils.h"#include "registry.h"#include "atm.h"#include "net_io.h"/********************************************************************/#define HEC_GENERATOR   0x107               /* x^8 + x^2 +  x  + 1  */#define COSET_LEADER    0x055               /* x^6 + x^4 + x^2 + 1  */m_uint8_t hec_syndrome_table[256];/* Generate a table of CRC-8 syndromes for all possible input bytes */static void gen_syndrome_table(void){   int i,j,syndrome;   for(i=0;i<256;i++) {      syndrome = i;            for(j=0;j<8;j++) {         if (syndrome & 0x80)            syndrome = (syndrome << 1) ^ HEC_GENERATOR;         else            syndrome = (syndrome << 1);      }      hec_syndrome_table[i] = (unsigned char)syndrome;   }}/* Compute HEC field for ATM header */m_uint8_t atm_compute_hec(m_uint8_t *cell_header){   register m_uint8_t hec_accum = 0;   register int i;   /*     * calculate CRC-8 remainder over first four bytes of cell header.    * exclusive-or with coset leader & insert into fifth header byte.    */   for(i=0;i<4;i++)      hec_accum = hec_syndrome_table[hec_accum ^ cell_header[i]];      return(hec_accum ^ COSET_LEADER);}/* Insert HEC field into an ATM header */void atm_insert_hec(m_uint8_t *cell_header){   cell_header[4] = atm_compute_hec(cell_header);}/* Initialize ATM code (for HEC checksums) */void atm_init(void){   gen_syndrome_table();}/* VPC hash function */static inline u_int atmsw_vpc_hash(u_int vpi){   return((vpi ^ (vpi >> 8)) & (ATMSW_VP_HASH_SIZE-1));}/* VCC hash function */static inline u_int atmsw_vcc_hash(u_int vpi,u_int vci){   return((vpi ^ vci) & (ATMSW_VC_HASH_SIZE-1));}/* VP lookup */atmsw_vp_conn_t *atmsw_vp_lookup(atmsw_table_t *t,netio_desc_t *input,                                 u_int vpi){   atmsw_vp_conn_t *swc;      for(swc=t->vp_table[atmsw_vpc_hash(vpi)];swc;swc=swc->next)      if ((swc->input == input) && (swc->vpi_in == vpi))         return swc;   return NULL;}/* VC lookup */atmsw_vc_conn_t *atmsw_vc_lookup(atmsw_table_t *t,netio_desc_t *input,                                 u_int vpi,u_int vci){   atmsw_vc_conn_t *swc;   for(swc=t->vc_table[atmsw_vcc_hash(vpi,vci)];swc;swc=swc->next)      if ((swc->input == input) && (swc->vpi_in == vpi) &&           (swc->vci_in == vci))         return swc;   return NULL;}/* VP switching */void atmsw_vp_switch(atmsw_vp_conn_t *vpc,m_uint8_t *cell){   m_uint32_t atm_hdr;   /* rewrite the atm header with new vpi */   atm_hdr =  ntohl(*(m_uint32_t *)cell);   atm_hdr =  atm_hdr & ~ATM_HDR_VPI_MASK;   atm_hdr |= vpc->vpi_out << ATM_HDR_VPI_SHIFT;   *(m_uint32_t *)cell = htonl(atm_hdr);   /* recompute HEC field */   atm_insert_hec(cell);   /* update the statistics counter */   vpc->cell_cnt++;}/* VC switching */void atmsw_vc_switch(atmsw_vc_conn_t *vcc,m_uint8_t *cell){   m_uint32_t atm_hdr;   /* rewrite the atm header with new vpi/vci */   atm_hdr = ntohl(*(m_uint32_t *)cell);   atm_hdr =  atm_hdr & ~(ATM_HDR_VPI_MASK|ATM_HDR_VCI_MASK);   atm_hdr |= vcc->vpi_out << ATM_HDR_VPI_SHIFT;   atm_hdr |= vcc->vci_out << ATM_HDR_VCI_SHIFT;   *(m_uint32_t *)cell = htonl(atm_hdr);   /* recompute HEC field */   atm_insert_hec(cell);   /* update the statistics counter */   vcc->cell_cnt++;}/* Handle an ATM cell */ssize_t atmsw_handle_cell(atmsw_table_t *t,netio_desc_t *input,                          m_uint8_t *cell){   m_uint32_t atm_hdr,vpi,vci;   netio_desc_t *output = NULL;   atmsw_vp_conn_t *vpc;   atmsw_vc_conn_t *vcc;   ssize_t len;   /* Extract VPI/VCI information */   atm_hdr = ntohl(*(m_uint32_t *)cell);   vpi = (atm_hdr & ATM_HDR_VPI_MASK) >> ATM_HDR_VPI_SHIFT;   vci = (atm_hdr & ATM_HDR_VCI_MASK) >> ATM_HDR_VCI_SHIFT;   /* VP switching */   if ((vpc = atmsw_vp_lookup(t,input,vpi)) != NULL) {      atmsw_vp_switch(vpc,cell);      output = vpc->output;   } else {        /* VC switching */      if ((vcc = atmsw_vc_lookup(t,input,vpi,vci)) != NULL) {         atmsw_vc_switch(vcc,cell);         output = vcc->output;      }   }   len = netio_send(output,cell,ATM_CELL_SIZE);      if (len != ATM_CELL_SIZE) {      t->cell_drop++;      return(-1);   }   return(0);}/* Receive an ATM cell */static int atmsw_recv_cell(netio_desc_t *nio,u_char *atm_cell,ssize_t cell_len,                           atmsw_table_t *t){   int res;   if (cell_len != ATM_CELL_SIZE)      return(-1);   ATMSW_LOCK(t);   res = atmsw_handle_cell(t,nio,atm_cell);   ATMSW_UNLOCK(t);   return(res);}/* Acquire a reference to an ATM switch (increment reference count) */atmsw_table_t *atmsw_acquire(char *name){   return(registry_find(name,OBJ_TYPE_ATMSW));}/* Release an ATM switch (decrement reference count) */int atmsw_release(char *name){   return(registry_unref(name,OBJ_TYPE_ATMSW));}/* Create a virtual switch table */atmsw_table_t *atmsw_create_table(char *name){   atmsw_table_t *t;   /* Allocate a new switch structure */   if (!(t = malloc(sizeof(*t))))      return NULL;   memset(t,0,sizeof(*t));   pthread_mutex_init(&t->lock,NULL);   mp_create_fixed_pool(&t->mp,"ATM Switch");   if (!(t->name = mp_strdup(&t->mp,name)))      goto err_name;   /* Record this object in registry */   if (registry_add(t->name,OBJ_TYPE_ATMSW,t) == -1) {      fprintf(stderr,"atmsw_create_table: unable to create switch '%s'\n",              name);      goto err_reg;   }   return t; err_reg: err_name:   mp_free_pool(&t->mp);   free(t);   return NULL;}/* Free resources used by a VPC */static void atmsw_release_vpc(atmsw_vp_conn_t *swc){   if (swc) {      /* release input NIO */      if (swc->input) {         netio_rxl_remove(swc->input);         netio_release(swc->input->name);      }      /* release output NIO */      if (swc->output)          netio_release(swc->output->name);   }}/* Free resources used by a VCC */static void atmsw_release_vcc(atmsw_vc_conn_t *swc){   if (swc) {      /* release input NIO */      if (swc->input) {         netio_rxl_remove(swc->input);         netio_release(swc->input->name);      }      /* release output NIO */      if (swc->output)          netio_release(swc->output->name);   }}/* Create a VP switch connection */int atmsw_create_vpc(atmsw_table_t *t,char *nio_input,u_int vpi_in,                     char *nio_output,u_int vpi_out){   atmsw_vp_conn_t *swc;   u_int hbucket;   ATMSW_LOCK(t);   /* Allocate a new switch connection */   if (!(swc = mp_alloc(&t->mp,sizeof(*swc)))) {      ATMSW_UNLOCK(t);      return(-1);   }   swc->input   = netio_acquire(nio_input);   swc->output  = netio_acquire(nio_output);   swc->vpi_in  = vpi_in;   swc->vpi_out = vpi_out;   /* Check these NIOs are valid and the input VPI does not exists */   if (!swc->input || !swc->output || atmsw_vp_lookup(t,swc->input,vpi_in))      goto error;   /* Add as a RX listener */   if (netio_rxl_add(swc->input,(netio_rx_handler_t)atmsw_recv_cell,                     t,NULL) == -1)      goto error;   hbucket = atmsw_vpc_hash(vpi_in);   swc->next = t->vp_table[hbucket];   t->vp_table[hbucket] = swc;   ATMSW_UNLOCK(t);   return(0); error:   ATMSW_UNLOCK(t);   atmsw_release_vpc(swc);   mp_free(swc);   return(-1);}/* Delete a VP switch connection */int atmsw_delete_vpc(atmsw_table_t *t,char *nio_input,u_int vpi_in,                     char *nio_output,u_int vpi_out){      netio_desc_t *input,*output;   atmsw_vp_conn_t **swc,*p;   u_int hbucket;   ATMSW_LOCK(t);   input = registry_exists(nio_input,OBJ_TYPE_NIO);   output = registry_exists(nio_output,OBJ_TYPE_NIO);   if (!input || !output) {      ATMSW_UNLOCK(t);      return(-1);   }   hbucket = atmsw_vpc_hash(vpi_in);   for(swc=&t->vp_table[hbucket];*swc;swc=&(*swc)->next)    {      p = *swc;

⌨️ 快捷键说明

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