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

📄 vlan.c

📁 模拟vlan的环境,可以创建端口, 删除vlan 等操作,
💻 C
字号:

/* 
 * vlan.c
 * Original Author:  zhough@ruijie.com.cn 2007-8-30  
 * Vlan相关的操作函数的定义
 */

#include<stdio.h>
#include "vlan.h"

static struct vlan_t  *vlan_table[HASH_SIZE_VLAN];      /* vlan表*/

static int vlan_cnt;        /* 已建立的vlan数目 */



struct vlan_t * create_vlan(int vid, char *name);
struct vlan_t * vid_to_vlan(int vid);
static int  hash_vlan(int id);
 void insert_to_vlan_table( struct vlan_t *vlan,int vid);
 char * strdup(char *s);

void del_port_from_vlan(int vid, int pid);
void  destory_vlan(int vid);

 void delete_vlan_from_port_table(  int vid);
 
static struct port_t * port_table[HASH_SIZE_PORT];     /* port表*/
static int max_port_num;        /* 最大port数目 */
static int phy_port_cnt;           /* 已添加的port数目 */


/* 
 * 初始化vlan表
 */
void  init_vlan(void)
{
    int i;

    vlan_cnt = 0;
    for (i = 0; i < HASH_SIZE_VLAN; i++)
    {
        vlan_table[i] = NULL;
    }

    create_vlan(DEFAULT_VLAN, "Vlan0");/* 系统默认创建vlan1 */
}


/* 
 * @vid: vlan的id
 * @name:vlan的名字
 *
 * 根据vid和vlan的名字创建一个vlan, 如果创建成功则返回创建好的vlan, 否则返回空
 */
struct vlan_t * create_vlan(int vid, char *name)
{
    int index;
    struct vlan_t *vlan;
	int port_number_count=0;
    
    if (vid <=0 || vid > 4095)
    {   
        printf("invalid vid %d  \n", vid);
        return NULL;
    }
    if (vlan_cnt >= VLAN_NUM)
    {
        printf("can't create more vlan \n");
        return NULL;
    }
   
    vlan = vid_to_vlan(vid);
    if (vlan)
        return vlan; /* 如果已经存在就直接返回 */

    vlan = (struct vlan_t *)malloc(sizeof(struct vlan_t));
    if (!vlan)
    {
        printf("Cannot allocate memory \n");
        return NULL;
    }

	 for(port_number_count=0 ;port_number_count<PORT_NUM;port_number_count++)
	 	      vlan->same_vlan_port_table[port_number_count]=NULL;
   
    vlan->vid = vid;
    vlan->name = strdup(name);
    vlan->next=NULL;
   
	 insert_to_vlan_table(vlan, vid);
   
    vlan_cnt++;
    return vlan;
}



/* 
 * @vid: vlan的id
 *
 * 根据vid查找vlan,如果存在这个vlan, 返回一个vlan结构, 否则返回空
 */
struct vlan_t * vid_to_vlan(int vid)
{
    struct vlan_t *vlan_begin;
   
    int index;

    if (vid <= 0 || vid > 4095)
    {
        printf("invalid vid %d \n", vid);
        return NULL;
    }

    index = hash_vlan(vid);

    vlan_begin=vlan_table[index];
	if(vlan_begin==NULL)
		{ 
		   printf("can't find  vid %d \n", vid);
		   return NULL ;
		}
   
    else
    	{  
	   while(vlan_begin !=NULL)
		{
		     if(vlan_begin->vid==vid)
		   	 return vlan_begin;
			else
			vlan_begin=vlan_begin->next;
		  }
		   printf("can't find  vid %d \n", vid);
		   return NULL ;	   
    	}

}


/* 
 * @id: vlan的ID
 *
 * 根据id取哈希表vlan的索引
 * 返回哈希表的索引
 */
static int  hash_vlan(int id)
{

 /* 采用简单的取余法*/
    return id & HASH_MASK_VLAN;
}
   

/* 
 * @id: vlan的ID
 * @vlan: the pointer to the vlan node   
 * 根据id取哈希表vlan的索引
 * 返回哈希表的索引
 */
 void insert_to_vlan_table( struct vlan_t *vlan,int vid)
 {
    struct vlan_t *vlan_begin;
   
    int index;

	index = hash_vlan(vid);

    vlan_begin=vlan_table[index];
	if(vlan_begin==NULL)
	 { 
	   vlan_table[index]=vlan;
	   return  ;
	}
   
    else
    	{  
	   vlan_table[index]=vlan;
	   vlan->next=vlan_begin;
	  return  ;	   
    	}

 }


