This patch add feature on ifconfig, check the presence of an ip on the lan.

aspinall
Submitted By: Vincenzo Giacchina <[EMAIL PROTECTED]>
Date: 2007-11-12
Initial Package Version: 1.0
Upstream Status: Not submitted - LFS Specific
Origin: http://aspinall.giaco.net/codes/net-tools-1.60-checkip-1.patch
Description: This patch check if an ip is in the lan. the checking is made by an arp request.


--- ifconfig.c	2001-04-13 18:25:18.000000000 +0000
+++ ifconfig.c.patch	2007-12-10 20:24:31.000000000 +0000
@@ -35,7 +35,6 @@
 #include <sys/ioctl.h>
 #include <netinet/in.h>
 #include <net/if.h>
-#include <net/if_arp.h>
 #include <stdio.h>
 #include <errno.h>
 #include <fcntl.h>
@@ -44,6 +43,9 @@
 #include <string.h>
 #include <unistd.h>
 #include <netdb.h>
+#include <arpa/inet.h>
+#include <linux/if_packet.h>
+#include <linux/if_ether.h>
 
 /* Ugh.  But libc5 doesn't provide POSIX types.  */
 #include <asm/types.h>
@@ -70,6 +72,28 @@
 
 #endif				/* HAVE_AFINET6 */
 
+#define ARPHRD_ETHER            1                      /* Ethernet 10Mbps              */
+#define ARPOP_REQUEST           1                      /* ARP request                  */
+#define PKT_LEN                 sizeof(eth) + sizeof(arp)
+#define BUFF_LEN                sizeof(*eth) + sizeof(*arp)
+#define IPV4_LEN                4
+#define MAX_CYCLE               8
+#define MAX_LEN_IP_STRING       16
+
+
+struct arphdr
+{
+        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            */
+};
+
 #if HAVE_AFIPX
 #if (__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1)
 #include <netipx/ipx.h>
@@ -100,6 +124,233 @@
 		       unsigned long nm, unsigned long bc,
 		       int flag);
 
