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

📄 agent.c

📁 mobile ip 源程序 对移动ip 的人员有用~!
💻 C
📖 第 1 页 / 共 3 页
字号:
   /* No port # for ICMP delete later       URhereto.sin_port = htons(ADVERTISETO);   */   readmhdata("/etc/mip-mh.ok");   readvmhdata("/etc/mip-vmh.ok");  /* read data for visiting MH */   /* read the ipaddr, authtype and 				  * secret for first MAXMHNUM mobile				  * hosts */    readlog("/usr/adm/mip-ha.log"); /* restore any state from a previous				    * incarnation of this daemon */    signal(SIGTERM, graceful_exit); /* terminate gracefully */   signal(SIGINT, graceful_exit); /* terminate gracefully */   signal(SIGALRM, alarm_handler); /* alarm_handler is the function				    * that gets called when alarm				    * goes off */    signal(SIGHUP, hup_handler);  /* Added to toggle URH messages */      alarm(ALARMINTERVAL);}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");      } }voidprocessWhereAmI(char *msg, int len, struct sockaddr_in *from)  {   /* if message is not of type WhereAmI, record this in a    * debug log and ignore msg. Otherwise call sendURhere()    * with the address and port obtained from the from    * structure */     struct icmp *where;  struct iphdr *ip;  int iphdrlen;  ip = (struct iphdr*)msg;    iphdrlen = ip->ihl << 2; /* Bytes */        where = (struct icmp*)(msg+iphdrlen);       if (where->type != ROUTERSOLTYPE || len < (iphdrlen + sizeof(struct icmp)))     agentstats.badwhereami++;  else    {      if (debug > 1)	fprintf(stderr, "\n-- WHEREAMI from %s\n", inet_ntoa(from->sin_addr));         sendURhere(from);}}     intIsOurAddress(unsigned long addr)  {   return((haAddr == addr) ? 1 : 0);}charnewtunnel() {   char i;   for (i = 1; i < MAXTUNNELS; i++)  {      if ((tunnelbitvec & (1 << i)) == 0)      	return(i);   }   return(0);}int whichmh(unsigned long addr)  {   int i;      mhinfo[0].ipaddr = addr;   for (i = supportedMHnum; i >= 0; i--)     if (mhinfo[i].ipaddr == addr) break;      return(i);}intwhichvmh(unsigned long addr) {    int i;    vmhinfo[0].ipaddr = addr;  for(i= supportedVMHnum; i>=0; i--)    if(vmhinfo[i].ipaddr == addr) break;  return(i);}inthavetunnel(int mh, unsigned long coaddr)  {   /* Return 0 (false) or 1 (true) depending on whether we can find    * an existing tunnel as required set up for the mobile host whose    * mhinfo index is given in mh. This tunnel should end at    * coaddr and a route to homeaddr must use the tunnel */   if ((mhinfo[mh].status & TUNNELUP) && (mhinfo[mh].coaddr == coaddr))     return (1);   else     return(0);}int maIdcmp(struct id *id1, struct id *id2)  {   return((id1->high == id2->high) ? 0:1);}voidprocessRegisterMe(char *msg, int len, struct sockaddr_in *from)  {   struct registerme *reg;   int code = 0;   int mh, vmh;   int authoffset;   char temp = 0;   unsigned short fromport;   unsigned long fromaddr; /* for sending back reg reply */   struct sockaddr_in toaddr; /* for sending mesg to HA */      if (debug > 2)       fprintf(stderr, "<<<<<<  Entering processRegisterMe \n");      if (debug > 0)      {       if (len < sizeof(struct registerme)) 	 fprintf(stderr,"msg length short of registerme size.\n");     }      reg = (struct registerme *) msg;   fromport = (unsigned short) from->sin_port;   fromaddr = (unsigned long) from->sin_addr.s_addr;   if (debug > 0)  {      fprintf(stderr, "\n==========================\n");      printtime();      if (reg->lifetime == 0)       	fprintf(stderr, "-- DEREGISTERME from %s Port %2d\n",		inet_ntoa(from->sin_addr),fromport);      else      	fprintf(stderr, "-- REGISTERME from %s Port %2d\n",		inet_ntoa(from->sin_addr), fromport);      if (debug > 1)  {	 fprintf(stderr, "[%8lx:%8lx] Type %2d Flags %2x Lifetime %8d\n",	      reg->Id.high, reg->Id.low, reg->type, reg->flags, reg->lifetime);	 fprintf(stderr, "Homeaddr: %8lx, Homeagent: %8lx, Careof: %8lx",	      htonl(reg->homeaddr), htonl(reg->ha), htonl(reg->coaddr));	 printext(msg, len, 0);	 if (debug > 2) {	   fprintf(stderr, "\n--------------------\n");	   testprint(msg, len);	   fprintf(stderr, "--------------------");	 }      }      fprintf(stderr, "\n==========================\n");   }      if(IsOurAddress(reg->ha)) {     if(debug > 1)fprintf(stderr,"Acting as home agent...\n");     mh = 0;   if (len < sizeof(struct registerme) || (reg->flags & 0x03)|| reg->type != REGISTERMETYPE ||        !IsOurAddress(reg->ha) || !(authoffset=authextfound(msg, len, 0)))  {      code = 134; /* badly formed request */      agentstats.badregisterme++;   } else if ((mh = whichmh(reg->homeaddr)) == 0)  {      code = 129; /* administratvely prohibited */      agentstats.mhprohibited++;   } else if (reg->lifetime == 0 && 	      (reg->coaddr != mhinfo[mh].coaddr && reg->coaddr != mhinfo[mh].ipaddr)){     code = 134;     agentstats.badregisterme++;   } else if (maIdcmp(&mhinfo[mh].RegistrationId, &(reg->Id)) != 0)  {      code = 133; /* id is not quite what we expected */       agentstats.idmismatch++;   } else if (reg->flags & 0x5c) {     code = 128; /* reason unspecified  no broadcast support 		    no GRE encap no Van Jacobson header compession */   } else if (!authok(msg, len, authoffset, mhinfo[mh].secret,               mhinfo[mh].keylen,mhinfo[mh].SPIval))  {      code = 131; /* failed authentication */      agentstats.authfailed++;   }      /* create a new id we can use for our reply */    newId(&(mhinfo[mh].RegistrationId), &(reg->Id));   if (code)  { /* Refusal */           sendRefusal(fromport, code, 0, reg->homeaddr, reg->coaddr, haAddr, mh);      if (debug > 2)      	fprintf(stderr, "Refusal sent.\n");      /* If it was deregistration request rejection due to ID mismatch	 when mobile host is away, send that rejection also on local net*/       if(code == 133 && reg->lifetime == 0 && (mhinfo[mh].status & TUNNELUP))	{	  lowARPreq(REM0, mhinfo[mh].ipaddr, proxyHwAddr);	  lowrtreq(DELRT, mhinfo[mh].ipaddr, &temp);	  sendRefusal(fromport, code, 0, reg->homeaddr, reg->coaddr, haAddr, mh);	  lowARPreq(PROXY, mhinfo[mh].ipaddr, proxyHwAddr);	  lowrtreq(ADDRT, mhinfo[mh].ipaddr, &(mhinfo[mh].tunnelnum));	  if(debug >2)	    fprintf(stderr, "Refusal sent on home network.\n");	}	        return;   }   /* Now we know that we are looking at a good request */   if (reg->lifetime == 0) /* We got a deregistration request */     {   /* if this is a degistration request, we can always oblige.     *    i. make lifetime field zero, if there is a name in the    *       tunnel field, down it clear name Change status. Clear    *       coaddr field also. We can leave the RegistrationId field    *       unchanged. Update any statistics we maintain. code = 1    *       lifetime = 0  */	mhinfo[mh].timeleft = 0;	code = 1;	mhinfo[mh].status &= ~TUNNELUP;	mhinfo[mh].coaddr = 0;	lowrtreq(DELRT, mhinfo[mh].ipaddr, &temp);	lowifacereq(DOWN, mhinfo[mh].tunnelnum, 0, 0);	lowARPreq(REM0, mhinfo[mh].ipaddr, proxyHwAddr);	mhinfo[mh].tunnelnum = 0;	agentstats.successfulreg++;	sendConfirm(fromport, code, 0, reg->homeaddr, reg->coaddr, haAddr, mh);   }    else if (mhinfo[mh].status & TUNNELUP)  {	mhinfo[mh].timeleft = (reg->lifetime > MAXLIFETIME) ?	      MAXLIFETIME : (int) reg->lifetime;	/* If S bit is set we send code =1 since this agent does not support 	   simultaneous bindings */	if(reg->flags & 0x80) 	  code = 1;	else 	  code = 0;		if (reg->coaddr == mhinfo[mh].coaddr)  {	   /* we have a renewal */	   agentstats.successfulreg++;	   sendConfirm(fromport, code, mhinfo[mh].timeleft, reg->homeaddr,		       reg->coaddr, haAddr, mh);	} 	else  {	   /* the tunnel needs to be redirected */	   mhinfo[mh].coaddr = reg->coaddr;	   lowifacereq(REDIRECT, mhinfo[mh].tunnelnum, 0, reg->coaddr);	   agentstats.successfulreg++;	   sendConfirm(fromport, code, mhinfo[mh].timeleft, reg->homeaddr,		       reg->coaddr, haAddr, mh);	}     }   else { /* A tunnel does not already exist */ 	mhinfo[mh].timeleft = (reg->lifetime > MAXLIFETIME) ?	      MAXLIFETIME : (int) reg->lifetime;	/* If S bit is set we send code =1 since this agent does not support 	   simultaneous bindings */	if(reg->flags & 0x80) 	  code = 1;	else 	  code = 0;	if (mhinfo[mh].tunnelnum = newtunnel())  {	   /* we were able to find an unused tunnel name */	   mhinfo[mh].status |= TUNNELUP;	   mhinfo[mh].coaddr = reg->coaddr;	   lowifacereq(MKPT2PT, mhinfo[mh].tunnelnum, haAddr, reg->coaddr);	   lowrtreq(ADDRT, mhinfo[mh].ipaddr, &(mhinfo[mh].tunnelnum));	   lowARPreq(PROXY, mhinfo[mh].ipaddr, proxyHwAddr);	   /* Send gratuitous ARP */	   lowarpsend(DEVICE,mhinfo[mh].ipaddr,proxyHwAddr,mhinfo[mh].ipaddr);	   agentstats.successfulreg++;	   sendConfirm(fromport, code, mhinfo[mh].timeleft, reg->homeaddr,		       reg->coaddr, haAddr, mh);	} else  {	   code = 130; /* insufficient resources */	   agentstats.noresources++;	   sendRefusal(fromport, code, 0, reg->homeaddr, reg->coaddr, 		       haAddr, mh);	   if (debug > 2)	     fprintf(stderr, "Refusal sent due to insuff resources.\n");	}     }   }else /* Now agent has to act as FA */  {     code =0;    if(debug>1)fprintf(stderr,"Acting as a foreign agent...\n");    vmh = 0;   if (len < sizeof(struct registerme) || reg->type != REGISTERMETYPE)  {      code = 70; /* badly formed request */      agentstats.badregisterme++;   } else if ((vmh = whichvmh(reg->homeaddr)) == 0)  {      code = 65; /* administratvely prohibited */      agentstats.mhprohibited++;   } else if (vmhinfo[vmh].ha != reg->ha)      code = 65; /* check for home agent  address if it is the 		    same as present in FA database */      else if (reg->flags & 0x08) /* No GRE encap */       code = 72;     else if (reg->flags & 0x04) /* No Van Jacobson header comp.*/       code = 73;     else if (reg->flags & 0x10) /* No minimal encap */       code = 72;vmhinfo[vmh].RegId.high = reg->Id.high;vmhinfo[vmh].RegId.low = reg->Id.low;if(code) /* refusal */    {      sendRefusalVMH(fromport,code,0,reg->homeaddr,reg->ha,vmh);      if(debug>2)	fprintf(stderr,"Refusal sent to VMH\n");          return;    }/* Now we have valid registerme (as far as FA is concerned ) */     if(vmhinfo[vmh].status != CONFIRMED){      vmhinfo[vmh].status |= PENDING;      vmhinfo[vmh].timeleft = 0;}     vmhinfo[vmh].RegId.high = reg->Id.high;     vmhinfo[vmh].RegId.low = reg->Id.low;     vmhinfo[vmh].fromport = fromport;     toaddr.sin_family = AF_INET;     toaddr.sin_port = htons(MIPREGPORT);     toaddr.sin_addr.s_addr = vmhinfo[vmh].ha;     reg = (struct registerme *) msg;          errno = 0;     if(sendto(RegMeVMHid,(char *)msg,len,0,	      (struct sockaddr *) &toaddr, sizeof(struct sockaddr))<0)      {	perror("FA: sendRegisterme for HA failed in sendto");	 if(errno == ECONNREFUSED || 	     errno == ENETUNREACH || errno == EHOSTUNREACH);	  else{	    cleanup(); exit(-1);	  }      }    if(debug > 0){      fprintf(stderr,"====================================\n");      if(!errno)	fprintf(stderr,"REGISTERME FORWARDED TO %s PORT %d\n",	      inet_ntoa(toaddr.sin_addr),(unsigned int) toaddr.sin_port);    }      } /* End of else part */ } /* End of ProcessRegisterme *//* Handle ragister reply from HA  */void processRegReply(char *inmsg, int len, struct sockaddr_in *from)  {     struct regreply *rreply;      int code = 0;     int vmh;     int authoffset;     char temp = 0;     unsigned short fromport;     struct sockaddr_in toaddr;     char devname[10];     strcpy(devname,DEVICE);     rreply = (struct regreply*) inmsg;     fromport = (unsigned short)from->sin_port;          if(debug>0)       {	 fprintf(stderr,"================================\n");	 fprintf(stderr,"REPLY from HA %8lx for VMH %8lx Code %2d\n",		 htonl(rreply->ha),htonl(rreply->homeaddr),rreply->code);	 if(len < sizeof(struct regreply))	   fprintf(stderr,"msg length short for register reply...ignoring\n");	 fprintf(stderr,"===============================\n");       }     vmh = whichvmh(rreply->homeaddr);     if(vmh == 0)       {	 if(debug>0)	   fprintf(stderr,"Regreply for unsupported VMH..ignoring\n");

⌨️ 快捷键说明

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