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

📄 mh.c

📁 mobile ip 源程序 对移动ip 的人员有用~!
💻 C
📖 第 1 页 / 共 2 页
字号:
/*----------------------------------------------------------------------------  Copyright (C) 1995-6, Vipul Gupta and Abhijit Dixit. Created 1995-6. All  rights reserved.  Linux-Mobile-IP            An implementation of Mobile IP for the LINUX operating system            developed at the State University of New York, Binghamton            (with partial support from the Center for Computing Technologies).            Except as noted in the accompanying documentation, this            implementation complies with revision 16 of the Internet             Engineering Task Force (IETF) Mobile-IP draft.            More information can be obtained from:                  http://anchor.cs.binghamton.edu/~mobileip/    Version:   1.00     05/23/1996   Authors:   Abhijit Dixit <abhijit@cs.binghamton.edu>              Vipul Gupta <vgupta@cs.binghamton.edu>             Benjamin Lancki <ben@anchor.cs.binghamton.edu>  Permission is hereby granted to redistribute this code and/or  modify it under the terms of the GNU Genral Public License  as published by the Free Software Foundation; either version  two or (at your option) any later version provided this ENTIRE  notice is retained in any copies or any part of this software.  A copy of the GNU General Public License can be obtained by contacting  the Free Software Foundation, Inc. 675 Mass Ave, Cambridge, MA 02139, USA.             -----------------------------------------------------------------------------*/ /* *   *                      mh.c : Design of the Mobile Host * *  Command line arguments: *    -a : mobile host's IP address on its home network  *    -m : network mask corresponding to the IP address above *    -g : IP address on the mobility interface of the homeagent. *     * * * History of Changes: *     Jul 25, 1995              First version coded  - V.G. *     Aug  1, 1995              Removed bug in processURhere. Now we *                               turn off REGAWAY when we move home and *                               turn off REGHOME when we move away - V.G. *     Aug  2, 1995              Moved URhere gathering in alarm_handler() *                               as part of preventing a flip-flop effect *                               when a mobile host hears URhere messages *                               from multiple mobility agents  *                               alternately - V.G. *     Aug  9, 1995              Added support for MD5 authentication in *                               processing the registration and registration  *                               reply - B.L. *     Aug 13, 1995              Agent now reads config file /etc/mip-mh.ok to *                               initialize mhinfo struct - B.L. *     Aug 14, 1995              Agent keeps a log in event of system crash *                               or shutdown and recovers on startup - B.L. *  * *     Sept 20, 1995             Low level routine added for adding and  *                               deleting route to a network -A.D. * * * *     Sept 22, 1995             Changed the code so Registerme mesgs are *                               now sent to FA instead of home agent; *				 because of this change , reply from home  *                               agent forwarded by foreign agent. *				 Separate mobile subnet is  *				 not required. -A.D. * *     Sept 30, 1995             mh does not exit when select fails on  *                               INTR -A.D * *     Oct 5, 1995               ARP cache is flushed when MH moves to *                               new network.-A.D. *       *     Oct 10, 1995              mh does not exit when sendto fails *                               because of network or host unreachable *                               condition. -A.D.    *				  *     Nov 10, 1995              Due to addition of a 'special sleep' *                               mh consumes very little cpu time.- A.D.     * *     Dec 5, 1995               Router Solicitation *                               Messages changed to use ICMP -A.D. *  *     April  1996               Complete redesign of the Mobile Host.  *                               MH now operates without Foreign Agent (Self  *                               Decapsulation) and some of the other  *                               inefficiencies are removed.  *                               - V.G. and A.D. *      *     May    1996               MH now sends gratuitous ARP after to coming to home network. *                               -A.D.*/#include <stdio.h>#include <sys/types.h>#include <sys/time.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <errno.h>#include <signal.h>#include <unistd.h>#include <stdlib.h>#include <string.h>#include <netinet/ip.h>#include "mh.h"#include "low.h"#define did_reboot(new,prev) (((new)<(prev))&((new)<256))/* Application required flags */#define APREF 0x00int debug = 2;short doit  = 0;char *state[] =  { "INIT", "ATHOME", "ATFOREIGN", "ASPOPUP"};extern int errno;extern void testprint(char *,int);extern void appendauth(char *,int *,char *,int,unsigned long);extern int authextfound(char *,int,int);extern int authok(char *,int,int,char *,int,unsigned long);extern void printext(char *,int,int);extern void printtime();extern int  in_cksum(u_short*,int);extern int lowdefifcreq(u_long*,u_long*,char*);void sendRegisterMe(int, unsigned char, unsigned short, unsigned long,		    unsigned long, unsigned long);int routersolId, URheresid, Regreplysid, RegisterMesid;int ioctlsid;void usage(char *), cleanup();struct sockaddr_in routersolto =     {  (short) AF_INET, (unsigned short) 0,	(unsigned long) 0, (unsigned long) 0 };char lastreq[1024]; /* this is the last request on which we are awaiting a reply */void init();myinfo Myinfo;dm_info Dminfo;short backoff[] = {1,2,4,8,16,32,64};short renewal[] = {2,4,8};struct stats  {   unsigned long badurhere;   unsigned long badregreply;   unsigned long idmismatch;   unsigned long authfailed;   unsigned long regsent;   unsigned long regfailed;   unsigned long regsuccessful;} mhstats =  { (long) 0, (long) 0,  (long) 0, (long) 0,               (long) 0, (long) 0,  (long) 0 };voidinitsockets()  {   struct sockaddr_in sa;   int enable = 1;      bzero((void*)&sa,sizeof(sa));   routersolId = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);   Regreplysid = RegisterMesid = socket(AF_INET, SOCK_DGRAM, 0);   URheresid = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);   ioctlsid = socket(AF_INET, SOCK_DGRAM, 0);   if (Regreplysid < 0 || URheresid < 0 ||        routersolId < 0 || RegisterMesid < 0 || ioctlsid < 0)  {	  fprintf(stderr, "initsockets(): could not create sockets.\n");	   exit(-1);       }   sa.sin_family = AF_INET; sa.sin_addr.s_addr = htonl(INADDR_ANY);    if (setsockopt(routersolId, SOL_SOCKET, SO_BROADCAST, &enable, sizeof(int))       < 0)  {	  perror("initsockets(): setsockopt SO_BROADCAST failed");	  cleanup(); exit(-1);       }   /* This is where we receive regreplies and send registermes from */   sa.sin_port = 0;    if (bind(RegisterMesid, (struct sockaddr *) &sa, sizeof(sa)) < 0)  {      perror("initsockets(): Bind RegisterMesid failed.\n");      cleanup(); exit(-1);   }   if (debug > 0)     fprintf(stderr, "Initialized sockets ...\n");}voidcleanup()  {      if (debug > 1)     fprintf(stderr, "Done cleaning up ... \n");}voidgraceful_exit()  {   struct sockaddr_in sock;   unsigned char flags = 0x00;      cleanup();   if ((Myinfo.status & 0x03)== ATFOREIGN ||        (Myinfo.status & 0x03)  == ASPOPUP)  {      Myinfo.retries = 0;      sendRegisterMe((int) 0, flags, (unsigned short) 0, Myinfo.homeaddr, 		     Myinfo.homeagent, Myinfo.coaddr);   }   /* deregister ourselves if we were registered or this will    * tie up a tunnel for atmost MAXLIFETIME period */    exit(0);}voidsendroutersol(struct sockaddr_in *toaddr){  struct icmp msg;  memset((char*)&msg,0,sizeof(struct icmp));    if (debug > 0)    fprintf(stderr, "\n-- RouterSol to  %s.\n",	     inet_ntoa(toaddr->sin_addr));  msg.type = ROUTERSOLTYPE;  msg.code = 0;  msg.cksum = 0;  msg.cksum = in_cksum((u_short*)&msg,sizeof(struct icmp));  if (sendto(routersolId, (char *) &msg, sizeof(msg), 0, 	     (struct sockaddr *) toaddr, sizeof(struct sockaddr)) < 0)  {    perror("sendroutersol(): send to failed.\n");        if(errno == ECONNREFUSED ||        errno == ENETUNREACH || errno == EHOSTUNREACH);    else		       {	cleanup(); exit(-1);      }  }}voidsendRegisterMe(int attempt, unsigned char flags, unsigned short lifetime, 	       unsigned long homeaddr, unsigned long homeagent,	       unsigned	long coaddr){   struct sockaddr_in toaddr;   struct registerme *req;   static int len;   toaddr.sin_family = AF_INET;   toaddr.sin_port = htons(MIPREGPORT);      /* Depending upon ASPOPUP and ATFOREIGN states toaddr is selected */   if(Myinfo.status & 0x03 == ASPOPUP)     toaddr.sin_addr.s_addr = Myinfo.homeagent;   else     toaddr.sin_addr.s_addr = Myinfo.closeagentaddr;    if(attempt != 0)     {       fprintf(stderr,"Retransmitting the same (earlier) request\n");       if (sendto(RegisterMesid, (char *) lastreq, len, 0, 	      (struct sockaddr *) &toaddr, sizeof(struct sockaddr)) < 0)  {		 perror("sendRegisterMe(): send to failed.\n");		 if(errno == ECONNREFUSED || 		    errno == ENETUNREACH || errno == EHOSTUNREACH);		 else		 		   {		     cleanup(); exit(-1);		   }	      };       return;            }   len = sizeof(struct registerme);   req = (struct registerme *) lastreq;   req->type = REGISTERMETYPE;   req->flags = flags;   req->lifetime = lifetime;   req->homeaddr = homeaddr;   req->ha = homeagent;   req->coaddr = coaddr;   /* we generate a new 64-bit Id unless this is a retransmission */   if (attempt == 0)     NewId(&Myinfo.RequestId, &Myinfo.RequestId);   req->Id.high = Myinfo.RequestId.high;   req->Id.low = Myinfo.RequestId.low;   appendauth(lastreq, &len, Myinfo.secret, Myinfo.secretlen,Myinfo.SPIval);   if (debug > 0)  {     fprintf(stderr, "\n==========================\n");     printtime();     if (req->lifetime == 0)        fprintf(stderr, "-- DEREGISTERME to %s at port %d (attempt %d).\n",	       inet_ntoa(toaddr.sin_addr), (unsigned int) toaddr.sin_port,	       attempt);     else       fprintf(stderr, "-- REGISTERME to %s at port %d (attempt %d).\n",	       inet_ntoa(toaddr.sin_addr), (unsigned int) toaddr.sin_port,	       attempt);     if (debug > 1)  {       fprintf(stderr, "[%8lx:%8lx] Type %2d Flags %2x Lifetime %8d\n",	       req->Id.high, req->Id.low, req->type, req->flags, req->lifetime);       fprintf(stderr, "Homeaddr: %8lx, Homeagent: %8lx, Careof: %8lx",	       htonl(req->homeaddr), htonl(req->ha), htonl(req->coaddr));	 if (debug > 2) {	   fprintf(stderr, "\n--------------------\n");	   printext(lastreq, len, 0);	   testprint(lastreq, len);	   fprintf(stderr, "--------------------");	 }      }      fprintf(stderr, "\n==========================\n");   }      if (sendto(RegisterMesid, (char *) lastreq, len, 0, 	      (struct sockaddr *) &toaddr, sizeof(struct sockaddr)) < 0)  {		 perror("sendRegisterMe(): send to failed.\n");		 if(errno == ECONNREFUSED || 		    errno == ENETUNREACH || errno == EHOSTUNREACH);		 else		 		   {		     cleanup(); exit(-1);		   }	      };}void dsn_maker(int);voidalarm_handler()  {   struct registerme *req;      if(debug >2)     fprintf(stderr,"The current state is %s\n",state[Myinfo.status & 0x03]);      if((Myinfo.status & 0x03)== INIT)     sendroutersol(&routersolto);    dsn_maker(URheresid);      /* we take care of our registration renewals */   if (!((Myinfo.status & 0x03) == ATHOME && 	 (Myinfo.status & DEREGISTERED)||Myinfo.status == INIT))      {       Myinfo.timeleft-=2;             if(Myinfo.status & REGISTERED)	 {	   if(Myinfo.retries <3){	     if(Myinfo.timeleft <= Myinfo.lifetime/renewal[Myinfo.retries])	       {		 /* Send new registration request */		 Myinfo.status |= AWAITINGREPLY;		 sendRegisterMe((int) 0, Myinfo.flags,Myinfo.lifetime,Myinfo.homeaddr, 			    Myinfo.homeagent, Myinfo.coaddr);		 Myinfo.retries++;	       }	   }	   else if (Myinfo.timeleft <= 0)  {	     Myinfo.timeleft = 0;	     /* Restore normal POPUP state so we ca have at least simple		connectivity */	     if((Myinfo.status & 0x03)==ASPOPUP)	       {		 lowifaceset(Myinfo.infname, Myinfo.coaddr, Myinfo.foreignnetmask);		 lowifacedown("dummy");	       }	     init((int)1);	 	     if (debug > 1)  {	       fprintf(stderr, "Registration expired ... \n");	     }		   }	 }       /* Take care of an request Retransmissions if NOT YET registered */       else {	 if (Myinfo.timeleft <= 0)  {	   Myinfo.timeleft = 0;	   if(Myinfo.retries < 6)	     {	       Myinfo.timeleft = (backoff[Myinfo.retries++])*RETRYINTERVAL;	       req = (struct registerme *) lastreq;	   	       sendRegisterMe(Myinfo.retries, req->flags, req->lifetime, 			   req->homeaddr, req->ha, req->coaddr);	     }	  else {	    /* MH has retransmitted this request enough times and	       and now it goes back to INIT state */	    init((int)1);	    if (debug > 1)  {	      fprintf(stderr, "We have retransmitted enough ... \n");	    }	  }	 }       }     }   signal(SIGALRM, alarm_handler);   alarm(1);}slp(double sec){  struct timeval tv;    tv.tv_sec = 0; tv.tv_usec = sec*1000000 ;  if((select(FD_SETSIZE, NULL, NULL, NULL, &tv)) < 0)  {    if(errno == EINTR ||  errno == ERESTART);    else        perror("select() failed in main loop.\n");      } }voidinit(int level)  {      Myinfo.timeleft = Myinfo.closeagentaddr = Myinfo.retries =0;    Myinfo.agentflags = Myinfo.seqno = Myinfo.lifetime =0;   Myinfo.coaddr = 0;   Myinfo.status = 0x00; /*INIT*/      if(level == 0){     bzero((void*)&Dminfo,sizeof(dm_info));     initsockets();     routersolto.sin_addr.s_addr = inet_addr(ADVERTISEON);     readhadata("/etc/mip-ha.dat");     signal(SIGTERM, graceful_exit);     signal(SIGINT, graceful_exit);     signal(SIGALRM, alarm_handler);     alarm(1);   }}   intIsOurAddress(unsigned long addr)  {   return((Myinfo.homeaddr == addr) ? 1:0);}intIsOurAgent(unsigned long addr)  {   return((Myinfo.homeagent == addr) ? 1:0);}intmhIdcmp(struct id *id1, struct id *id2)  {   return((id1->low == id2->low) ? 0:1);}intNewId(struct id *id1, struct id *id2)  {   static count = 0;   struct timeval tv;      if (count++ == 0)  {      gettimeofday(&tv, NULL);      srandom((int) tv.tv_usec);   };   id1->high = id2->high;   id1->low = (unsigned long) random();}void processRegreply(char *msg, int len, struct sockaddr_in *from)  {   struct regreply *reply;   int authoffset;   char hwaddr[10];   reply = (struct regreply *) msg;   /* This should never happen (probability is very very low) because       after we get a good reply we change the Id that we now expect       to a value we never sent       */   if (Myinfo.status & AWAITINGREPLY == 0)  {      fprintf(stderr, "Got a reply when we weren't expecting it.\n");      return;    }   /* Print contents of received message */   if (debug > 0)       {       fprintf(stderr, "\n==========================\n");       printtime();       fprintf(stderr, "-- REPLY from %s ", inet_ntoa(from->sin_addr));       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));	 if (debug > 2) {	   fprintf(stderr, "\n--------------------\n");	   printext(msg, len, 1);	   testprint(msg, len);	   fprintf(stderr, "--------------------");	 }       }       fprintf(stderr, "\n==========================\n");     }      Myinfo.RequestId.high = reply->Id.high;   Myinfo.retries = 0;   if (mhIdcmp(&Myinfo.RequestId, &(reply->Id)) != 0)  {

⌨️ 快捷键说明

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