/* 
 * @max_port_number: 最大port数目,由系统检测出并传递过来
 *
 * 初始化port表
 */
void init_port()
{
    int i;

    max_port_num=PORT_NUM;
    phy_port_cnt = 0;

    for (i = 0; i < HASH_SIZE_PORT; i++)
    {
        port_table[i] = NULL;
    }
	
}

/* 
 * @s: 字符串指针
 *
 * 将字符串s的内容拷贝到一个新的地方, 返回新的字符串地址
 */
 char * strdup(char *s)
{
    char *p;
    p = (char *) malloc(strlen(s)+1); /* +1 for '\0' */
    if (p != NULL)
        strcpy(p, s);
    
    return p;
}


/* 
 * @pid: port的id
 *
 * 根据pid查找port,如果存在这个port,返回一个port结构,否则返回空
 */
struct port_t *  pid_to_port(int pid)
{
    struct port_t *port_begin;
   
    int index;

    if (pid < 0 || (pid >= 512 && pid < 2048) || pid >= 2175)
    {
        printf("invalid pid %d \n", pid);
        return NULL;
    }

    index = hash_port(pid);
   
    port_begin=port_table[index];
	if(port_begin==NULL)
	{ 
          printf("can't find  pid  %d  \n", pid);
	  return NULL ;
	}
   
    else
    	{  
           while(port_begin !=NULL)
	     {
	       if(port_begin->pid==pid)
		   return port_begin;
		else
		  port_begin=port_begin->next;
	    }
		printf("can't find  pid  %d \n", pid);
		return NULL ;	   
    	}
    return NULL;
}



/* 
 * @pid: port的id
 * @speed: port的速度
 * @duplex: 是否支持双工
 *
 * 添加一个port到port表中,如果添加成功则返回创建好的port, 否则返回空
 */
struct port_t * add_port(int pid, int speed, int duplex)
{
    int index;
    struct port_t *port;
	 struct port_t *port_begin;
    int i;
 
    if (pid < 0 || (pid >= 512 && pid < 2048) || pid >= 2175)
    {
        printf("invalid pid %d \n", pid);
        return NULL;
    }
	//printf("phy_port_cnt=%d,max_port_num=%d  \n",phy_port_cnt,max_port_num);
    if (phy_port_cnt >= max_port_num)
    {
        printf("can't add more port\n");
        return NULL;
    }

    port = pid_to_port(pid);
	
    if (port)
    	{
    	 printf("this port is exist already \n");
        return port;    /* 如果已存在直接返回 */

    	}	

    port = (struct port_t *)malloc(sizeof(struct port_t));
    if (!port)
    {
        printf("Cannot allocate memory  \n");
        return NULL;
    }
     for(i=0;i<VLAN_NUM;i++)
	 	port->same_port_vlan_table[i]=NULL;
	 
    
    port->pid = pid;
    port->speed = speed;
    port->duplex = duplex;
    port->next=NULL;
	
    /* 添加到port表中 */
    index = hash_port(pid);
    port_begin=port_table[index];

	printf("index=%d \n",index );
	if(port_begin==NULL)
		{ 
		   port_table[index]=port;
		      printf("port->pid=%d \n",port->pid);
		  
		}
   
    else
    	{  
		   port_table[index]=port;
		   port->next=port_begin;
		   printf("port->pid=%d \n",port->pid);
		     
    	}
    phy_port_cnt++;
   printf("port->pid=%d \n",port->pid);
    return port;
}


/* 
 * @id: port的ID
 *
 * 根据id取哈希表port的索引,返回哈希表的索引
 */
static int hash_port(int id)
{
/* 采用简单的取余法*/
    return id & HASH_MASK_PORT;
}


/* 
 * @vid: vlan的id
 * @pid: port的id
 *
 * 将pid的port加入到vid的vlan, 如果加入成功就返回1,否则返回0
 */
