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

📄 mhlow.c

📁 mobile ip 源程序 对移动ip 的人员有用~!
💻 C
字号:
/*----------------------------------------------------------------------------  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.             -----------------------------------------------------------------------------*/     /* mhlow.c - Low level routines for the Mobile Host. */#include <stdio.h>#include <linux/netdevice.h>#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <sys/ioctl.h>#include <linux/route.h>#include <linux/if.h>#include <linux/if_arp.h>#include <linux/if_ether.h>#include <errno.h>#include <sys/file.h>#include <sys/param.h>#include <netdb.h>#include "low.h"extern int ioctlsid;extern int debug;typedef struct arhdr{          unsigned short  ar_hrd;		/* format of hardware address	*/	unsigned short	ar_pro;		/* format of protocol address	*/	unsigned char	ar_hln;		/* length of hardware address	*/	unsigned char	ar_pln;		/* length of protocol address	*/	unsigned short	ar_op;		/* ARP opcode (command)		*/        unsigned char ar_sha[ETH_ALEN];    /* sender hardware address	*/	unsigned char ar_sip[4];	/* sender IP address		*/	unsigned char ar_tha[ETH_ALEN];	/* target hardware address	*/	unsigned char ar_tip[4];       	/* target IP address		*/      } Arphdr;int lowdefifcreq(u_long *ipaddr, u_long *gw, char *name){  char line[120],dev[10];  long dest = -1;  struct sockaddr_in *sock;  struct ifreq ifr;  FILE *fd;    if((fd = fopen("/proc/net/route","r"))==NULL)    {       fprintf(stderr,"Error opening proc file\n");      return -1;    }     do {      if (fgets(line, sizeof(line), fd) == NULL) break;   } while (sscanf(line, "%s %lx %lx", dev, &dest, gw) != 2 || dest != 0x0);   fclose(fd);   if (dest != 0x0) return (-1);   bzero(&ifr, sizeof(struct ifreq));   strcpy(ifr.ifr_name,dev);   sock = (struct sockaddr_in *) &ifr.ifr_addr;   sock->sin_family = AF_INET;   if (ioctl(ioctlsid, SIOCGIFADDR, (char *) &ifr) < 0)  {	       perror("lowdefifcreq failed in SIOCGIFADDR");	       return -1;	   };    *ipaddr = sock->sin_addr.s_addr;  strcpy(name,ifr.ifr_name);  return 1;}lowifacedown(char *name)  { /* down the interface whose name is given */   struct ifreq ifr;   if (debug > 0)  {      fprintf(stderr, "DOWNiface %s.\n", name);   };   strcpy(ifr.ifr_name, name);   ifr.ifr_flags &= ~IFF_UP;   if (ioctl(ioctlsid, SIOCSIFFLAGS, (char *) &ifr) < 0)  {      perror("lowifacedown failed SIOCSIFFLAGS");   };}lowifaceset(char *name, unsigned long ipaddr, unsigned long mask)  {   struct ifreq ifr;   struct sockaddr_in *sock;      if (debug > 0)  {      fprintf(stderr, "lowifaceset called on %s addr %lx mask %lx.\n", 	      name, htonl(ipaddr), htonl(mask));   };      strcpy(ifr.ifr_name, name);   if (ioctl(ioctlsid, SIOCGIFFLAGS, (char *) &ifr) < 0 )  {      fprintf(stderr, "SIOCGIFFLAGS failed on %s\n", name);   };   ifr.ifr_flags |= IFF_UP;   if (ioctl(ioctlsid, SIOCSIFFLAGS, (char *) &ifr) < 0)  {      perror("lowifaceset failed SIOCSIFFLAGS");   };   sock = (struct sockaddr_in *) &ifr.ifr_addr;   sock->sin_family = AF_INET;   sock->sin_addr.s_addr = ipaddr;   if (ioctl(ioctlsid, SIOCSIFADDR, (char *) &ifr) < 0)  {      perror("lowifaceset failed SIOCSIFADDR");   }   sock = (struct sockaddr_in *) &ifr.ifr_broadaddr;   sock->sin_family = AF_INET;   sock->sin_addr.s_addr = (ipaddr & mask) | (0xffffffff & ~mask);   if (ioctl(ioctlsid, SIOCSIFBRDADDR, (char *) &ifr) < 0)  {      perror("lowifaceset failed SIOCSIFBRDADDR");   }   sock = (struct sockaddr_in *) &ifr.ifr_netmask;   sock->sin_family = AF_INET;   sock->sin_addr.s_addr = mask;    if (ioctl(ioctlsid, SIOCSIFNETMASK, (char *) &ifr) < 0)  {      perror("lowifaceset failed SIOCSIFNETMASK");   };}lowrtdefault(unsigned long ipaddr)  {   struct rtentry rtent;   struct sockaddr_in *sock;      if (debug > 0)  {      fprintf(stderr, "ROUTEdefault gw %lx.\n", 	      htonl(ipaddr));   };   bzero((char *) &rtent, sizeof(struct rtentry));   sock = (struct sockaddr_in *) &rtent.rt_dst;   sock->sin_family = AF_INET;   sock = (struct sockaddr_in *) &rtent.rt_gateway;   sock->sin_family = AF_INET;   sock->sin_addr.s_addr = ipaddr;   rtent.rt_flags = RTF_GATEWAY | RTF_UP;   if (ioctl(ioctlsid, SIOCADDRT, (char *) &rtent) == -1)  {      perror("SIOCADDRT failed");   }}lowrtset(unsigned long dest, char *devname, int type)  {   struct rtentry rtent;   struct sockaddr_in *sock;      if (debug > 0)  {      fprintf(stderr, "ROUTEset dest %8lx dev %s Type(6:DELRT 7:ADDRT) %2d.\n", 	      htonl(dest), devname, type);   };   bzero((char *) &rtent, sizeof(struct rtentry));   sock = (struct sockaddr_in *) &rtent.rt_dst;   sock->sin_family = AF_INET;   sock->sin_addr.s_addr = dest;   switch(type){   case ADDRT:     rtent.rt_flags = RTF_UP | RTF_HOST;     rtent.rt_dev = devname;     if (ioctl(ioctlsid, SIOCADDRT, (char *) &rtent) == -1)  {      perror("SIOCADDRT failed");    }    break;      case DELRT:     if (ioctl(ioctlsid, SIOCDELRT, (char *) &rtent) < 0 &&	 errno != EFAULT)  {       perror("lowrtreq DELRT failed SIOCDELRT");     };     break;   }  }lowrtnetset(unsigned long net,char *devname, unsigned long netmask,int type)  {   struct rtentry rtent;   struct sockaddr_in *sock , *socknm;      if (debug > 0)  {      fprintf(stderr, "ROUTEset dest net %8lx dev %s               Type(6:DELRT 7:ADDRT) %2d\n",htonl(net), devname,type);     };   bzero((char *) &rtent, sizeof(struct rtentry));   sock = (struct sockaddr_in *) &rtent.rt_dst;   sock->sin_family = AF_INET;   sock->sin_addr.s_addr = net;      switch(type){   case ADDRT:     socknm = (struct sockaddr_in *) &rtent.rt_genmask;     socknm->sin_family = AF_INET;     socknm->sin_addr.s_addr = netmask;     rtent.rt_flags = RTF_UP;     rtent.rt_dev =  devname;     if (ioctl(ioctlsid, SIOCADDRT, (char *) &rtent) == -1)  {       perror("SIOCADDRT failed");       }     break;        case DELRT:      if (ioctl(ioctlsid, SIOCDELRT, (char *) &rtent) < 0 &&	       errno != EFAULT)  {	      perror("lowrtreq DELRT failed SIOCDELRT");	   };	   break;   }   if(debug>2)fprintf(stderr,"Finished adding/del route for net %lx\n"		      ,htonl(net));}/* delete is used in lowflshARP() */int deleteARP(char *host)	{	struct arpreq ar;	struct hostent *hp;	struct sockaddr_in *sin;	int s; 	bzero((caddr_t)&ar, sizeof ar);	ar.arp_pa.sa_family = AF_INET;	sin = (struct sockaddr_in *)&ar.arp_pa;	sin->sin_family = AF_INET;	sin->sin_addr.s_addr = inet_addr(host);	if ((long)sin->sin_addr.s_addr == -1) {		if (!(hp = gethostbyname(host))) {			fprintf(stderr, "arp: %s: ", host);			herror((char *)NULL);			return(-1);		}		bcopy((char *)hp->h_addr, (char *)&sin->sin_addr,		    sizeof sin->sin_addr);	}	s = socket(AF_INET, SOCK_DGRAM, 0);	if (s < 0) {		perror("arp: socket");		return(-1);	}	if (ioctl(s, SIOCDARP, (caddr_t)&ar) < 0) {		if (errno == ENXIO && debug >2)			fprintf(stderr,"%s (%s) -- no entry\n",			    host, inet_ntoa(sin->sin_addr));		else			perror("SIOCDARP");		return(-1);	}	close(s);	      }lowflshARP() {  int i,fd;  char buf[1024];  char host[20];  if((fd = open("/proc/net/arp",O_RDONLY,0))<0)    {      perror("arp: error opening arptab");      return;};    if((i = read(fd,buf,sizeof(buf)))<0)	{		perror("arp: error reading arptab");		exit(1);	      }  close(fd);  buf[i]='\0';for(i=0;buf[i]!='\0';i++)if(buf[i] == '\n'){  if(sscanf(&buf[i+1],"%s",host)!=0)    { if(debug >2)       {	fprintf(stderr,"%s\n",host);	fprintf(stderr,"Deleting arp entry...\n");      }      deleteARP(host);     }  }}lownetmaskreq(char *dev,unsigned long *mask)  {        struct ifreq ifr;    struct sockaddr_in *sock;           sock = (struct sockaddr_in *)&ifr.ifr_netmask;    sock->sin_family = AF_INET;         if (debug > 0)  {      fprintf(stderr, "lownetmaskreq called on %s \n", dev);    };      strcpy(ifr.ifr_name, dev);   if (ioctl(ioctlsid, SIOCGIFNETMASK, (char *) &ifr) < 0)  {      perror("lownetmaskreq failed SIOCGIFNETMASK");   };    sock = (struct sockaddr_in *) &ifr.ifr_netmask;    *mask =  sock->sin_addr.s_addr ;   }lowhwaddrreq(char *dev,unsigned char *hwaddr)  {    struct ifreq ifr;    int i;    if (debug > 0)  {      fprintf(stderr, "lowhwaddrreq called on %s \n", dev);    };      strcpy(ifr.ifr_name, dev);   if (ioctl(ioctlsid, SIOCGIFHWADDR, (char *) &ifr) < 0)  {      perror("lowhwaddrreq failed SIOCGIFHWADDR");   };   bcopy((char*)&ifr.ifr_hwaddr.sa_data,hwaddr,6);     }void lowarpsend(char *device,unsigned long ipaddr,char *hwaddr, unsigned long destipaddr){  char frame[60];  struct ethhdr *ehdr;  Arphdr *ahdr;  int sockid;  struct sockaddr sa;  struct in_addr sin_addr;    if((sockid = socket(AF_INET,SOCK_PACKET,htons(ETH_P_802_3)))<0)    {      perror("Socket call failed in lowarpsend():");      return;    }  bzero((void*)frame,sizeof(frame));/* Ethernet header */  ehdr = (struct ethhdr*)frame;  hwaddread(ehdr->h_dest,"ff:ff:ff:ff:ff:ff");  bcopy(hwaddr,ehdr->h_source,6);  ehdr->h_proto = htons(ETH_P_ARP);  ahdr = (Arphdr*)(frame + sizeof(struct ethhdr));/* Arp header */  ahdr->ar_hrd = htons(ARPHRD_ETHER);  ahdr->ar_pro = htons(ETH_P_IP);  ahdr->ar_hln = 6;  ahdr->ar_pln = 4;  ahdr->ar_op  = htons(ARPOP_REQUEST);  bcopy(hwaddr,ahdr->ar_sha,6);  bcopy(&ipaddr,ahdr->ar_sip,4);  bzero(ahdr->ar_tha,6);  bcopy(&ipaddr,ahdr->ar_tip,4);       sa.sa_family = AF_INET;  strcpy(sa.sa_data, device);    if(sendto(sockid, frame, sizeof(frame), 0, &sa, sizeof(sa))<0)    {      perror("Sendto failed:");      exit(-1);    }  };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);   }};voidlowARPreq(int type, unsigned long ipaddr, char *hwaddr)     {	struct arpreq ar;	struct sockaddr_in *sock;	if (debug > 0)  {	   fprintf(stderr,                    "ARPreq %d (REM0=0,REM1=1,PROXY=2), addr %lx, hwaddr %x:%x:%x:%x:%x:%x\n",		   type, htonl(ipaddr), (unsigned char) hwaddr[0],		    (unsigned char) hwaddr[1],  (unsigned char) hwaddr[2],		    (unsigned char) hwaddr[3],  (unsigned char) hwaddr[4],		    (unsigned char) hwaddr[5]);	};	if (ipaddr == 0)  {	   if (debug > 0)	     fprintf(stderr, "lowARPreq called with zero ipaddr. Ignored.\n");	   return;	};	memset(&ar, 0, sizeof(struct arpreq));	sock = (struct sockaddr_in *) &ar.arp_pa;	sock->sin_family = AF_INET;	sock->sin_addr.s_addr = ipaddr;	switch (type)  {	 case REM0:	   /* remove an arp entry where ipaddr and hwaddr match */	   if (ioctl(ioctlsid, SIOCGARP, (char *) &ar) < 0)  {	      if (errno != ENXIO)	      	perror("lowARPreg REM0 failed SIOCGARP");	   };	   if (memcmp(hwaddr, ar.arp_ha.sa_data, 6) == 0) 	     if (ioctl(ioctlsid, SIOCDARP, (char *) &ar) < 0)  {		perror("lowARPreg REM0 failed SIOCDARP");	     };	   break;	 case REM1:	   /* remove arp entry for ipaddr */	   if (ioctl(ioctlsid, SIOCDARP, (char *) &ar) < 0)  {	      if (errno != ENXIO)	      	perror("lowARPreg REM1 failed SIOCDARP");	   };	   break;(struct sockaddr_in *) &ar.arp_ha;	 case PROXY:	   /* add a proxy ARP entry for given pair */	   ar.arp_flags |= ATF_PUBL;	   	   sock = (struct sockaddr_in *) &ar.arp_ha;	   sock->sin_family = ARPHRD_ETHER;	   /*sock = (struct sockaddr_in *) &ar.arp_netmask;	   sock->sin_addr.s_addr = 0xfeffffff; */	   memcpy(ar.arp_ha.sa_data, hwaddr, 6);	   ar.arp_flags = (ATF_PERM | ATF_PUBL | ATF_COM);	   if (ioctl(ioctlsid, SIOCSARP, (char *) &ar) < 0)  {	      perror("lowARPreg PROXY failed SIOCSARP");	   };	   break;	 default:	   fprintf(stderr, "lowARPreq(): Request type %d not supported.\n",		   type);	}      }

⌨️ 快捷键说明

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