+unsigned char *getmacaddr(char *dev, char **ip, int *index) {
+
+struct ifreq ifr;
+struct sockaddr_in *sin = (struct sockaddr_in *) &ifr.ifr_addr;
+
+	int s = socket (AF_INET,SOCK_DGRAM,0);
+
+	if(strlen(dev) >= IFNAMSIZ)
+	{
+		fprintf(stderr, "[dev] name interface is too long\n");
+		close(s);
+		return NULL;
+	}
+
+	strcpy(ifr.ifr_name, dev);
+
+	if(ioctl(s, SIOCGIFINDEX, &ifr) < 0) {
+		fprintf(stderr, "ioctl SIOCGIFINDEX error\n");
+		close(s);
+		return NULL;
+	}
+
+	*index = ifr.ifr_ifindex;
+
+	if (ioctl(s, SIOCGIFADDR, &ifr) < 0) {
+		fprintf(stderr, "ioctl SIOCGIFADDR error\n");
+		close(s);
+		return NULL;
+	}
+		*ip = inet_ntoa(sin->sin_addr);
+        
+	if (ioctl(s, SIOCGIFHWADDR, &ifr) < 0) {
+		fprintf(stderr, "ioctl SIOCGIFHWADDR error\n");
+		close(s);
+		return NULL;
+	}
+
+	unsigned char *pmac = calloc(1, ETH_ALEN);
+	memcpy(pmac, ifr.ifr_ifru.ifru_hwaddr.sa_data, ETH_ALEN);
+	
+	close(s);
+	return pmac;
+}
+
+
+int recvReply(int s, struct arphdr *arp_request, short int delay, int debug) {
+
+struct arphdr *arp;
+struct ethhdr *eth;
+struct sockaddr_ll from;
+struct timeval timeout;
+
+fd_set read_fd;
+
+char buff[BUFF_LEN];
+
+int i =0, plx=0;
+size_t len_from = sizeof(from);
+
+
+FD_ZERO( &read_fd );
+
+	timeout.tv_sec = 0;
+	timeout.tv_usec = (delay*100000)/2;
+
+        memset(buff, 0x00, PKT_LEN);
+
+	FD_SET(s, &read_fd );
+
+		if( (plx = select(s+1, &read_fd, NULL, NULL, &timeout )) == -1 ) {
+                        fprintf(stderr, "Error select()\n");
+                        return EXIT_FAILURE;       
+                } 
+	
+	if(plx) {
+		if( FD_ISSET(s, &read_fd )) {
+		        recvfrom(s, buff, BUFF_LEN, 0, (struct sockaddr*)&from, &len_from);
+        	}
+	}
+		else
+			return EXIT_FAILURE;
+
+	eth = (struct ethhdr *)buff;
+	arp = (struct arphdr *)&buff[sizeof(*eth)];
+
+	
+	/* check arp packet */
+
+	for(;i<ETH_ALEN;i++) { 
+		if(arp_request->ar_sha[i] != arp->ar_tha[i])
+			return EXIT_FAILURE;
+	}
+	for(i=0;i<IPV4_LEN;i++) {
+		if((arp_request->ar_sip[i] != arp->ar_tip[i])||(arp_request->ar_tip[i] != arp->ar_sip[i]))
+			return EXIT_FAILURE;
+	}
+
+	if(debug) {
+
+		fprintf(stdout, "Debug mode: \n\n");
+
+		fprintf(stdout, "\t[Eth Header]source            : %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n", 
+			eth->h_source[0], eth->h_source[1], eth->h_source[2], eth->h_source[3], eth->h_source[4], eth->h_source[5]);
+		
+		fprintf(stdout, "\t[Eth Header]dest              : %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n", 
+			eth->h_dest[0], eth->h_dest[1], eth->h_dest[2], eth->h_dest[3], eth->h_dest[4], eth->h_dest[5]);
+
+		fprintf(stdout, "\t[Arp Header]source            : %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n", 
+			arp->ar_sha[0], arp->ar_sha[1], arp->ar_sha[2], arp->ar_sha[3], arp->ar_sha[4], arp->ar_sha[5]);
+		
+		fprintf(stdout, "\t[Arp Header]dest              : %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n", 
+			arp->ar_tha[0], arp->ar_tha[1], arp->ar_tha[2], arp->ar_tha[3], arp->ar_tha[4], arp->ar_tha[5]);
+
+		fprintf(stdout, "\t[Arp Header]Source IP address : %d.%d.%d.%d\n", 
+			arp->ar_sip[0], arp->ar_sip[1], arp->ar_sip[2], arp->ar_sip[3]);
+		
+		fprintf(stdout, "\t[Arp Header]Target IP address : %d.%d.%d.%d\n\n", 
+			arp->ar_tip[0], arp->ar_tip[1], arp->ar_tip[2], arp->ar_tip[3]);  
+	}
+
+return EXIT_SUCCESS;
+}
+
+
+
+int CheckIPlan(char *target_ip, char *device, int debug){
+
+int s, index=0, ret, delay, i;
+
+struct ethhdr eth;
+struct arphdr arp;
+struct in_addr src , dst;
+struct sockaddr_ll to;
+
+char *ip  = NULL;
+unsigned char *mac = NULL;
+unsigned char *pkt = NULL;
+unsigned char h_bcast[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+
+
+if((s=socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ARP))) == -1) {
+	fprintf(stderr, "Errore socket()\n");
+	return EXIT_FAILURE;
+}
+
+pkt = malloc(PKT_LEN);
+
+if(pkt == NULL) {
+	fprintf(stderr, "Error malloc()\n");
+	return EXIT_FAILURE;
+}
+
+if((mac=getmacaddr(device, &ip, &index)) == NULL){
+	fprintf(stderr, "Error getmacaddr()\n");
+	return EXIT_FAILURE;
+}
+
+/* if myip is equal now ip */
+
+if(!strncmp(ip, target_ip, strlen(ip)))
+	return EXIT_FAILURE;
+	
+memcpy(eth.h_source, mac, ETH_ALEN);
+free(mac);
+
+memcpy(eth.h_dest, h_bcast, ETH_ALEN);
+eth.h_proto = htons(ETH_P_ARP);
+
+if(!inet_aton(ip, &src)) {
+	fprintf(stderr, "Error inet_aton()\n");
+	return EXIT_FAILURE;
+}
+
+if(!inet_aton(target_ip, &dst)) {
+        fprintf(stderr, "Error inet_aton()\n");
+        return EXIT_FAILURE;
+}
+
+to.sll_family  = AF_PACKET;
+to.sll_ifindex = index;
+to.sll_halen = ETH_ALEN;
+to.sll_protocol = htons(ETH_P_ARP);
+to.sll_hatype = htons(ARPHRD_ETHER);
+to.sll_pkttype = htons(PACKET_BROADCAST);
+
+memcpy(to.sll_addr, h_bcast, ETH_ALEN);
+
+arp.ar_hrd = htons(ARPHRD_ETHER);
+arp.ar_pro = htons(ETH_P_IP);
+arp.ar_hln = ETH_ALEN;
+arp.ar_pln = 0x4;
+arp.ar_op = htons(ARPOP_REQUEST);
+
+memcpy(arp.ar_sha, eth.h_source, ETH_ALEN); 
+memcpy(arp.ar_tha, h_bcast, ETH_ALEN);
+memcpy(arp.ar_sip, &src, IPV4_LEN);
+memcpy(arp.ar_tip, &dst, IPV4_LEN);
+
+memset(pkt, 0x00, PKT_LEN);
+
+memcpy(pkt, &eth, sizeof(eth));
+pkt += sizeof(eth);
+memcpy(pkt, &arp, sizeof(arp));
+pkt -= sizeof(eth);
+
+for(i=0,delay=1;i<MAX_CYCLE;i++,delay++) {
+
+	if((ret = sendto(s ,pkt, PKT_LEN, 0, (struct sockaddr*)&to, sizeof(to))) == -1) {
+		fprintf(stderr, "%s\n", strerror(ret));
+		return EXIT_FAILURE;
+	}
+
+	if(!recvReply(s, &arp, delay, debug))
+		break;
+
+	else if (i==MAX_CYCLE-1)
+		return EXIT_FAILURE;
+
+	usleep(400);
+}
+
+close(s);
+return EXIT_SUCCESS;
+}
+
+
+
 static int if_print(char *ifname)
 {
     int res;
@@ -174,8 +425,10 @@
 
 static void usage(void)
 {
-    fprintf(stderr, _("Usage:\n  ifconfig [-a] [-i] [-v] [-s] <interface> [[<AF>] <address>]\n"));
+    fprintf(stderr, _("Usage:\n  ifconfig [-a] [-i] [-v] [-s] [-c] [-d] <interface> [[<AF>] <address>]\n"));
 #if HAVE_AFINET
+    fprintf(stderr, _("  [-c[check present ip in the lan]]\n"));
+    fprintf(stderr, _("  [-d[with -c, debug header arp replay]]\n"));
     fprintf(stderr, _("  [add <address>[/<prefixlen>]]\n"));
     fprintf(stderr, _("  [del <address>[/<prefixlen>]]\n"));
     fprintf(stderr, _("  [[-]broadcast [<address>]]  [[-]pointopoint [<address>]]\n"));
@@ -236,6 +489,7 @@
     int goterr = 0, didnetmask = 0;
     char **spp;
     int fd;
+    int debug=0, checkip=0, c=0;
 #if HAVE_AFINET6
     extern struct aftype inet6_aftype;
     struct sockaddr_in6 sa6;
@@ -266,6 +520,12 @@
 	else if (!strcmp(*argv, "-v"))
 	    opt_v = 1;
 	
+	else if (!strcmp(*argv, "-d"))
+            debug = 1;
+
+        else if (!strcmp(*argv, "-c"))
+            checkip = 1;
+
 	else if (!strcmp(*argv, "-V") || !strcmp(*argv, "-version") ||
 	    !strcmp(*argv, "--version"))
 	    version();
@@ -936,7 +1196,16 @@
 		    fprintf(stderr, _("No support for INET on this system.\n"));
 		    exit(1);
 		}
-		r = ioctl(fd, SIOCSIFADDR, &ifr);
+		
+		if(checkip) {
+			if(!CheckIPlan(host, ifr.ifr_name, debug)){
+				printf("Error: %s is present in the lan, set another ip!\n", host);
+				c=1;
+			}
+		}	
+		if(!c)	
+			r = ioctl(fd, SIOCSIFADDR, &ifr);
+	
 		break;
 #endif
 #if HAVE_AFECONET
-- 
http://linuxfromscratch.org/mailman/listinfo/patches
FAQ: http://www.linuxfromscratch.org/faq/
Unsubscribe: See the above information page

Reply via email to