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, ð, 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