int add_port_to_vlan(int vid, int pid)
{
    
    struct vlan_t *vlan;
    struct port_t *port;
    int index;
  
    if (pid < 0 || (pid >= 512 && pid < 2048) || pid >= 2175 
        || vid <= 0 || vid > 4095)
    {
        printf("invalid vid %d or pid %d \n", vid, pid);
        return 0;
    }

    if (is_contain(vid, pid))
        return 1;
   
    if ((vlan = vid_to_vlan(vid)) == NULL)
        if ((vlan = create_vlan(vid, "tmpvlan")) == NULL)
        {
            printf("can't create a new vlan %d\n", vid);
            return 0;
        }
    if ((port = pid_to_port(pid)) == NULL)
    {
        printf("port %d doesn't exists \n", pid);
        return 0;
    }

	 vlan->same_vlan_port_table[pid]=port;
	 return 1 ;
    
    
}


/* 
 * @vid: vlan的id
 * @pid: port的id
 *
 * 判断pid的port是否属于一个vid的vlan, 如果属于就返回1, 否则返回0
 */
int is_contain(int vid, int pid)
{
     
    struct vlan_t *vlan_node;
    int index;

    if (pid < 0 || (pid >= 512 && pid < 2048) || pid >= 2175 
        || vid <= 0 || vid > 4095)
    {
        printf("invalid vid %d or pid %d \n", vid, pid);
        return 0;
    }
   
   vlan_node=vid_to_vlan(vid);
   if(vlan_node==NULL)
   	{
     	printf(" the vlan does not exist \n");
		return 0 ;
		
   	}
   if( vlan_node->same_vlan_port_table[pid]==NULL)
   	    return 0;
   else
   	      return 1;

}



void print_vlan(int vid )
{
  int vlan_row;
  int port_num;

 struct vlan_t  *  print ;

  print= vid_to_vlan(vid);
  if(print==NULL)
   	{
	   	 printf("no port inclueded \n");
		 return;
   	} 	
    
for(port_num=0;port_num<PORT_NUM;port_num++)
	{
	 printf("vlan=%d has the followed ports \n",vid);
	 printf("---------------------------------------\n");
	 if(print->same_vlan_port_table[port_num]!=NULL)
	 	{
	 	   printf("vid=%d, port=%d \n",print->vid ,port_num);
	 	} 
	 printf("---------------------------------------\n");
	}
	  print=print->next;
}




/* 
 * @vid: vlan的id
 * @pid: port的id
 *
 * 将pid的port从vid的vlan中删除
 */
void del_port_from_vlan(int vid, int pid)
{
    struct vlan_t *vlan_node;
    struct port_t * port_node;
    int index_vlan;
	int index_port;

    if (pid < 0 || (pid >= 512 && pid < 2048) || pid >= 2175 
        || vid <= 0 || vid > 4095)
    {
        printf("invalid vid %d or pid %d\n", vid, pid);
        return;
    }
       
         vlan_node= vid_to_vlan(vid);
         port_node= pid_to_port( pid);
		 if((vlan_node!=NULL) &(port_node!=NULL) )
		 	{
				 vlan_node->same_vlan_port_table[pid]=NULL;
				 port_node->same_port_vlan_table[vid]=NULL;
				  return ;
		 	}
		 else
		 	{
		 	  printf("delete failure \n");
			  return ;
		 	}
}



/* 
 * @vid: vlan的id
 *
 * 根据vid删除一个vlan
 */
void  destory_vlan(int vid)
{
    int index;
    int pid;
    struct vlan_t *vlan;
    struct vlan_t *vlan_begin;

    if (vid <= 1 || vid > 4095)
    {/* shouldn't destroy vlan1 */
        printf("invalid vid %d\n", vid);
        return;
    }

     vlan = vid_to_vlan(vid);
	 delete_vlan_from_port_table(vid);
     if(vlan)
     	{
	      index = hash_vlan(vid);
	      vlan_begin=vlan_table[index];
		   if(vlan_begin==vlan)
		   	 vlan_table[index]=NULL;
		   else
			{
				while(vlan_begin->next !=vlan)
			   	vlan=vlan->next;
				vlan_begin->next=vlan->next;
		        
		    	}
		    free(vlan);
			vlan = NULL;
	        vlan_cnt--;
     	}
    }




/* 
 * @vid: vlan的id
 *
 * 根据vid删除一个vlan
 */
 void delete_vlan_from_port_table(  int vid)
{
      
    int index;
	int index_vlan_num;
	struct port_t * port ;
	  for (index=0 ; index<HASH_SIZE_PORT;index++)
	  	{
	  	       port =port_table[index];
			   while(port!=NULL)
			   	{
					port->same_port_vlan_table[vid]=NULL;
					port=port->next;
			   	}
	  	}
}



⌨️ 快捷键说明

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