?? mobileip.c
字號:
#include <sys/types.h>#include <sys/select.h>#include <sys/socket.h>#include <netinet/in.h>#include <sys/file.h>#include <unistd.h>#include <sys/ioctl.h>#include <net/if.h>#include <string.h>#include <stdio.h>#include <sys/param.h>#define SERV_PORT 5678//the port opened for server#define DEL_PORT 5555//the port the send the delSTAMsg#define MAXLEN 1024//the max length for read or write data once////////////////////////////////////////////////////////////////#define STYLE_RegMsg 0x04 #define MSG_WRONG -1#define MSG_REG 0///////////////////////////////////////////////////////////////////typedef struct tunnel{ //the struct of tunnel unsigned long sta_addr; unsigned long opposite_addr; struct tunnel *next;}TUNNEL, *TunnelList;typedef struct tunnel_counter{ //the struct to compute the tunnel number int counter; unsigned long opposite_addr; struct tunnel_counter *next;}COUNTER, *CounterList;#define TUNNEL_SIZE sizeof(TUNNEL)#define COUNTER_SIZE sizeof(COUNTER)//////////////////////////////////////////////////////////////////////////////////struct RegMsg{ //the register message struct form proxy int code; unsigned long sta_addr; unsigned long regAgent_addr;};struct delSTAMsg{ //the message struct to send to old tunnel's opposite sopt int code; unsigned long sta_addr;};/////////////////////////////////////////////////////////////////////////////////////////the global variableTunnelList Tlist; CounterList Clist;///////////////////////////////////////////////////////////////////////////////////////////int check_msg(char *buf); //to check if the message is register messagevoid create_tunnellist(struct tunnel *L); //to create the tunnel listvoid create_counterlist(CounterList L); //to create the counter listvoid delTlistNode(TunnelList pList,unsigned long sta,unsigned long tunnel_opp);void delClistNode(CounterList pList,unsigned long tunnel_opp);void addTlistNode(TunnelList pList,unsigned long sta,unsigned long tunnel_opp);void addClistNode(CounterList pList,unsigned long tunnel_opp);//void updateTlistNode(TunnelList &pList,unsigned long sta,unsigned long tunnel_opp);//void updateClistNode(CounterList &pList,unsigned long tunnel_opp);int delOldTunnel(unsigned long tunnel_opp); //to delete the old tunnel of staint createNewTunnel(unsigned long tunnel_opp); //to create new tunnel of staint searchStaTunnel(TunnelList pList,unsigned long sta,unsigned long tunnel_opp);//to search the tunnel relate to this sta unsigned long searchSta(TunnelList pList,unsigned long sta); //to search the old tunnel of specific staint searchCounter(CounterList pList,unsigned long tunnel_opp); //to search the counter list which opposite spot is thisvoid addCounter(CounterList pList,unsigned long tunnel_opp); //add 1 to the counter of specific tunnelint delCounter(CounterList pList,unsigned long tunnel_opp); //delete 1 to the counter of specific tunnelint sendDelStaMsg(unsigned long sta,unsigned long tunnel_opp); //send the delete message to the opposite spot of this tunnelint isLocAddr(unsigned long tunnel_opp); //to check if the opposite of this tunnel is localhost///////////////////////////////////////////////////////////////////////int isLocAddr(unsigned long tunnel_opp){ int sockfd; struct ifreq ifr; struct sockaddr_in sin; if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { printf("socket error\n"); exit(1); } //get the IP address in address structure memset(&sin,0,sizeof(sin)); memset(&ifr, 0, sizeof(ifr)); strncpy(ifr.ifr_name, "eth0", sizeof(ifr.ifr_name)-1); if (ioctl(sockfd, SIOCGIFADDR, &ifr) < 0) { printf("ioctl SIOCGIFADDR error\n"); exit(1); } //check IP address from address structure to string format memcpy(&sin,(struct sockaddr_in*)&ifr.ifr_addr,sizeof(ifr.ifr_addr)); if(sin.sin_addr.s_addr==tunnel_opp) return 0; else return -1;}//-------------------------------------------------------------------------------int sendDelStaMsg(unsigned long sta,unsigned long tunnel_opp){ int sock; int len; struct sockaddr_in agent_addr; struct delSTAMsg delmsg; char buf[MAXLEN]; memset(&delmsg,0,sizeof(delmsg)); delmsg.code=0x05; delmsg.sta_addr=sta; memset(buf,0,MAXLEN); memcpy(buf,&delmsg,sizeof(delmsg)); bzero(&agent_addr,sizeof(agent_addr)); agent_addr.sin_family=AF_INET; agent_addr.sin_port=htons(DEL_PORT); agent_addr.sin_addr.s_addr=tunnel_opp; sock=socket(AF_INET,SOCK_DGRAM,0); if(sock<0) { printf("socket create error\n"); exit(1); } else sendto(sock,buf,MAXLEN,0,(struct sockaddr*)&agent_addr,sizeof(agent_addr));}//----------------------------------------------------------------------------int delCounter(CounterList pList,unsigned long tunnel_opp){ CounterList p; CounterList current; p=pList; current=pList->next; while(current!=NULL) { if(current->opposite_addr==tunnel_opp) { current->counter-=1; if(current->counter==0) return 0; else return (current->counter); } else { p=current; current=current->next; } } if(current==NULL) printf("the tunnel can't be finded to minus 1 to the counter\n");}//--------------------------------------------------------------------------void addCounter(CounterList pList,unsigned long tunnel_opp){ CounterList p,current; p=pList; current=pList->next; while(current!=NULL) { if(current->opposite_addr==tunnel_opp) current->counter+=1; else { p=current; current=current->next; } } if(current==NULL) printf("the tunnel can't be finded to add counter\n");}//--------------------------------------------------------------------------------------int searchCounter(CounterList pList,unsigned long tunnel_opp){ CounterList p,current; p=pList; current=pList->next; while(current!=NULL) { if(current->opposite_addr==tunnel_opp) return 0; else { p=current; current=current->next; } } if(current==NULL) return -1;}//---------------------------------------------------------------------------unsigned long searchSta(TunnelList pList,unsigned long sta){ TunnelList p,current; p=pList; current=pList->next; while(current!=NULL) { if(current->sta_addr==sta) return (current->opposite_addr); else { p=current; current=current->next; } } if(current==NULL) return 0;}//------------------------------------------------------------------------------int searchStaTunnel(TunnelList pList,unsigned long sta,unsigned long tunnel_opp){ TunnelList p,current; p=pList; current=pList->next; while(current!=NULL) { if((current->sta_addr==sta)&&(current->opposite_addr==tunnel_opp)) return 0; else { p=current; current=current->next; } } if(current==NULL) return -1;}//---------------------------------------------------------------------------int createNewTunnel(unsigned long tunnel_opp){ unsigned long tunnel_head; //how to get the value? unsigned long tunnel_end; //how to get the value? struct in_addr inaddr1,inaddr2; char *head_ip, *end_ip; char netmask[30]; //how to get it? char buf[1024]; memset(buf,0,1024); memset(&inaddr1,0,sizeof(inaddr1)); memset(&inaddr2,0,sizeof(inaddr2)); inaddr1.s_addr=tunnel_head; inaddr2.s_addr=tunnel_end; head_ip=(char*)inet_ntoa(inaddr1); end_ip=(char*)inet_ntoa(inaddr2); system("insmod ipip.o"); sprintf(buf,"ifconfig tunl0 %s pointopoint %s",head_ip,end_ip); system(buf); memset(buf,0,1024); sprintf(buf,"ifconfig tunl0 netmask %s",netmask); system(buf); memset(buf,0,1024); sprintf("route add head_ip %s",head_ip); system(buf); }//------------------------------------------------------------------------------int delOldTunnel(unsigned long tunnel_opp){ system("ifconfig tunl0 down");}//----------------------------------------------------------------------------void addClistNode(CounterList pList,unsigned long tunnel_opp){ CounterList p,current; p=pList; current=(CounterList)malloc(COUNTER_SIZE); current->next=NULL; current->counter=1; current->opposite_addr=tunnel_opp; while(p->next!=NULL) p=p->next; p->next=current;}//----------------------------------------------------------------------------void addTlistNode(TunnelList pList,unsigned long sta,unsigned long tunnel_opp){ TunnelList p,current; p=pList; current=(TunnelList)malloc(TUNNEL_SIZE); current->next=NULL; current->sta_addr=sta; current->opposite_addr=tunnel_opp; while(p->next!=NULL) p=p->next; p->next=current;}//--------------------------------------------------------------------------void delClistNode(CounterList pList,unsigned long tunnel_opp){ CounterList p,current; p=pList; current=pList->next; while(current!=NULL) { if(current->opposite_addr==tunnel_opp) { p->next=current->next; free(current); } else { p=current; current=current->next; } } if(current==NULL) printf("delete the counter node error!\n");}//---------------------------------------------------------------------------void delTlistNode(TunnelList pList,unsigned long sta,unsigned long tunnel_opp){ TunnelList p,current; p=pList; current=pList->next; while(current!=NULL) { if((current->sta_addr==sta)&&(current->opposite_addr==tunnel_opp)) { p->next=current->next; free(current); } else { p=current; current=current->next; } } if(current==NULL) printf("delete tunnel node error!\n");}//----------------------------------------------------------------------void create_counterlist(CounterList L){ L=(CounterList)malloc(COUNTER_SIZE); L->next=NULL;}//-----------------------------------------------------------------------void create_tunnellist(TunnelList L){ L=(TunnelList)malloc(TUNNEL_SIZE); L->next=NULL;}//--------------------------------------------------------------------------int check_msg(char *buf){ if(buf[0]==STYLE_RegMsg) return 0; else return -1; }/////////////////////////////////////////////////////////////////////TunnelList tunnel;CounterList counter;int main(int argc,char ** argv){ int maxfd; int listen_fd; int sock_test; int msg_style; fd_set readset,writeset; int recv_len,recv_n; char recvs[MAXLEN]; char sends[MAXLEN]; struct sockaddr_in serv_addr,recv_addr; int nonBlock; //the variable to set socket non-blocked struct RegMsg *p_regMsg; struct tunnel *tunnel_head,*tunnel_now,*tunnel_last; struct tunnel_counter * counter_head,*counter_now,*counter_last; unsigned long opposite_tunnel; ///////////////////////////////////////////initialize the variables msg_style=-1; recv_len=0; recv_n=0; nonBlock=1; memset(recvs,0, MAXLEN); memset(sends,0,MAXLEN); ///////////////////////////////////////////////////////////////// create_tunnellist(tunnel); create_counterlist(counter);////////////////////////////////////////////////////////////////////////// listen_fd=socket(AF_INET,SOCK_DGRAM,0); if(listen_fd<0) { printf("socket() failed with error!\n"); exit(1); } serv_addr.sin_family=AF_INET; serv_addr.sin_addr.s_addr=htonl(INADDR_ANY); serv_addr.sin_port=htons(SERV_PORT); bzero(&(serv_addr.sin_zero),8); sock_test=bind(listen_fd,(struct sockaddr*)&serv_addr,sizeof(struct sockaddr)); if(sock_test<0) { printf("bind() failed with error!\n"); exit(1); } //set the listen socket listen_fd as nonblock socket ioctl(listen_fd,FIONBIO,&nonBlock); //now set the parameter of select() if(maxfd<listen_fd) maxfd=listen_fd; while(1) { FD_ZERO(&readset); FD_ZERO(&writeset); FD_SET(listen_fd,&readset); select(maxfd+1,&readset,NULL,NULL,NULL); if(FD_ISSET(listen_fd,&readset)) { memset(recvs,0,MAXLEN); recv_len=sizeof(recv_addr); bzero(&recv_addr,sizeof(recv_addr)); recv_n=recvfrom(listen_fd,recvs,MAXLEN,0,(struct sockaddr*)&recv_addr,&recv_len); if(recv_n<0) { printf("recvfrom error!\n"); exit(1); } else { msg_style=check_msg(recvs); if(MSG_REG==msg_style) { p_regMsg=(struct RegMsg *)recvs; if(searchStaTunnel(tunnel,p_regMsg->sta_addr,p_regMsg->regAgent_addr)==-1)//the tunnel to this sta don't exist { opposite_tunnel=searchSta(tunnel,p_regMsg->sta_addr); if(opposite_tunnel>0) //find the old tunnel of this sta { if(delCounter(counter,p_regMsg->regAgent_addr)==0) delOldTunnel(p_regMsg->regAgent_addr); sendDelStaMsg(p_regMsg->sta_addr,p_regMsg->regAgent_addr); } if(isLocAddr(p_regMsg->regAgent_addr)<0) //it's not local address { if(searchCounter(counter,p_regMsg->regAgent_addr)==-1) //not exist createNewTunnel(p_regMsg->regAgent_addr); addCounter(counter,p_regMsg->regAgent_addr); } } } }//else }//if }//while close(listen_fd); return;}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -