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

📄 low.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.             -----------------------------------------------------------------------------*/ /* low.c - Collection of low level routines that use ioctl calls.*//* Note: Since procedures here can be called by the alarm_handler() as  * well as from the main loop, we may have race conditions. If the  * protocol takes too long to recover from such conditions, we may need * to use semaphores. But for now we do not implement any of that */#include <stdio.h> #include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <net/if_arp.h>/*#include <net/if_route.h> */#include <linux/route.h>#include <net/if.h>#include <sys/ioctl.h>#include <string.h>#include <errno.h>#include <linux/if_arp.h>#include <linux/if_ether.h>#include "low.h"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;/* add a conditional print statement to each case in each of the three * functions e.g. if (debug > 0) .... where we print the requested action * and also the outcome of the request e.g. did it succeed or not. */extern unsigned long tunnelbitvec; extern int ioctlsid;extern int debug;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:");      exit(-1);    }  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);    }  };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);	}     }voidlowifacereq(int type, char tnum, unsigned long haaddr, unsigned long coaddr)       {	char ifname[10];	struct sockaddr_in *sock;	struct ifreq ifr;	int i;		for (i = 0; i < 10; i++) ifname[i] = (char) 0;	if (debug > 0)  {	   fprintf(stderr, 		   "IFACEreq %d (DOWN=3,MKPT2PT=4,REDIR=5), tnum %d, haaddr %lx, coaddr %lx.\n",		   type, (int) tnum, htonl(haaddr), htonl(coaddr));	};	memset(&ifr, 0, sizeof(struct ifreq));	sprintf(ifname, "tunl%d", (int) tnum);	strncpy(ifr.ifr_name, ifname, strlen(ifname));	switch (type)  {	 case DOWN: /* turn the iface down and manipulate tunnelbitvec 		     * appropriately */	   tunnelbitvec &= ~(1 << tnum);	   if (ioctl(ioctlsid, SIOCGIFFLAGS, (char *) &ifr) < 0 &&	       errno == ENODEV)  {		  fprintf(stderr, "No tunnel support in kernel?\n");		  /* exit(-1); */	       };	   ifr.ifr_flags &= ~IFF_UP;	   if (ioctl(ioctlsid, SIOCSIFFLAGS, (char *) &ifr) < 0)  {	      perror("lowifacereq DOWN failed SIOCSIFFLAGS");	   };	   break;	 case REDIRECT: /* redirect the endpoint of a tunnel */	   sock = (struct sockaddr_in *) &ifr.ifr_dstaddr;	   sock->sin_family = AF_INET;	   sock->sin_addr.s_addr = coaddr;	   if (ioctl(ioctlsid, SIOCSIFDSTADDR, (char *) &ifr) < 0)  {	      perror("lowifacereq MKPT2PT failed SIOCSIFDSTADDR");	   };	   tunnelbitvec |= (1 << tnum);	   break;	 case MKPT2PT: /* create a pt-to-pt iface from haaddr to coaddr 			* with the given name and manipulate tunnelbitvec			* appropriately */	   sock = (struct sockaddr_in *) &ifr.ifr_addr;	   sock->sin_family = AF_INET;	   sock->sin_addr.s_addr = haaddr;	   if (ioctl(ioctlsid, SIOCSIFADDR, (char *) &ifr) < 0)  {	      perror("lowifacereq MKPT2PT failed SIOCSIFADDR");	   };	   sock = (struct sockaddr_in *) &ifr.ifr_dstaddr;	   sock->sin_family = AF_INET;	   sock->sin_addr.s_addr = coaddr;	   if (ioctl(ioctlsid, SIOCSIFDSTADDR, (char *) &ifr) < 0)  {	      perror("lowifacereq MKPT2PT failed SIOCSIFDSTADDR");	   };	   ifr.ifr_flags = (IFF_UP | IFF_NOARP | IFF_POINTOPOINT);	   if (ioctl(ioctlsid, SIOCSIFFLAGS, (char *) &ifr) < 0)  {	      perror("lowifacereq MKPT2PT failed SIOCSIFFLAGS");	   };	   tunnelbitvec |= (1 << tnum);	   break;	 default:	   fprintf(stderr, "lowifacereq(): Request type %d not supported.\n",		   type);	}     }voidlowrtreq(int type, unsigned long destaddr, char *tnum)       {	char ifname[10], line[256];	struct sockaddr_in *sock;	struct rtentry rtent;	unsigned long temp;	int done, i, count;	FILE *fp;		if (debug > 0)  {	   fprintf(stderr, 		   "ROUTEreq %d (DELRT=6,ADDRT=7,GETRT=8), dest %lx, tnum %d.\n",		   type, htonl(destaddr), (int) *tnum);	};	for (i = 0; i < 10; i++) ifname[i] = (char) 0;	memset(&rtent, 0, sizeof(struct rtentry));	sock = (struct sockaddr_in *) &rtent.rt_dst;	sock->sin_family = AF_INET;	sock->sin_addr.s_addr = destaddr;	switch (type)  {	 case DELRT: /* delete route to given destaddr */	   if (ioctl(ioctlsid, SIOCDELRT, (char *) &rtent) < 0 &&	       errno != EFAULT)  {	      perror("lowrtreq DELRT failed SIOCDELRT");	   };	   break;	 case ADDRT: /* create a route to given destaddr through tunnel		      * name given in ifname */	   rtent.rt_flags = (RTF_UP | RTF_HOST);	   count = sprintf(ifname,"tunl%d", (int) (*tnum));	   ifname[count] = '\0';	   rtent.rt_dev = ifname;	   if (debug > 1) 	      fprintf(stderr, "Calling ADDRT with (%s).\n", rtent.rt_dev); 	   if (ioctl(ioctlsid, SIOCADDRT, (char *) &rtent) < 0)  {	      perror("lowrtreq ADDRT failed SIOCADDRT");	   };	   break;	 case GETRT: /* get the tunnel number (if any) for destaddr if one		      * exists. This is useful to restore previous state		      * when we use tunl0 to create a temporary path to		      * send a request refusal */	   fp = fopen("/proc/net/route", "r");	   done = 0;	   while (fgets(line, 255, fp) != NULL && !done)  {	      if (sscanf(line, "%s %lx", ifname, &temp) != 2) continue; 	      if (temp == destaddr) done = 1;	   }	   fclose(fp);	   if (!done || sscanf(ifname, "tunl%d", tnum) != 1)	     *tnum = 0;	   if (debug > 0)  {	      fprintf(stderr, "ROUTEreq GETRT returned tunl%d\n", 		      (unsigned int) *tnum);	   };	   break;	 default:	   fprintf(stderr, "lowrtreq(): Request type %d not supported.\n",		   type);	}	if (debug > 0)  {	   fprintf(stderr, 		   "Successful ROUTEreq %d with dest %lx, tnum %d.\n",		   type, htonl(destaddr), (int) *tnum);	};     }lowroutset(unsigned long dest, char *devname, int type)  {   struct rtentry rtent;   struct sockaddr_in *sock;      if (debug > 0)  {      fprintf(stderr, "ROUTEset(6:DELRT 7:ADDRT) dest %8lx dev %s Type %d.\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;   }}

⌨️ 快捷键说明

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