?? 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 + -