📄 ripin.c
字号:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/ioctl.h>
#include <net/if.h>
#define RIPHSIZE 4
#define RIP_VERSION 1
#define RIP_REQUEST 1
#define RIP_RESPONSE 2
#define RIP_PORT 520
typedef struct
{
unsigned short rr_family;
unsigned short rr_mbz1;
struct in_addr rr_ipa;
unsigned int rr_mbz2;
unsigned int rr_mbz3;
unsigned int rr_metric;
}riprt;
#define MAXRIPROUTES 25
#define RIP_INFINITY 16
#define RIPRTTL 12
#define RIPZTIME 18
#define RIPINT 30
typedef struct
{
char rip_cmd;
char rip_vers;
unsigned short rip_mbz;
riprt rip_rts[MAXRIPROUTES];
}rip;
#define MAXROUTENUM 100
#define RT_INF 999
typedef struct
{
riprt rt_route;
unsigned long rt_gw;
int rt_isvalid;
long rt_ttl;
int rt_status;
}routelist;
rip replPacket;
rip recvPacket;
riprt *rTable;
rip reqPacket;
routelist myList[MAXROUTENUM];
int routeNum;
int sock;
struct sockaddr_in to, from, server;
fd_set rfds;
struct timeval timer;
long timeoff;
void newRoute(riprt* rt_route, char* ipAddr,unsigned short newAFI, unsigned int newMetric)
{
rt_route->rr_family=htons(newAFI);
rt_route->rr_mbz1=0;
inet_aton(ipAddr,&rt_route->rr_ipa);
rt_route->rr_mbz2=0;
rt_route->rr_mbz3=0;
rt_route->rr_metric=htonl(newMetric);
}
void printRoute(riprt *rt_route)
{
printf("Address Family Identifier: %d\n",ntohs(rt_route->rr_family));
printf("IPv4 Address: %s\n",inet_ntoa(rt_route->rr_ipa));
printf("Metric: %d\n",ntohl(rt_route->rr_metric));
printf("\n");
}
void printList(){ int i; printf("Num\tIP\t\tAFI\tMetric\tStatus\tNexthop\n"); for(i=0;i<MAXROUTENUM;i++) { if(myList[i].rt_isvalid!=1) continue; printf("%d\t%s\t%d\t%d\t%d\t",i, inet_ntoa(myList[i].rt_route.rr_ipa), ntohs(myList[i].rt_route.rr_family),ntohl(myList[i].rt_route.rr_metric), myList[i].rt_status); printf("%s\n",inet_ntoa(myList[i].rt_gw)); }}
void copyRoute(riprt *d,riprt *s)
{
d->rr_family=s->rr_family;
d->rr_ipa.s_addr=s->rr_ipa.s_addr;
d->rr_metric=s->rr_metric;
}
int readFile(char* filename)
{
FILE * file;
file=fopen(filename,"r");
if(file==NULL)
{
printf("File Not Found.\n");
return -1;
}
char ip[16];
int afi, metric;
while(fscanf(file,"%s %d %d\n",ip,&afi,&metric)!=EOF)
{
newRoute(&rTable[routeNum],ip,afi,metric);
newRoute(&myList[routeNum].rt_route,ip,afi,metric);
myList[routeNum].rt_ttl=RT_INF;
myList[routeNum].rt_isvalid=1;
myList[routeNum].rt_status=0;
routeNum++;
}
fclose(file);
return 1;
}
int settimer(void)
{
int i;
for(i=0;i<MAXROUTENUM;i++)
{
if(myList[i].rt_ttl == RT_INF)
continue;
if(myList[i].rt_isvalid==1)
{
myList[i].rt_ttl-=timeoff;
if(myList[i].rt_ttl<=0)
{
if(myList[i].rt_status==0)
{
printf("List[%d] is invalid.\n",i);
myList[i].rt_status=1;
myList[i].rt_ttl+=RIPZTIME;
}
else if(myList[i].rt_status==1)
{
printf("List[%d] to be deleted.\n",i);
myList[i].rt_isvalid=0;
routeNum--;
}
}
}
}
}
int ripinit()
{
int length,temp=1,error,i;
struct sockaddr_in tempip;
routeNum=0;
for(i=0;i<MAXROUTENUM;i++)
{
newRoute(&myList[i].rt_route,"0.0.0.0",0,0);
myList[i].rt_gw=0;
myList[i].rt_isvalid=0;
myList[i].rt_ttl=0;
myList[i].rt_status=0;
}
//REQUEST packet
reqPacket.rip_cmd=RIP_REQUEST;
reqPacket.rip_vers=RIP_VERSION;
reqPacket.rip_mbz=0;
newRoute(&reqPacket.rip_rts[0],"0.0.0.0",0,RIP_INFINITY);
//RESPONSE packet
replPacket.rip_cmd=RIP_RESPONSE;
replPacket.rip_vers=RIP_VERSION;
replPacket.rip_mbz=0;
rTable=replPacket.rip_rts;
if(readFile("test.txt")<0)
{
printf("File not found.\n");
return -1;
}
//timer
timer.tv_sec=RIPINT;
timer.tv_usec=0;
//setup to
to.sin_family=AF_INET;
inet_aton("255.255.255.255",&to.sin_addr);
to.sin_port=htons(RIP_PORT);
//setup server
server.sin_family=AF_INET;
server.sin_addr.s_addr=htonl(INADDR_ANY);
server.sin_port=htons(RIP_PORT);
//create socket
sock=socket(AF_INET,SOCK_DGRAM,0);
if(sock<0)
{
printf("Can't create socket!\n");
return -1;
}
//open broadcast
if(setsockopt(sock,SOL_SOCKET,SO_BROADCAST,&temp,sizeof(int))!=0)
{
printf("Can't enable Broadcast.\n");
close(sock);
return -1;
}
//bind
if(bind(sock,(struct sockaddr *)&server,sizeof server)<0)
{
printf("Can't bind.\n");
close(sock);
return -1;
}
FD_ZERO(&rfds);
FD_SET(sock,&rfds);
error=sendto(sock,&reqPacket,RIPHSIZE+sizeof(riprt),0,(struct sockaddr*)(&to),sizeof(to));
if(error<0)
printf("Can't broadcast.\n");
return 1;
}
int ripsend()
{
int error,i,j,k;
timer.tv_sec=RIPINT;
timer.tv_usec=0;
if(routeNum==0)
{
printf("Route table is null.\n");
return -1;
}
for(i=0,j=0,k=0;i<routeNum;i++)
{
while(myList[j].rt_isvalid!=1)
j++;
if(myList[j].rt_status!=0)
{
j++;
continue;
}
copyRoute(&rTable[k],&myList[j].rt_route);
j++;k++;
if(j>MAXROUTENUM)
printf("Out of Route list!\n");
}
if(k==0)
{
printf("Route list is null.\n");
return -1;
}
error=sendto(sock,&replPacket,RIPHSIZE+k*sizeof(riprt),0,(struct sockaddr*)(&to),sizeof(to));
if(error<0)
{
printf("Can't broadcast. Error %d\n",error);
}
return 1;
}
int riprecv()
{
int recvLen,len,i,j,m,error;
len=recvfrom(sock,&recvPacket,sizeof(recvPacket),0,(struct sockaddr*)&from,&recvLen);
printf("%d recieved from %s.\n",len,inet_ntoa(from.sin_addr.s_addr));
if((len-RIPHSIZE)%sizeof(riprt)!=0)
{
printf("Wrong packet.\n");
return -2;
}
if(recvPacket.rip_vers!=RIP_VERSION||recvPacket.rip_mbz!=0)
{
printf("Packet not match.\n");
return -3;
}
if(recvPacket.rip_cmd==RIP_REQUEST)
{
//request
printf("Request\n");
ripsend();
}
else if(recvPacket.rip_cmd==RIP_RESPONSE)
{
//response
printf("Response\n");
for(i=0;i<(len-RIPHSIZE)/sizeof(riprt);i++)
{
m=ntohl(recvPacket.rip_rts[i].rr_metric);
m++;
if(m>=RIP_INFINITY)
continue;
recvPacket.rip_rts[i].rr_metric=htonl(m);
for(j=0;j<MAXROUTENUM;j++)
{
if(myList[j].rt_isvalid!=1)
continue;
if(myList[j].rt_route.rr_ipa.s_addr == recvPacket.rip_rts[i].rr_ipa.s_addr)
{
if(myList[j].rt_gw == from.sin_addr.s_addr)
{
myList[j].rt_ttl=RIPRTTL;
myList[j].rt_status=0;
copyRoute(&myList[j].rt_route, &recvPacket.rip_rts[i]);
break;
}
if(recvPacket.rip_rts[i].rr_metric <= myList[j].rt_route.rr_metric)
{
myList[j].rt_ttl=RIPRTTL;
myList[j].rt_status=0;
myList[j].rt_gw=from.sin_addr.s_addr;
copyRoute(&myList[j].rt_route,&recvPacket.rip_rts[i]);
break;
}
break;
}
}
if(j==MAXROUTENUM)
{
j=0;
while(myList[j].rt_isvalid==1)
j++;
routeNum++;
myList[j].rt_isvalid=1;
myList[j].rt_ttl=RIPRTTL;
myList[j].rt_status=0;
myList[j].rt_gw=from.sin_addr.s_addr;
copyRoute(&myList[j].rt_route,&recvPacket.rip_rts[i]);
}
}
}
else
{
printf("Command invalid.\n");
return -5;
}
return 1;
}
int main(int argc, char* argv[])
{
int action;
struct timeval starttime,endtime;
if(ripinit()!=1)
exit(1);
while(1)
{
FD_ZERO(&rfds);
FD_SET(sock,&rfds);
gettimeofday(&starttime);
action=select(FD_SETSIZE,&rfds,NULL,NULL,&timer);
gettimeofday(&endtime);
timeoff=1000000*(endtime.tv_sec-starttime.tv_sec);
timeoff+=(endtime.tv_usec-starttime.tv_usec);
timeoff/=1000000;
settimer();
if(action)
{
printf("Packet arrived.\n");
riprecv();
printList();
}
else
{
printf("Send packets.\n");
ripsend();
}
}
close(sock);
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -