📄 agent.c
字号:
return; } else if(!(vmhinfo[vmh].status & CONFIRMED)) { if(debug>0) fprintf(stderr,"Unexpected regreply...ignoring\n"); return; } if(rreply->type != REGREPLYTYPE || len < sizeof(struct registerme)){ if(debug >0) fprintf(stderr,"Bad regreply...ignoring\n"); return; } if(debug >0){ if(rreply->code != 0 && rreply->code != 1) fprintf(stderr,"Rejection from HA\n"); else fprintf(stderr,"Acceptance from HA\n"); fprintf(stderr,"==============================\n"); } /* If reply is rejection from HA */ if(rreply->code != 0 && rreply->code != 1){ if(vmhinfo[vmh].status == PENDING) { vmhinfo[vmh].status &= 0x0; vmhinfo[vmh].timeleft = 0; toaddr.sin_family = AF_INET; toaddr.sin_addr.s_addr = vmhinfo[vmh].ipaddr; toaddr.sin_port = vmhinfo[vmh].fromport; lowroutset(vmhinfo[vmh].ipaddr,devname,ADDRT); if(sendto(Regreplysid,(char *)inmsg,len,0, (struct sockaddr *) &toaddr, sizeof(struct sockaddr))<0) { perror("FA: processRegreply for VMH failed in sendto"); if(errno == ECONNREFUSED || errno == ENETUNREACH || errno == EHOSTUNREACH); else { cleanup(); exit(-1); } } delay(); lowroutset(vmhinfo[vmh].ipaddr,devname,DELRT); } else if(vmhinfo[vmh].status == CONFIRMED) { toaddr.sin_family = AF_INET; toaddr.sin_addr.s_addr = vmhinfo[vmh].ipaddr; toaddr.sin_port = vmhinfo[vmh].fromport; if(sendto(Regreplysid,(char *)inmsg,len,0, (struct sockaddr *) &toaddr, sizeof(struct sockaddr))<0) { perror("FA: processRegreply for VMH failed in sendto"); if(errno == ECONNREFUSED || errno == ENETUNREACH || errno == EHOSTUNREACH); else{ cleanup(); exit(-1); } } } } /* Accept from home agent */else { if(debug >0)fprintf(stderr,"Processing Aceept...\n"); vmhinfo[vmh].status |= CONFIRMED; vmhinfo[vmh].timeleft = rreply->lifetime; toaddr.sin_family = AF_INET; toaddr.sin_addr.s_addr = vmhinfo[vmh].ipaddr; toaddr.sin_port = vmhinfo[vmh].fromport; lowroutset(vmhinfo[vmh].ipaddr,devname,ADDRT); if(debug>1){ fprintf(stderr,"Sending Acceptance from HA...\n"); fprintf(stderr,"VMHAddr: %s Port %2d \n", inet_ntoa(toaddr.sin_addr), toaddr.sin_port); } if(sendto(Regreplysid,(char *)inmsg,len,0, (struct sockaddr *) &toaddr, sizeof(struct sockaddr))<0) { perror("FA: processRegreply for VMH failed in sendto"); if(errno == ECONNREFUSED || errno == ENETUNREACH || errno == EHOSTUNREACH); else{ cleanup(); exit(-1); } } if(debug>1)fprintf(stderr,"Sent Reply to MH...\n"); }/* End of Accept part */ }/* End of processRegReply */void main(int argc, char **argv) { struct sockaddr_in from; static char inmsg[1024]; char *cmd; int len, fromlen, c; extern char *optarg; extern int optind; unsigned char argsfound = 0; fd_set fdvec; struct timeval tv; cmd = argv[0]; while ((c = getopt(argc, argv, "a:m:h:i:")) != -1) { switch ((char) c) { case 'a': argsfound |= 0x01; if ((haAddr = inet_addr(optarg)) == -1) { fprintf(stderr, "Bad address passed to -a.\n"); exit(-1); }; break; case 'm': argsfound |= 0x02; if ((haNetmask = inet_addr(optarg)) == -1) { fprintf(stderr, "Bad netmask passed to -m.\n"); exit(-1); }; break; case 'h': argsfound |= 0x04; if (hwaddread(proxyHwAddr,optarg) == -1) { fprintf(stderr, "Bad hwaddr passed to -h.\n"); exit(-1); }; break; /* Network interface to be used */ case 'i': argsfound |= 0x08; if((strcpy(DEVICE,optarg))<0) { fprintf(stderr,"Bad device name\n");exit(-1); }; break; case '?': usage(cmd); exit(1); break; } } if (argsfound != 0x0F) { usage(cmd); exit(1); } if (debug > 1) { fprintf(stderr, "IPaddr: %x, Mask: %x", htonl(haAddr), htonl(haNetmask)); fprintf(stderr, "HWaddr: %x:%x:%x:%x:%x:%x\n", (unsigned char) proxyHwAddr[0], (unsigned char) proxyHwAddr[1], (unsigned char) proxyHwAddr[2], (unsigned char) proxyHwAddr[3], (unsigned char) proxyHwAddr[4], (unsigned char) proxyHwAddr[5]); } /* Make sure we ARE on the network we are supposed to act as an * agent for and we do have tunnel support in /proc/net/dev * else complain and exit. Also make sure we have our effective * uid set to root since we will be manipulating routing tables and such. * We currently do not perform this check */ init(); while (1) { int selcode; FD_ZERO(&fdvec); FD_SET(WhereAmIsid, &fdvec); FD_SET(RegisterMesid, &fdvec); FD_SET(RegReplyHAid, &fdvec); /* For reg replies from HA to be fwd to MH */ tv.tv_sec = 0; tv.tv_usec = 0; while((selcode = select(FD_SETSIZE, &fdvec, NULL, NULL, &tv)) < 0) { if(errno == EINTR || errno == ERESTART); else perror("select() failed in main loop.\n"); } /* listen for a WhereAmI message on WhereAmIsid without * blocking and if there is a message, process it */ len = 1024; fromlen = sizeof(struct sockaddr_in); if (FD_ISSET(WhereAmIsid, &fdvec)) { if (debug > 2) fprintf(stderr, "Data on WhereAmIsid.\n"); if ((len = recvfrom(WhereAmIsid, inmsg, len, 0, (struct sockaddr *) &from, &fromlen)) < 0) { if(errno == ECONNREFUSED || errno == ENETUNREACH || errno == EHOSTUNREACH); else { perror("recvfrom() on WhereAmIsid failed.\n"); cleanup(); exit(-1);} }; processWhereAmI(inmsg, len, &from); } len = 1024; fromlen = sizeof(struct sockaddr_in); if (FD_ISSET(RegisterMesid, &fdvec)) { if (debug > 2) fprintf(stderr, "Data on RegisterMesid.\n"); if ((len = recvfrom(RegisterMesid, inmsg, len, 0, (struct sockaddr *) &from, &fromlen)) < 0) { perror("recvfrom() on RegisterMesid failed.\n"); if(errno == ECONNREFUSED || errno == ENETUNREACH || errno == EHOSTUNREACH); else { cleanup(); exit(-1); } }; processRegisterMe(inmsg, len, &from); if (debug > 2) fprintf(stderr, "In main finished processing RegisterMe.\n"); } /* For register replies from HA */ if (FD_ISSET(RegReplyHAid, &fdvec)){ if(debug>2) fprintf(stderr,"Data on RegReplyHAid\n"); if ((len = recvfrom(RegReplyHAid, inmsg, len, 0, (struct sockaddr *) &from, &fromlen)) < 0) { perror("recvfrom() on RegReplyidid failed.\n"); if(errno == ECONNREFUSED || errno == ENETUNREACH || errno == EHOSTUNREACH); else{ cleanup(); exit(-1); } }; processRegReply(inmsg, len, &from); } slp(SLEEPINTERVAL); } }voidusage(char *cmd) { fprintf(stderr, "Usage is: %s -a ipaddr -m netmask -h hwaddr -i interface\n", cmd);}int hwaddread(char s[], char *hwadr) { int a, b, c, d, e, f; if (sscanf(hwadr,"%x:%x:%x:%x:%x:%x", &a, &b, &c, &d, &e, &f) != 6) return(-1); else { s[0] = (unsigned char) a; s[1] = (unsigned char) b; s[2] = (unsigned char) c; s[3] = (unsigned char) d; s[4] = (unsigned char) e; s[5] = (unsigned char) f; return(0); }} voidsendReply(unsigned short fromport, int code, int time, unsigned long homeaddr, unsigned long coaddr, unsigned long haAddr, struct id replyid) { struct sockaddr_in sock; static char outmsg[1024]; struct regreply *reply; int len=sizeof(struct regreply); int mh; sock.sin_family = AF_INET; if(coaddr != 0) sock.sin_addr.s_addr = coaddr; else sock.sin_addr.s_addr =homeaddr; sock.sin_port = fromport; reply = (struct regreply *) outmsg; reply->type = 3; reply->code = (unsigned char) code; reply->lifetime = (unsigned short) time; reply->homeaddr = homeaddr; reply->ha = haAddr; reply->Id.high = replyid.high; reply->Id.low = replyid.low; if(coaddr != 0){ /* for diff bet FA and HA reply */ mh = whichmh(homeaddr); appendauth(outmsg, &len, mhinfo[mh].secret, mhinfo[mh].keylen,mhinfo[mh].SPIval); } if (debug > 0) { fprintf(stderr, "\n==========================\n"); printtime(); fprintf(stderr, "-- REPLY to %s at port %d ", inet_ntoa(sock.sin_addr), sock.sin_port); if ((reply->code != 0) && (reply->code != 1)) fprintf(stderr, "(Rejection)\n"); else fprintf(stderr, "(Acceptance)\n"); if (debug > 1) { fprintf(stderr, "[%8lx:%8lx] Type %2d Code %3d Lifetime %8d\n", reply->Id.high, reply->Id.low, reply->type, reply->code, reply->lifetime); fprintf(stderr, "Homeaddr: %8lx, Homeagent: %8lx", htonl(reply->homeaddr), htonl(reply->ha)); printext(outmsg, len, 1); if (debug > 2) { fprintf(stderr, "\n--------------------\n"); testprint(outmsg, len); fprintf(stderr, "--------------------"); } } fprintf(stderr, "\n==========================\n"); } if (sendto(Regreplysid, (char *) outmsg, len, 0, (struct sockaddr *) &sock, sizeof(struct sockaddr)) < 0) { perror("sendReply(): send to failed.\n"); if(errno == ECONNREFUSED || errno == ENETUNREACH || errno == EHOSTUNREACH); else { cleanup(); exit(-1); } } }/* send refusal from FA to MH */voidsendRefusalVMH(unsigned short fromport,int code,int time, unsigned long homeaddr,unsigned long ha,int vmh){ char devname[10]; strcpy(devname,DEVICE);/* set host specific route to visiting MH to send refusal */ lowroutset(homeaddr,devname,ADDRT); sendReply(fromport, code, time, homeaddr, 0, ha, vmhinfo[vmh].RegId); delay(); /* delete the route */ lowroutset(homeaddr, devname, DELRT);}voidsendConfirm(unsigned short fromport, int code, int time, unsigned long homeaddr, unsigned long coaddr, unsigned long haAddr, int mh) { sendReply(fromport, code, time, homeaddr, coaddr, haAddr, mhinfo[mh].RegistrationId); }voiddelay() { int i; /* artificial delay in an attempt to ensure that packet is * sent before we change the kernel routing tables again */ for (i = 0; i <= 100000; i++) ;}voidsendRefusal(unsigned short fromport,int code,int time, unsigned long homeaddr,unsigned long coaddr, unsigned long ha,int mh){ sendReply(fromport, code, time, homeaddr, coaddr, ha, mhinfo[mh].RegistrationId);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -